001package cpw.mods.fml.client.registry;
002
003import java.util.List;
004import java.util.Map;
005
006import net.minecraft.block.Block;
007import net.minecraft.client.renderer.RenderBlocks;
008import net.minecraft.client.renderer.entity.*;
009import net.minecraft.entity.Entity;
010import net.minecraft.world.IBlockAccess;
011
012import com.google.common.collect.Lists;
013import com.google.common.collect.Maps;
014import com.google.common.collect.ObjectArrays;
015
016import cpw.mods.fml.client.SpriteHelper;
017import cpw.mods.fml.client.TextureFXManager;
018
019/**
020 * @author cpw
021 *
022 */
023public class RenderingRegistry
024{
025    private static final RenderingRegistry INSTANCE = new RenderingRegistry();
026
027    private int nextRenderId = 36;
028
029    private Map<Integer, ISimpleBlockRenderingHandler> blockRenderers = Maps.newHashMap();
030
031    private List<EntityRendererInfo> entityRenderers = Lists.newArrayList();
032
033    /**
034     * Add a new armour prefix to the RenderPlayer
035     *
036     * @param armor
037     */
038    public static int addNewArmourRendererPrefix(String armor)
039    {
040        RenderPlayer.armorFilenamePrefix = ObjectArrays.concat(RenderPlayer.armorFilenamePrefix, armor);
041        RenderBiped.bipedArmorFilenamePrefix = RenderPlayer.armorFilenamePrefix;
042        return RenderPlayer.armorFilenamePrefix.length - 1;
043    }
044
045    /**
046     * Register an entity rendering handler. This will, after mod initialization, be inserted into the main
047     * render map for entities
048     *
049     * @param entityClass
050     * @param renderer
051     */
052    public static void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
053    {
054        instance().entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
055    }
056
057    /**
058     * Register a simple block rendering handler
059     *
060     * @param handler
061     */
062    public static void registerBlockHandler(ISimpleBlockRenderingHandler handler)
063    {
064        instance().blockRenderers.put(handler.getRenderId(), handler);
065    }
066
067    /**
068     * Register the simple block rendering handler
069     * This version will not call getRenderId on the passed in handler, instead using the supplied ID, so you
070     * can easily re-use the same rendering handler for multiple IDs
071     *
072     * @param renderId
073     * @param handler
074     */
075    public static void registerBlockHandler(int renderId, ISimpleBlockRenderingHandler handler)
076    {
077        instance().blockRenderers.put(renderId, handler);
078    }
079    /**
080     * Get the next available renderId from the block render ID list
081     */
082    public static int getNextAvailableRenderId()
083    {
084        return instance().nextRenderId++;
085    }
086
087    /**
088     * Add a texture override for the given path and return the used index
089     *
090     * @param fileToOverride
091     * @param fileToAdd
092     */
093    public static int addTextureOverride(String fileToOverride, String fileToAdd)
094    {
095        int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
096        addTextureOverride(fileToOverride, fileToAdd, idx);
097        return idx;
098    }
099
100    /**
101     * Add a texture override for the given path and index
102     *
103     * @param path
104     * @param overlayPath
105     * @param index
106     */
107    public static void addTextureOverride(String path, String overlayPath, int index)
108    {
109        TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
110    }
111
112    /**
113     * Get and reserve a unique texture index for the supplied path
114     *
115     * @param path
116     */
117    public static int getUniqueTextureIndex(String path)
118    {
119        return SpriteHelper.getUniqueSpriteIndex(path);
120    }
121
122    @Deprecated public static RenderingRegistry instance()
123    {
124        return INSTANCE;
125    }
126
127    private static class EntityRendererInfo
128    {
129        public EntityRendererInfo(Class<? extends Entity> target, Render renderer)
130        {
131            this.target = target;
132            this.renderer = renderer;
133        }
134        private Class<? extends Entity> target;
135        private Render renderer;
136    }
137
138    public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
139    {
140        if (!blockRenderers.containsKey(modelId)) { return false; }
141        ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
142        return bri.renderWorldBlock(world, x, y, z, block, modelId, renderer);
143    }
144
145    public void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
146    {
147        if (!blockRenderers.containsKey(modelID)) { return; }
148        ISimpleBlockRenderingHandler bri = blockRenderers.get(modelID);
149        bri.renderInventoryBlock(block, metadata, modelID, renderer);
150    }
151
152    public boolean renderItemAsFull3DBlock(int modelId)
153    {
154        ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
155        return bri != null && bri.shouldRender3DInInventory();
156    }
157
158    public void loadEntityRenderers(Map<Class<? extends Entity>, Render> rendererMap)
159    {
160        for (EntityRendererInfo info : entityRenderers)
161        {
162            rendererMap.put(info.target, info.renderer);
163            info.renderer.setRenderManager(RenderManager.instance);
164        }
165    }
166}