From c6f362b77f04b30c854fccd61d7601b1c4f914e3 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 22 Aug 2012 23:46:16 -0400 Subject: [PATCH] Fix entity handling for ModLoader mods, thanks parachute mod! --- .../cpw/mods/fml/client/FMLClientHandler.java | 37 ++++++++++----- .../modloader/ModLoaderClientHelper.java | 13 ++++++ client/net/minecraft/src/BaseMod.java | 20 +++++++- client/net/minecraft/src/ModLoader.java | 4 ++ .../cpw/mods/fml/common/FMLCommonHandler.java | 5 +- .../cpw/mods/fml/common/IFMLSidedHandler.java | 3 +- .../fml/common/modloader/BaseModProxy.java | 2 + .../modloader/IModLoaderSidedHelper.java | 5 ++ .../ModLoaderEntitySpawnCallback.java | 30 ++++++++++++ .../fml/common/modloader/ModLoaderHelper.java | 20 ++++++-- .../modloader/ModLoaderModContainer.java | 7 +++ .../fml/common/network/EntitySpawnPacket.java | 2 +- .../fml/common/registry/EntityRegistry.java | 46 +++++++++++++++++-- .../cpw/mods/fml/server/FMLServerHandler.java | 3 +- 14 files changed, 170 insertions(+), 27 deletions(-) create mode 100644 common/cpw/mods/fml/common/modloader/ModLoaderEntitySpawnCallback.java diff --git a/client/cpw/mods/fml/client/FMLClientHandler.java b/client/cpw/mods/fml/client/FMLClientHandler.java index fefcc5d5df..fcc55cd98d 100644 --- a/client/cpw/mods/fml/client/FMLClientHandler.java +++ b/client/cpw/mods/fml/client/FMLClientHandler.java @@ -52,6 +52,7 @@ import cpw.mods.fml.common.ObfuscationReflectionHelper; import cpw.mods.fml.common.Side; import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket; import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; import cpw.mods.fml.common.registry.IThrowableEntity; import cpw.mods.fml.common.registry.LanguageRegistry; @@ -250,22 +251,41 @@ public class FMLClientHandler implements IFMLSidedHandler } @Override - public Entity spawnEntityIntoClientWorld(Class cls, EntitySpawnPacket packet) + public Entity spawnEntityIntoClientWorld(EntityRegistration er, EntitySpawnPacket packet) { WorldClient wc = client.field_71441_e; + Class cls = er.getEntityClass(); + try { - Entity entity = (Entity)(cls.getConstructor(World.class).newInstance(wc)); + Entity entity; + if (er.hasCustomSpawning()) + { + entity = er.doCustomSpawning(packet); + } + else + { + entity = (Entity)(cls.getConstructor(World.class).newInstance(wc)); + entity.field_70157_k = packet.entityId; + entity.func_70012_b(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch); + if (entity instanceof EntityLiving) + { + ((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw; + } + + } + + entity.field_70118_ct = packet.rawX; + entity.field_70117_cu = packet.rawY; + entity.field_70116_cv = packet.rawZ; + if (entity instanceof IThrowableEntity) { Entity thrower = client.field_71439_g.field_70157_k == packet.throwerId ? client.field_71439_g : wc.func_73024_a(packet.throwerId); ((IThrowableEntity)entity).setThrower(thrower); } - entity.field_70118_ct = packet.rawX; - entity.field_70117_cu = packet.rawY; - entity.field_70116_cv = packet.rawZ; Entity parts[] = entity.func_70021_al(); if (parts != null) @@ -277,13 +297,6 @@ public class FMLClientHandler implements IFMLSidedHandler } } - entity.field_70157_k = packet.entityId; - entity.func_70012_b(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch); - - if (entity instanceof EntityLiving) - { - ((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw; - } if (packet.metadata != null) { diff --git a/client/cpw/mods/fml/client/modloader/ModLoaderClientHelper.java b/client/cpw/mods/fml/client/modloader/ModLoaderClientHelper.java index d233a02cfc..e3375097f2 100644 --- a/client/cpw/mods/fml/client/modloader/ModLoaderClientHelper.java +++ b/client/cpw/mods/fml/client/modloader/ModLoaderClientHelper.java @@ -21,13 +21,17 @@ import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; +import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.client.registry.KeyBindingRegistry; import cpw.mods.fml.client.registry.RenderingRegistry; +import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.modloader.BaseModProxy; import cpw.mods.fml.common.modloader.IModLoaderSidedHelper; import cpw.mods.fml.common.modloader.ModLoaderHelper; import cpw.mods.fml.common.modloader.ModLoaderModContainer; +import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; public class ModLoaderClientHelper implements IModLoaderSidedHelper { @@ -48,6 +52,7 @@ public class ModLoaderClientHelper implements IModLoaderSidedHelper public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game) { + FMLLog.finer("Handling post startup activities for ModLoader mod %s", mc.getModId()); BaseMod mod = (BaseMod) mc.getMod(); Map, Render> renderers = Maps.newHashMap(); @@ -56,6 +61,7 @@ public class ModLoaderClientHelper implements IModLoaderSidedHelper for (Entry, Render> e : renderers.entrySet()) { + FMLLog.finest("Registering ModLoader entity renderer %s as instance of %s", e.getKey().getName(), e.getValue().getClass().getName()); RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue()); } @@ -101,4 +107,11 @@ public class ModLoaderClientHelper implements IModLoaderSidedHelper { return ((net.minecraft.src.BaseMod)mod).getContainerGUI((EntityClientPlayerMP) player, ID, x, y, z); } + + + @Override + public Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration er) + { + return ((net.minecraft.src.BaseMod)mod).spawnEntity(er.getModEntityId(), client.field_71441_e, input.scaledX, input.scaledY, input.scaledZ); + } } diff --git a/client/net/minecraft/src/BaseMod.java b/client/net/minecraft/src/BaseMod.java index 21a7924047..ed956a1e32 100644 --- a/client/net/minecraft/src/BaseMod.java +++ b/client/net/minecraft/src/BaseMod.java @@ -224,7 +224,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr public void generateSurface(World world, Random random, int chunkX, int chunkZ) { } - + /** * Callback to return a gui screen to display * @param player @@ -239,7 +239,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr { return null; } - + /** * Return the name of your mod. Defaults to the class name * @@ -465,4 +465,20 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr } + /** + * + * Spawn the entity of the supplied type, if it is your mod's + * @param entityId + * @param world + * @param scaledX + * @param scaledY + * @param scaledZ + * @return + */ + @SideOnly(CLIENT) + public Entity spawnEntity(int entityId, World world, double scaledX, double scaledY, double scaledZ) + { + return null; + } + } diff --git a/client/net/minecraft/src/ModLoader.java b/client/net/minecraft/src/ModLoader.java index 0f6c5f0d9c..daacbaf229 100644 --- a/client/net/minecraft/src/ModLoader.java +++ b/client/net/minecraft/src/ModLoader.java @@ -113,6 +113,10 @@ public class ModLoader GameRegistry.addBiome(biome); } + public static void addEntityTracker(BaseMod mod, Class entityClass, int entityTypeId, int updateRange, int updateInterval, boolean sendVelocityInfo) + { + ModLoaderHelper.buildEntityTracker(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo); + } /** * Add localization for the specified string * diff --git a/common/cpw/mods/fml/common/FMLCommonHandler.java b/common/cpw/mods/fml/common/FMLCommonHandler.java index c8eaf5a917..e1e33eb539 100644 --- a/common/cpw/mods/fml/common/FMLCommonHandler.java +++ b/common/cpw/mods/fml/common/FMLCommonHandler.java @@ -38,6 +38,7 @@ import com.google.common.collect.Lists; import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket; import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.TickRegistry; import cpw.mods.fml.server.FMLServerHandler; @@ -333,9 +334,9 @@ public class FMLCommonHandler sidedDelegate.showGuiScreen(clientGuiElement); } - public Entity spawnEntityIntoClientWorld(Class cls, EntitySpawnPacket entitySpawnPacket) + public Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket entitySpawnPacket) { - return sidedDelegate.spawnEntityIntoClientWorld(cls, entitySpawnPacket); + return sidedDelegate.spawnEntityIntoClientWorld(registration, entitySpawnPacket); } public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket) diff --git a/common/cpw/mods/fml/common/IFMLSidedHandler.java b/common/cpw/mods/fml/common/IFMLSidedHandler.java index fe73694ce0..f25636e110 100644 --- a/common/cpw/mods/fml/common/IFMLSidedHandler.java +++ b/common/cpw/mods/fml/common/IFMLSidedHandler.java @@ -7,6 +7,7 @@ import net.minecraft.src.Entity; import net.minecraft.src.Packet; import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket; import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; public interface IFMLSidedHandler { @@ -18,7 +19,7 @@ public interface IFMLSidedHandler void showGuiScreen(Object clientGuiElement); - Entity spawnEntityIntoClientWorld(Class entityClass, EntitySpawnPacket packet); + Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket packet); void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket); diff --git a/common/cpw/mods/fml/common/modloader/BaseModProxy.java b/common/cpw/mods/fml/common/modloader/BaseModProxy.java index eac3732b40..73dfa045e8 100644 --- a/common/cpw/mods/fml/common/modloader/BaseModProxy.java +++ b/common/cpw/mods/fml/common/modloader/BaseModProxy.java @@ -16,6 +16,7 @@ package cpw.mods.fml.common.modloader; import java.util.Random; +import net.minecraft.src.Entity; import net.minecraft.src.EntityPlayer; import net.minecraft.src.GuiScreen; import net.minecraft.src.IInventory; @@ -24,6 +25,7 @@ import net.minecraft.src.NetHandler; import net.minecraft.src.NetworkManager; import net.minecraft.src.Packet250CustomPayload; import net.minecraft.src.World; +import net.minecraft.src.WorldClient; import cpw.mods.fml.common.Side; import cpw.mods.fml.common.TickType; import cpw.mods.fml.common.asm.SideOnly; diff --git a/common/cpw/mods/fml/common/modloader/IModLoaderSidedHelper.java b/common/cpw/mods/fml/common/modloader/IModLoaderSidedHelper.java index de773d29d8..a085e3e9ec 100644 --- a/common/cpw/mods/fml/common/modloader/IModLoaderSidedHelper.java +++ b/common/cpw/mods/fml/common/modloader/IModLoaderSidedHelper.java @@ -1,5 +1,8 @@ package cpw.mods.fml.common.modloader; +import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; +import net.minecraft.src.Entity; import net.minecraft.src.EntityPlayer; public interface IModLoaderSidedHelper @@ -9,4 +12,6 @@ public interface IModLoaderSidedHelper Object getClientGui(BaseModProxy mod, EntityPlayer player, int iD, int x, int y, int z); + Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration registration); + } diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderEntitySpawnCallback.java b/common/cpw/mods/fml/common/modloader/ModLoaderEntitySpawnCallback.java new file mode 100644 index 0000000000..0470f415de --- /dev/null +++ b/common/cpw/mods/fml/common/modloader/ModLoaderEntitySpawnCallback.java @@ -0,0 +1,30 @@ +package cpw.mods.fml.common.modloader; + +import java.util.concurrent.Callable; + +import com.google.common.base.Function; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; + +import net.minecraft.src.Entity; + +public class ModLoaderEntitySpawnCallback implements Function +{ + + private BaseModProxy mod; + private EntityRegistration registration; + + public ModLoaderEntitySpawnCallback(BaseModProxy mod, EntityRegistration er) + { + this.mod = mod; + this.registration = er; + } + + @Override + public Entity apply(EntitySpawnPacket input) + { + return ModLoaderHelper.sidedHelper.spawnEntity(mod, input, registration); + } +} diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java b/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java index df1bca1392..4fe41e795f 100644 --- a/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java +++ b/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java @@ -17,10 +17,13 @@ package cpw.mods.fml.common.modloader; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Callable; import com.google.common.collect.Maps; +import net.minecraft.src.BaseMod; import net.minecraft.src.Container; +import net.minecraft.src.Entity; import net.minecraft.src.EntityPlayer; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.ICraftingHandler; @@ -34,6 +37,8 @@ import cpw.mods.fml.common.network.IConnectionHandler; import cpw.mods.fml.common.network.IGuiHandler; import cpw.mods.fml.common.network.IPacketHandler; import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.registry.EntityRegistry; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; /** * @author cpw @@ -42,9 +47,9 @@ import cpw.mods.fml.common.network.NetworkRegistry; public class ModLoaderHelper { public static IModLoaderSidedHelper sidedHelper; - + private static Map guiHelpers = Maps.newHashMap(); - + public static void updateStandardTicks(BaseModProxy mod, boolean enable, boolean useClock) { ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer(); @@ -137,7 +142,7 @@ public class ModLoaderHelper helper.injectContainer(container); player.openGui(helper.getMod(), id, player.field_70170_p, x, y, z); } - + public static Object getClientSideGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z) { if (sidedHelper != null) @@ -151,4 +156,13 @@ public class ModLoaderHelper { return new ModLoaderDispenseHelper(mod); } + + + @SuppressWarnings("deprecation") + public static void buildEntityTracker(BaseModProxy mod, Class entityClass, int entityTypeId, int updateRange, int updateInterval, + boolean sendVelocityInfo) + { + EntityRegistration er = EntityRegistry.registerModLoaderEntity(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo); + er.setCustomSpawning(new ModLoaderEntitySpawnCallback(mod, er)); + } } diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java index 8b7c3cace1..94ccc008eb 100644 --- a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java +++ b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java @@ -51,6 +51,7 @@ import cpw.mods.fml.common.discovery.ASMDataTable.ASMData; import cpw.mods.fml.common.discovery.ContainerType; import cpw.mods.fml.common.event.FMLConstructionEvent; import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLLoadCompleteEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.network.FMLNetworkHandler; @@ -553,6 +554,12 @@ public class ModLoaderModContainer implements ModContainer } } + @Subscribe + public void loadComplete(FMLLoadCompleteEvent complete) + { + ModLoaderHelper.finishModLoading(this); + } + @Override public ArtifactVersion getProcessedVersion() { diff --git a/common/cpw/mods/fml/common/network/EntitySpawnPacket.java b/common/cpw/mods/fml/common/network/EntitySpawnPacket.java index d5a788f6d6..0a2e0f4587 100644 --- a/common/cpw/mods/fml/common/network/EntitySpawnPacket.java +++ b/common/cpw/mods/fml/common/network/EntitySpawnPacket.java @@ -182,7 +182,7 @@ public class EntitySpawnPacket extends FMLPacket } - Entity entity = FMLCommonHandler.instance().spawnEntityIntoClientWorld(cls, this); + Entity entity = FMLCommonHandler.instance().spawnEntityIntoClientWorld(registration, this); } } diff --git a/common/cpw/mods/fml/common/registry/EntityRegistry.java b/common/cpw/mods/fml/common/registry/EntityRegistry.java index ce4994ef7e..08e1644136 100644 --- a/common/cpw/mods/fml/common/registry/EntityRegistry.java +++ b/common/cpw/mods/fml/common/registry/EntityRegistry.java @@ -4,6 +4,7 @@ import java.util.BitSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; import java.util.logging.Level; import net.minecraft.src.BiomeGenBase; @@ -14,6 +15,7 @@ import net.minecraft.src.EntityTracker; import net.minecraft.src.EnumCreatureType; import net.minecraft.src.SpawnListEntry; +import com.google.common.base.Function; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; @@ -24,10 +26,11 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; public class EntityRegistry { - public class EntityRegistration { private Class entityClass; @@ -37,6 +40,7 @@ public class EntityRegistry private int trackingRange; private int updateFrequency; private boolean sendsVelocityUpdates; + private Function customSpawnCallback; public EntityRegistration(ModContainer mc, Class entityClass, String entityName, int id, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates) { this.container = mc; @@ -63,10 +67,6 @@ public class EntityRegistry { return modId; } - public int getModId() - { - return modId; - } public int getTrackingRange() { return trackingRange; @@ -79,6 +79,18 @@ public class EntityRegistry { return sendsVelocityUpdates; } + public boolean hasCustomSpawning() + { + return customSpawnCallback != null; + } + public Entity doCustomSpawning(EntitySpawnPacket packet) throws Exception + { + return customSpawnCallback.apply(packet); + } + public void setCustomSpawning(Function callable) + { + this.customSpawnCallback = callable; + } } private static final EntityRegistry INSTANCE = new EntityRegistry(); @@ -285,4 +297,28 @@ public class EntityRegistry return false; } + /** + * + * DO NOT USE THIS METHOD + * + * @param entityClass + * @param entityTypeId + * @param updateRange + * @param updateInterval + * @param sendVelocityInfo + * @return + */ + @Deprecated + public static EntityRegistration registerModLoaderEntity(Object mod, Class entityClass, int entityTypeId, int updateRange, int updateInterval, + boolean sendVelocityInfo) + { + String entityName = (String) EntityList.field_75626_c.get(entityClass); + if (entityName == null) + { + throw new IllegalArgumentException(String.format("The ModLoader mod %s has tried to register an entity tracker for a non-existent entity type %s", Loader.instance().activeModContainer().getModId(), entityClass.getCanonicalName())); + } + instance().doModEntityRegistration(entityClass, entityName, entityTypeId, mod, updateRange, updateInterval, sendVelocityInfo); + return instance().entityClassRegistrations.get(entityClass); + } + } diff --git a/common/cpw/mods/fml/server/FMLServerHandler.java b/common/cpw/mods/fml/server/FMLServerHandler.java index 56633c9d80..520bdb7b14 100644 --- a/common/cpw/mods/fml/server/FMLServerHandler.java +++ b/common/cpw/mods/fml/server/FMLServerHandler.java @@ -25,6 +25,7 @@ import cpw.mods.fml.common.ObfuscationReflectionHelper; import cpw.mods.fml.common.Side; import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket; import cpw.mods.fml.common.network.EntitySpawnPacket; +import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.LanguageRegistry; /** @@ -133,7 +134,7 @@ public class FMLServerHandler implements IFMLSidedHandler } @Override - public Entity spawnEntityIntoClientWorld(Class entityClass, EntitySpawnPacket packet) + public Entity spawnEntityIntoClientWorld(EntityRegistration er, EntitySpawnPacket packet) { // NOOP return null;