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 }