001    package cpw.mods.fml.client.modloader;
002    
003    import java.util.Collection;
004    import java.util.Collections;
005    import java.util.Map;
006    import java.util.Map.Entry;
007    import java.util.logging.Level;
008    
009    import net.minecraft.client.Minecraft;
010    import net.minecraft.src.BaseMod;
011    import net.minecraft.src.Entity;
012    import net.minecraft.src.EntityClientPlayerMP;
013    import net.minecraft.src.EntityPlayer;
014    import net.minecraft.src.KeyBinding;
015    import net.minecraft.src.Packet250CustomPayload;
016    import net.minecraft.src.Render;
017    import net.minecraft.src.RenderManager;
018    
019    import com.google.common.base.Equivalences;
020    import com.google.common.base.Supplier;
021    import com.google.common.base.Suppliers;
022    import com.google.common.collect.Iterables;
023    import com.google.common.collect.Iterators;
024    import com.google.common.collect.MapDifference;
025    import com.google.common.collect.MapDifference.ValueDifference;
026    import com.google.common.collect.Maps;
027    import com.google.common.collect.Multimap;
028    import com.google.common.collect.Multimaps;
029    
030    import cpw.mods.fml.client.FMLClientHandler;
031    import cpw.mods.fml.client.registry.KeyBindingRegistry;
032    import cpw.mods.fml.client.registry.RenderingRegistry;
033    import cpw.mods.fml.common.FMLLog;
034    import cpw.mods.fml.common.Loader;
035    import cpw.mods.fml.common.modloader.BaseModProxy;
036    import cpw.mods.fml.common.modloader.IModLoaderSidedHelper;
037    import cpw.mods.fml.common.modloader.ModLoaderHelper;
038    import cpw.mods.fml.common.modloader.ModLoaderModContainer;
039    import cpw.mods.fml.common.network.EntitySpawnPacket;
040    import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
041    
042    public class ModLoaderClientHelper implements IModLoaderSidedHelper
043    {
044    
045        /**
046         * @param mod
047         * @param inventoryRenderer
048         * @return
049         */
050        public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
051        {
052            int renderId=RenderingRegistry.getNextAvailableRenderId();
053            ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
054            RenderingRegistry.registerBlockHandler(bri);
055            return renderId;
056        }
057    
058    
059        public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
060        {
061            FMLLog.finer("Handling post startup activities for ModLoader mod %s", mc.getModId());
062            BaseMod mod = (BaseMod) mc.getMod();
063    
064            Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap(RenderManager.instance.entityRenderMap);
065    
066            try
067            {
068                FMLLog.finest("Requesting renderers from basemod %s", mc.getModId());
069                mod.addRenderer(renderers);
070                FMLLog.finest("Received %d renderers from basemod %s", renderers.size(), mc.getModId());
071            }
072            catch (Exception e)
073            {
074                FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the addRenderer call. Continuing, but expect odd results", mc.getModId());
075            }
076    
077            MapDifference<Class<? extends Entity>, Render> difference = Maps.difference(RenderManager.instance.entityRenderMap, renderers, Equivalences.identity());
078    
079            for ( Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnLeft().entrySet())
080            {
081                FMLLog.warning("The mod %s attempted to remove an entity renderer %s from the entity map. This will be ignored.", mc.getModId(), e.getKey().getName());
082            }
083    
084            for (Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnRight().entrySet())
085            {
086                FMLLog.finest("Registering ModLoader entity renderer %s as instance of %s", e.getKey().getName(), e.getValue().getClass().getName());
087                RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue());
088            }
089    
090            for (Entry<Class<? extends Entity>, ValueDifference<Render>> e : difference.entriesDiffering().entrySet())
091            {
092                FMLLog.finest("Registering ModLoader entity rendering override for %s as instance of %s", e.getKey().getName(), e.getValue().rightValue().getClass().getName());
093                RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue().rightValue());
094            }
095    
096            try
097            {
098                mod.registerAnimation(game);
099            }
100            catch (Exception e)
101            {
102                FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the registerAnimation call. Continuing, but expect odd results", mc.getModId());
103            }
104        }
105    
106        public ModLoaderClientHelper(Minecraft client)
107        {
108            this.client = client;
109            ModLoaderHelper.sidedHelper = this;
110            keyBindingContainers = Multimaps.newMultimap(Maps.<ModLoaderModContainer, Collection<ModLoaderKeyBindingHandler>>newHashMap(), new Supplier<Collection<ModLoaderKeyBindingHandler>>()
111            {
112                @Override
113                public Collection<ModLoaderKeyBindingHandler> get()
114                {
115                    return Collections.singleton(new ModLoaderKeyBindingHandler());
116                }
117            });
118        }
119    
120        private Minecraft client;
121        private static Multimap<ModLoaderModContainer, ModLoaderKeyBindingHandler> keyBindingContainers;
122    
123        @Override
124        public void finishModLoading(ModLoaderModContainer mc)
125        {
126            handleFinishLoadingFor(mc, client);
127        }
128    
129    
130        public static void registerKeyBinding(BaseModProxy mod, KeyBinding keyHandler, boolean allowRepeat)
131        {
132            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
133            ModLoaderKeyBindingHandler handler = Iterables.getOnlyElement(keyBindingContainers.get(mlmc));
134            handler.setModContainer(mlmc);
135            handler.addKeyBinding(keyHandler, allowRepeat);
136            KeyBindingRegistry.registerKeyBinding(handler);
137        }
138    
139    
140        @Override
141        public Object getClientGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
142        {
143            return ((net.minecraft.src.BaseMod)mod).getContainerGUI((EntityClientPlayerMP) player, ID, x, y, z);
144        }
145    
146    
147        @Override
148        public Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration er)
149        {
150            return ((net.minecraft.src.BaseMod)mod).spawnEntity(er.getModEntityId(), client.theWorld, input.scaledX, input.scaledY, input.scaledZ);
151        }
152    
153    
154        @Override
155        public void sendClientPacket(BaseModProxy mod, Packet250CustomPayload packet)
156        {
157            ((net.minecraft.src.BaseMod)mod).clientCustomPayload(client.thePlayer.sendQueue, packet);
158        }
159    }