diff --git a/common/net/minecraftforge/common/IExtendedEntityProperties.java b/common/net/minecraftforge/common/IExtendedEntityProperties.java new file mode 100644 index 0000000000..d3f5586f5d --- /dev/null +++ b/common/net/minecraftforge/common/IExtendedEntityProperties.java @@ -0,0 +1,31 @@ +package net.minecraftforge.common; + +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +public interface IExtendedEntityProperties { + /** + * Called when the entity that this class is attached to is saved. + * Any custom entity data that needs saving should be saved here. + * @param compound The compound to save to. + */ + public void saveNBTData(NBTTagCompound compound); + + /** + * Called when the entity that this class is attached to is loaded. + * In order to hook into this, you will need to subscribe to the EntityConstructing event. + * Otherwise, you will need to initialize manually. + * @param compound The compound to load from. + */ + public void loadNBTData(NBTTagCompound compound); + + /** + * Used to initialize the extended properties with the entity that this is attached to, as well + * as the world object. + * Called automatically if you register with the EntityConstructing event. + * @param entity The entity that this extended properties is attached to + * @param world The world in which the entity exists + */ + public void init(Entity entity, World world); +} diff --git a/common/net/minecraftforge/event/entity/EntityEvent.java b/common/net/minecraftforge/event/entity/EntityEvent.java index 318c16d422..f7d287dd43 100644 --- a/common/net/minecraftforge/event/entity/EntityEvent.java +++ b/common/net/minecraftforge/event/entity/EntityEvent.java @@ -1,6 +1,7 @@ package net.minecraftforge.event.entity; import net.minecraft.entity.Entity; +import net.minecraft.world.World; import net.minecraftforge.event.Event; public class EntityEvent extends Event @@ -11,6 +12,13 @@ public class EntityEvent extends Event { this.entity = entity; } + + public static class EntityConstructing extends EntityEvent + { + public EntityConstructing(Entity entity){ + super(entity); + } + } public static class CanUpdate extends EntityEvent { diff --git a/patches/minecraft/net/minecraft/entity/Entity.java.patch b/patches/minecraft/net/minecraft/entity/Entity.java.patch index 320de7e312..e427ccf8e1 100644 --- a/patches/minecraft/net/minecraft/entity/Entity.java.patch +++ b/patches/minecraft/net/minecraft/entity/Entity.java.patch @@ -1,14 +1,17 @@ --- ../src_base/minecraft/net/minecraft/entity/Entity.java +++ ../src_work/minecraft/net/minecraft/entity/Entity.java -@@ -2,6 +2,7 @@ +@@ -1,7 +1,10 @@ + package net.minecraft.entity; ++import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import java.util.ArrayList; ++import java.util.HashMap; import java.util.List; import java.util.Random; import java.util.UUID; -@@ -13,8 +14,13 @@ +@@ -13,8 +16,13 @@ import net.minecraft.crash.CrashReportCategory; import net.minecraft.enchantment.EnchantmentProtection; import net.minecraft.entity.effect.EntityLightningBolt; @@ -22,7 +25,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagDouble; -@@ -25,6 +31,7 @@ +@@ -25,12 +33,16 @@ import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; import net.minecraft.util.MathHelper; @@ -30,7 +33,16 @@ import net.minecraft.util.ReportedException; import net.minecraft.util.StatCollector; import net.minecraft.util.Vec3; -@@ -225,6 +232,11 @@ + import net.minecraft.world.Explosion; + import net.minecraft.world.World; + import net.minecraft.world.WorldServer; ++import net.minecraftforge.common.IExtendedEntityProperties; ++import net.minecraftforge.common.MinecraftForge; ++import net.minecraftforge.event.entity.EntityEvent; + + public abstract class Entity + { +@@ -225,6 +237,13 @@ private boolean invulnerable; private UUID entityUniqueID; public EnumEntitySize myEntitySize; @@ -39,10 +51,27 @@ + public boolean captureDrops = false; + public ArrayList capturedDrops = new ArrayList(); + private UUID persistentID; ++ ++ private HashMap extendedProperties; public Entity(World par1World) { -@@ -554,7 +566,7 @@ +@@ -274,6 +293,14 @@ + this.dataWatcher.addObject(0, Byte.valueOf((byte)0)); + this.dataWatcher.addObject(1, Short.valueOf((short)300)); + this.entityInit(); ++ ++ extendedProperties = new HashMap(); ++ ++ MinecraftForge.EVENT_BUS.post(new EntityEvent.EntityConstructing(this)); ++ ++ for (IExtendedEntityProperties props : this.extendedProperties.values()){ ++ props.init(this, par1World); ++ } + } + + protected abstract void entityInit(); +@@ -554,7 +581,7 @@ if (!this.worldObj.isRemote) { this.setFlag(0, this.fire > 0); @@ -51,7 +80,7 @@ } this.firstUpdate = false; -@@ -1534,6 +1546,10 @@ +@@ -1534,6 +1561,21 @@ par1NBTTagCompound.setInteger("PortalCooldown", this.timeUntilPortal); par1NBTTagCompound.setLong("UUIDMost", this.entityUniqueID.getMostSignificantBits()); par1NBTTagCompound.setLong("UUIDLeast", this.entityUniqueID.getLeastSignificantBits()); @@ -59,10 +88,21 @@ + { + par1NBTTagCompound.setCompoundTag("ForgeData", customEntityData); + } ++ ++ for (String identifier : this.extendedProperties.keySet()){ ++ try{ ++ IExtendedEntityProperties props = this.extendedProperties.get(identifier); ++ props.saveNBTData(par1NBTTagCompound); ++ }catch (Throwable t){ ++ FMLLog.severe("Failed to save extended properties for %s. This is a mod issue.", identifier); ++ t.printStackTrace(); ++ } ++ } ++ this.writeEntityToNBT(par1NBTTagCompound); if (this.ridingEntity != null) -@@ -1604,6 +1620,15 @@ +@@ -1604,6 +1646,26 @@ this.setPosition(this.posX, this.posY, this.posZ); this.setRotation(this.rotationYaw, this.rotationPitch); @@ -70,6 +110,17 @@ + { + customEntityData = par1NBTTagCompound.getCompoundTag("ForgeData"); + } ++ ++ for (String identifier : this.extendedProperties.keySet()){ ++ try{ ++ IExtendedEntityProperties props = this.extendedProperties.get(identifier); ++ props.loadNBTData(par1NBTTagCompound); ++ }catch (Throwable t){ ++ FMLLog.severe("Failed to load extended properties for %s. This is a mod issue.", identifier); ++ t.printStackTrace(); ++ } ++ } ++ + //Rawr, legacy code, Vanilla added a UUID, keep this so older maps will convert properly + if (par1NBTTagCompound.hasKey("PersistentIDMSB") && par1NBTTagCompound.hasKey("PersistentIDLSB")) + { @@ -78,7 +129,7 @@ this.readEntityFromNBT(par1NBTTagCompound); } catch (Throwable throwable) -@@ -1698,7 +1723,14 @@ +@@ -1698,7 +1760,14 @@ { EntityItem entityitem = new EntityItem(this.worldObj, this.posX, this.posY + (double)par2, this.posZ, par1ItemStack); entityitem.delayBeforeCanPickup = 10; @@ -94,7 +145,7 @@ return entityitem; } -@@ -2056,7 +2088,7 @@ +@@ -2056,7 +2125,7 @@ */ public boolean isRiding() { @@ -103,7 +154,7 @@ } /** -@@ -2400,7 +2432,7 @@ +@@ -2400,7 +2469,7 @@ public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) { @@ -112,7 +163,7 @@ } public boolean func_96091_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, int par6, float par7) -@@ -2455,4 +2487,100 @@ +@@ -2455,4 +2524,139 @@ { return this.getEntityName(); } @@ -211,5 +262,44 @@ + public boolean isCreatureType(EnumCreatureType type, boolean forSpawnCount) + { + return type.getCreatureClass().isAssignableFrom(this.getClass()); ++ } ++ ++ /** ++ * Register the instance of IExtendedProperties into the entity's collection. ++ * @param identifier The identifier which you can use to retrieve these properties for the entity. ++ * @param properties The instanceof IExtendedProperties to register ++ * @return The identifier that was used to register the extended properties. Empty String indicates an error. If your requested key already existed, this will return a modified one that is unique. ++ */ ++ public String registerExtendedProperties(String identifier, IExtendedEntityProperties properties){ ++ if (identifier == null){ ++ FMLLog.warning("Someone is attempting to register extended properties using a null identifier. This is not allowed. Aborting. This may have caused instability."); ++ return ""; ++ } ++ if (properties == null){ ++ FMLLog.warning("Someone is attempting to register null extended properties. This is not allowed. Aborting. This may have caused instability."); ++ return ""; ++ } ++ ++ String baseIdentifier = identifier; ++ int identifierModCount = 1; ++ while (this.extendedProperties.containsKey(identifier)){ ++ identifier = String.format("%s%d", baseIdentifier, identifierModCount); ++ } ++ ++ if (baseIdentifier != identifier){ ++ FMLLog.info("An attempt was made to register exended properties using an existing key. The duplicate identifier (%s) has been remapped to %s.", baseIdentifier, identifier); ++ } ++ ++ this.extendedProperties.put(identifier, properties); ++ return identifier; ++ } ++ ++ /** ++ * Gets the extended properties identified by the passed in key ++ * @param identifier The key that identifies the extended properties. ++ * @return The instance of IExtendedProperties that was found, or null. ++ */ ++ public IExtendedEntityProperties getExtendedProperties(String identifier){ ++ return this.extendedProperties.get(identifier); + } }