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        public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
045        {
046            int renderId=RenderingRegistry.getNextAvailableRenderId();
047            ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
048            RenderingRegistry.registerBlockHandler(bri);
049            return renderId;
050        }
051    
052    
053        public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
054        {
055            FMLLog.finer("Handling post startup activities for ModLoader mod %s", mc.getModId());
056            BaseMod mod = (BaseMod) mc.getMod();
057    
058            Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap(RenderManager.instance.entityRenderMap);
059    
060            try
061            {
062                FMLLog.finest("Requesting renderers from basemod %s", mc.getModId());
063                mod.addRenderer(renderers);
064                FMLLog.finest("Received %d renderers from basemod %s", renderers.size(), mc.getModId());
065            }
066            catch (Exception e)
067            {
068                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());
069            }
070    
071            MapDifference<Class<? extends Entity>, Render> difference = Maps.difference(RenderManager.instance.entityRenderMap, renderers, Equivalences.identity());
072    
073            for ( Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnLeft().entrySet())
074            {
075                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());
076            }
077    
078            for (Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnRight().entrySet())
079            {
080                FMLLog.finest("Registering ModLoader entity renderer %s as instance of %s", e.getKey().getName(), e.getValue().getClass().getName());
081                RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue());
082            }
083    
084            for (Entry<Class<? extends Entity>, ValueDifference<Render>> e : difference.entriesDiffering().entrySet())
085            {
086                FMLLog.finest("Registering ModLoader entity rendering override for %s as instance of %s", e.getKey().getName(), e.getValue().rightValue().getClass().getName());
087                RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue().rightValue());
088            }
089    
090            try
091            {
092                mod.registerAnimation(game);
093            }
094            catch (Exception e)
095            {
096                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());
097            }
098        }
099    
100        public ModLoaderClientHelper(Minecraft client)
101        {
102            this.client = client;
103            ModLoaderHelper.sidedHelper = this;
104            keyBindingContainers = Multimaps.newMultimap(Maps.<ModLoaderModContainer, Collection<ModLoaderKeyBindingHandler>>newHashMap(), new Supplier<Collection<ModLoaderKeyBindingHandler>>()
105            {
106                @Override
107                public Collection<ModLoaderKeyBindingHandler> get()
108                {
109                    return Collections.singleton(new ModLoaderKeyBindingHandler());
110                }
111            });
112        }
113    
114        private Minecraft client;
115        private static Multimap<ModLoaderModContainer, ModLoaderKeyBindingHandler> keyBindingContainers;
116    
117        @Override
118        public void finishModLoading(ModLoaderModContainer mc)
119        {
120            handleFinishLoadingFor(mc, client);
121        }
122    
123    
124        public static void registerKeyBinding(BaseModProxy mod, KeyBinding keyHandler, boolean allowRepeat)
125        {
126            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
127            ModLoaderKeyBindingHandler handler = Iterables.getOnlyElement(keyBindingContainers.get(mlmc));
128            handler.setModContainer(mlmc);
129            handler.addKeyBinding(keyHandler, allowRepeat);
130            KeyBindingRegistry.registerKeyBinding(handler);
131        }
132    
133    
134        @Override
135        public Object getClientGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
136        {
137            return ((net.minecraft.src.BaseMod)mod).getContainerGUI((EntityClientPlayerMP) player, ID, x, y, z);
138        }
139    
140    
141        @Override
142        public Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration er)
143        {
144            return ((net.minecraft.src.BaseMod)mod).spawnEntity(er.getModEntityId(), client.theWorld, input.scaledX, input.scaledY, input.scaledZ);
145        }
146    
147    
148        @Override
149        public void sendClientPacket(BaseModProxy mod, Packet250CustomPayload packet)
150        {
151            ((net.minecraft.src.BaseMod)mod).clientCustomPayload(client.thePlayer.sendQueue, packet);
152        }
153    }