From a7ea760097a0ce526dcc14a87083d7cc8d1f6dec Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 18 Jun 2012 20:16:48 -0700 Subject: [PATCH] Implemented enchanced EntityLiving events. Thanks Atomic for parts of it. --- .../net/minecraft/src/forge/ForgeHooks.java | 105 +++++++++++++- .../src/forge/IEntityLivingHandler.java | 127 +++++++++++++++++ .../src/forge/ISpecialMobSpawnHandler.java | 1 + .../minecraft/src/forge/MinecraftForge.java | 16 +++ .../adaptors/EntityLivingHandlerAdaptor.java | 64 +++++++++ .../net/minecraft/src/Entity.java.patch | 35 ++++- .../net/minecraft/src/EntityLiving.java.patch | 134 +++++++++++++++++- .../net/minecraft/src/EntityPlayer.java.patch | 35 +++-- .../minecraft/src/SpawnerAnimals.java.patch | 9 +- .../net/minecraft/src/Entity.java.patch | 33 ++++- .../net/minecraft/src/EntityLiving.java.patch | 132 ++++++++++++++++- .../net/minecraft/src/EntityPlayer.java.patch | 31 ++-- .../minecraft/src/SpawnerAnimals.java.patch | 9 +- 13 files changed, 691 insertions(+), 40 deletions(-) create mode 100644 forge/forge_common/net/minecraft/src/forge/IEntityLivingHandler.java create mode 100644 forge/forge_common/net/minecraft/src/forge/adaptors/EntityLivingHandlerAdaptor.java diff --git a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java index 726c44de3..02e6d5801 100644 --- a/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java +++ b/forge/forge_common/net/minecraft/src/forge/ForgeHooks.java @@ -9,6 +9,7 @@ import net.minecraft.src.BaseMod; import net.minecraft.src.Block; import net.minecraft.src.Chunk; import net.minecraft.src.ChunkCoordIntPair; +import net.minecraft.src.DamageSource; import net.minecraft.src.Entity; import net.minecraft.src.EntityItem; import net.minecraft.src.EntityLiving; @@ -340,7 +341,8 @@ public class ForgeHooks return 0; } static LinkedList fuelHandlers = new LinkedList(); - + + @SuppressWarnings("deprecation") //Internal use only, I don't want to see these yet public static boolean onEntitySpawnSpecial(EntityLiving entity, World world, float x, float y, float z) { for (ISpecialMobSpawnHandler handler : specialMobSpawnHandlers) @@ -352,7 +354,108 @@ public class ForgeHooks } return false; } + @SuppressWarnings("deprecation") static LinkedList specialMobSpawnHandlers = new LinkedList(); + + + public static boolean onEntityLivingSpawn(EntityLiving entity, World world, float x, float y, float z) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + if (handler.onEntityLivingSpawn(entity, world, x, y, z)) + { + return true; + } + } + return false; + } + + public static boolean onEntityLivingDeath(EntityLiving entity, DamageSource killer) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + if (handler.onEntityLivingDeath(entity, killer)) + { + return true; + } + } + return false; + } + + public static boolean onEntityLivingUpdate(EntityLiving entity) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + if (handler.onEntityLivingUpdate(entity)) + { + return true; + } + } + return false; + } + + public static void onEntityLivingJump(EntityLiving entity) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + handler.onEntityLivingJump(entity); + } + } + + public static boolean onEntityLivingFall(EntityLiving entity, float distance) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + if (handler.onEntityLivingFall(entity, distance)) + { + return true; + } + } + return false; + } + + public static boolean onEntityLivingAttacked(EntityLiving entity, DamageSource attack, int damage) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + if (handler.onEntityLivingAttacked(entity, attack, damage)) + { + return true; + } + } + return false; + } + + public static void onEntityLivingSetAttackTarget(EntityLiving entity, EntityLiving target) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + handler.onEntityLivingSetAttackTarget(entity, target); + } + } + + public static int onEntityLivingHurt(EntityLiving entity, DamageSource source, int damage) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + damage = handler.onEntityLivingHurt(entity, source, damage); + if (damage == 0) + { + return 0; + } + } + return damage; + } + + public static void onEntityLivingDrops(EntityLiving entity, DamageSource source, ArrayList drops, int lootingLevel, boolean recentlyHit, int specialDropValue) + { + for (IEntityLivingHandler handler : entityLivingHandlers) + { + handler.onEntityLivingDrops(entity, source, drops, lootingLevel, recentlyHit, specialDropValue); + } + } + + static LinkedList entityLivingHandlers = new LinkedList(); // Plant Management // ------------------------------------------------------------ diff --git a/forge/forge_common/net/minecraft/src/forge/IEntityLivingHandler.java b/forge/forge_common/net/minecraft/src/forge/IEntityLivingHandler.java new file mode 100644 index 000000000..1a86bd87a --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/IEntityLivingHandler.java @@ -0,0 +1,127 @@ +/** + * This software is provided under the terms of the Minecraft Forge Public + * License v1.0. + */ + +package net.minecraft.src.forge; + +import java.util.ArrayList; + +import net.minecraft.src.EntityItem; +import net.minecraft.src.EntityLiving; +import net.minecraft.src.DamageSource; +import net.minecraft.src.World; + +public interface IEntityLivingHandler +{ + /** + * Raised when an EntityLiving is spawned into the world from natural means, meaning + * not by command, MobSpawner, cheat, etc.. Just naturally throughout the world. + * + * This allows the mod to create special functionality that runs on a mob natural + * spawn. The Vanilla minecraft mechanic of having 'Spider Jockies', the color of + * sheep's wool, and Ocelot's spawning with babies can be canceled by returning + * true from this function + * + * Returning true will indicate that you have performed your special spawning, + * and no more handling will be done. + * + * @param entity The newly spawned entity + * @param world The world the entity is in + * @param x The Entitie's X Position + * @param y The Entitie's Y Position + * @param z The Entitie's Z Position + * @return True if the event was handled and no more processing should be done, false to continue processing + */ + public boolean onEntityLivingSpawn(EntityLiving entity, World world, float x, float y, float z); + + /** + * This is called when any EntityLiving's health reaches 0. + * You can cancel the death here, but you must raise the health or it will die again. + * In multiplayer, this is called by both the client and the server. + * + * @param entity Entity about to die + * @param killer DamageSource instance causing the death + * @return True to continue processing, false to cancel. + */ + public boolean onEntityLivingDeath(EntityLiving entity, DamageSource killer); + + /** + * This is called immediately after an EntityLiving receives a new attack target from AI classes. + * eg when a Zombie 'spots' a player. Handles friendly fire (setRevengeTarget) as well. + * In multiplayer, this is called by the server only. + * + * @param entity Entity attacking + * @param target Entity designated as new target + */ + public void onEntityLivingSetAttackTarget(EntityLiving entity, EntityLiving target); + + /** + * This is called when any EntityLiving takes damage from any DamageSource. + * In multiplayer, this is called by both the client and the server. + * + * @param entity Entity being attacked + * @param attack DamageSource instance of the attack + * @param damage Unmitigated damage the attack would cause + * @return True if the event was handled and no more processing should be done, false to continue processing + */ + public boolean onEntityLivingAttacked(EntityLiving entity, DamageSource attack, int damage); + + /** + * This is called immediately after an EntityLiving started a jump + * Velocity will already be set and can be modified. + * + * @param entity Entity starting the jump + */ + public void onEntityLivingJump(EntityLiving entity); + + /** + * This is called when an EntityLiving reconnects with the ground. + * Aborting this would stop both damage and the landing sound. + * + * @param entity Entity which fell + * @param distance absolute height between the last position touching the ground and the current. + * @return True if the event was handled and no more processing should be done, false to continue processing + */ + public boolean onEntityLivingFall(EntityLiving entity, float distance); + + /** + * This is called before EntityLiving's Base Update Tick. + * Aborting this process will freeze both Movement and Actions. + * + * @param entity Entity being ticked + * @return True if the event was handled and no more processing should be done, false to continue processing + */ + public boolean onEntityLivingUpdate(EntityLiving entity); + + /** + * This is called whenever a EntityLiving is hurt, before any armor calculations are taken into effect. + * Before any blocking, or potions are taken into account. + * Returning 0 from this will stop all processing. + * For the client's entity, this is only called in Single player, or if you are the server. + * + * @param entity The entity being hurt + * @param source The type of damage being dealt + * @param damage The amount of damage being dealt + * @return The amount of damage to let through. Returning 0 will prevent any further processing. + */ + public int onEntityLivingHurt(EntityLiving entity, DamageSource source, int damage); + + /** + * This is called after a EntityLiving die, and it spawns it's loot. The drop list should contain any item that the entity spawned at death. + * May not work properly on all Mod entities if they do not use dropFewItems/dropRareDrop/entityDropItem + * This will not contain the special record that creepers drop when they are killed by a Skeleton, or the apple notch drops. + * Or the player's inventory. + * + * If you need to deal with the Player's inventory, do so in onEntityLivingDeath + * In most cases, drops will be empty if the entity was a baby that hadn't reached full size yet. + * + * @param entity The entity that is droping the items + * @param source The damage source that caused the entities death + * @param drops An ArrayList containing all items to drop, AYou must make sure to not cause any concurancy exceptions with this + * @param lootingLevel The Looting enchantment level if the attacker was a player and they had the enchantment, else 0 + * @param recentlyHit Signifying if the entity was recently hit by a player. + * @param specialDropValue Random number used to determine if the 'special' loot should be dropped. 0 if the entity was a child + */ + public void onEntityLivingDrops(EntityLiving entity, DamageSource source, ArrayList drops, int lootingLevel, boolean recentlyHit, int specialDropValue); +} \ No newline at end of file diff --git a/forge/forge_common/net/minecraft/src/forge/ISpecialMobSpawnHandler.java b/forge/forge_common/net/minecraft/src/forge/ISpecialMobSpawnHandler.java index 5e1658592..88ea66e44 100644 --- a/forge/forge_common/net/minecraft/src/forge/ISpecialMobSpawnHandler.java +++ b/forge/forge_common/net/minecraft/src/forge/ISpecialMobSpawnHandler.java @@ -3,6 +3,7 @@ package net.minecraft.src.forge; import net.minecraft.src.EntityLiving; import net.minecraft.src.World; +@Deprecated //See IEntityLivingHandler public interface ISpecialMobSpawnHandler { /** diff --git a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java index 29333f9b5..3f90c2446 100755 --- a/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java +++ b/forge/forge_common/net/minecraft/src/forge/MinecraftForge.java @@ -9,6 +9,7 @@ import net.minecraft.src.Achievement; import net.minecraft.src.BaseMod; import net.minecraft.src.Block; import net.minecraft.src.Entity; +import net.minecraft.src.EntityLiving; import net.minecraft.src.EntityMinecart; import net.minecraft.src.Item; import net.minecraft.src.ItemStack; @@ -159,11 +160,26 @@ public class MinecraftForge * Register a new Special Mob Spawn handler * @param handler The handler to be registered */ + @Deprecated public static void registerSpecialMobSpawnHandler(ISpecialMobSpawnHandler handler) { + if (EntityLiving.class.getPackage() != null) + { + throw new RuntimeException("Still using deprecated method/interface MinecraftForge.registerSpecialModSpawnHandler()"); + } ForgeHooks.specialMobSpawnHandlers.add(handler); } + /** + * Register a new EntityLiving Handler + * @param handler The handler to be registered + */ + public static void registerEnitityLivingHandler(IEntityLivingHandler handler) + { + ForgeHooks.entityLivingHandlers.add(handler); + } + + /** * This is not supposed to be called outside of Minecraft internals. */ diff --git a/forge/forge_common/net/minecraft/src/forge/adaptors/EntityLivingHandlerAdaptor.java b/forge/forge_common/net/minecraft/src/forge/adaptors/EntityLivingHandlerAdaptor.java new file mode 100644 index 000000000..6f9d9d95f --- /dev/null +++ b/forge/forge_common/net/minecraft/src/forge/adaptors/EntityLivingHandlerAdaptor.java @@ -0,0 +1,64 @@ +package net.minecraft.src.forge.adaptors; + +import java.util.ArrayList; + +import net.minecraft.src.DamageSource; +import net.minecraft.src.EntityItem; +import net.minecraft.src.EntityLiving; +import net.minecraft.src.World; +import net.minecraft.src.forge.IEntityLivingHandler; + +public class EntityLivingHandlerAdaptor implements IEntityLivingHandler +{ + + @Override + public boolean onEntityLivingSpawn(EntityLiving entity, World world, float x, float y, float z) + { + return false; + } + + @Override + public boolean onEntityLivingDeath(EntityLiving entity, DamageSource killer) + { + return false; + } + + @Override + public void onEntityLivingSetAttackTarget(EntityLiving entity, EntityLiving target) + { + } + + @Override + public boolean onEntityLivingAttacked(EntityLiving entity, DamageSource attack, int damage) + { + return false; + } + + @Override + public void onEntityLivingJump(EntityLiving entity) + { + } + + @Override + public boolean onEntityLivingFall(EntityLiving entity, float distance) + { + return false; + } + + @Override + public boolean onEntityLivingUpdate(EntityLiving entity) + { + return false; + } + + @Override + public int onEntityLivingHurt(EntityLiving entity, DamageSource source, int damage) + { + return damage; + } + + @Override + public void onEntityLivingDrops(EntityLiving entity, DamageSource source, ArrayList drops, int lootingLevel, boolean recentlyHit, int specialDropValue) + { + } +} diff --git a/forge/patches/minecraft/net/minecraft/src/Entity.java.patch b/forge/patches/minecraft/net/minecraft/src/Entity.java.patch index 0d8447fc0..d5636f99c 100644 --- a/forge/patches/minecraft/net/minecraft/src/Entity.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/Entity.java.patch @@ -1,16 +1,25 @@ --- ../src_base/minecraft/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src_work/minecraft/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000 -@@ -173,6 +173,9 @@ +@@ -1,5 +1,6 @@ + package net.minecraft.src; + ++import java.util.ArrayList; + import java.util.List; + import java.util.Random; + +@@ -173,6 +174,11 @@ */ public boolean ignoreFrustumCheck; public boolean isAirBorne; + + /** Forge: Used to store custom data for each entity. */ + private NBTTagCompound customEntityData; ++ protected boolean captureDrops = false; ++ protected ArrayList capturedDrops = new ArrayList(); public Entity(World par1World) { -@@ -214,6 +217,29 @@ +@@ -214,6 +220,29 @@ } protected abstract void entityInit(); @@ -40,7 +49,7 @@ public DataWatcher getDataWatcher() { -@@ -1318,6 +1344,10 @@ +@@ -1318,6 +1347,10 @@ par1NBTTagCompound.setShort("Fire", (short)this.fire); par1NBTTagCompound.setShort("Air", (short)this.getAir()); par1NBTTagCompound.setBoolean("OnGround", this.onGround); @@ -51,7 +60,7 @@ this.writeEntityToNBT(par1NBTTagCompound); } -@@ -1359,6 +1389,10 @@ +@@ -1359,6 +1392,10 @@ this.onGround = par1NBTTagCompound.getBoolean("OnGround"); this.setPosition(this.posX, this.posY, this.posZ); this.setRotation(this.rotationYaw, this.rotationPitch); @@ -62,7 +71,23 @@ this.readEntityFromNBT(par1NBTTagCompound); } -@@ -1717,7 +1751,7 @@ +@@ -1444,7 +1481,14 @@ + { + EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY + (double)par2, this.posZ, par1ItemStack); + var3.delayBeforeCanPickup = 10; +- this.worldObj.spawnEntityInWorld(var3); ++ if (captureDrops) ++ { ++ capturedDrops.add(var3); ++ } ++ else ++ { ++ this.worldObj.spawnEntityInWorld(var3); ++ } + return var3; + } + +@@ -1717,7 +1761,7 @@ */ public boolean isRiding() { diff --git a/forge/patches/minecraft/net/minecraft/src/EntityLiving.java.patch b/forge/patches/minecraft/net/minecraft/src/EntityLiving.java.patch index 5cdc8d216..aac2f39b6 100644 --- a/forge/patches/minecraft/net/minecraft/src/EntityLiving.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/EntityLiving.java.patch @@ -1,6 +1,15 @@ --- ../src_base/minecraft/net/minecraft/src/EntityLiving.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src_work/minecraft/net/minecraft/src/EntityLiving.java 0000-00-00 00:00:00.000000000 -0000 -@@ -59,7 +59,7 @@ +@@ -6,6 +6,8 @@ + import java.util.List; + import java.util.Random; + ++import net.minecraft.src.forge.ForgeHooks; ++ + public abstract class EntityLiving extends Entity + { + public int heartsHalvesLife = 20; +@@ -59,7 +61,7 @@ * in each step in the damage calculations, this is set to the 'carryover' that would result if someone was damaged * .25 hearts (for example), and added to the damage in the next step */ @@ -9,7 +18,119 @@ /** Number of ticks since this EntityLiving last produced its sound */ private int livingSoundTime; -@@ -1342,7 +1342,7 @@ +@@ -303,6 +305,7 @@ + public void setAttackTarget(EntityLiving par1EntityLiving) + { + this.attackTarget = par1EntityLiving; ++ ForgeHooks.onEntityLivingSetAttackTarget(this, par1EntityLiving); + } + + public boolean func_48100_a(Class par1Class) +@@ -359,6 +362,7 @@ + { + this.entityLivingToAttack = par1EntityLiving; + this.revengeTimer = this.entityLivingToAttack != null ? 60 : 0; ++ ForgeHooks.onEntityLivingSetAttackTarget(this, par1EntityLiving); + } + + protected void entityInit() +@@ -641,7 +645,12 @@ + * Called to update the entity's position/logic. + */ + public void onUpdate() +- { ++ { ++ if (ForgeHooks.onEntityLivingUpdate(this)) ++ { ++ return; ++ } ++ + super.onUpdate(); + + if (this.arrowHitTempCounter > 0) +@@ -834,6 +843,11 @@ + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) + { ++ if (ForgeHooks.onEntityLivingAttacked(this, par1DamageSource, par2)) ++ { ++ return false; ++ } ++ + if (this.worldObj.isRemote) + { + return false; +@@ -1012,6 +1026,12 @@ + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) + { ++ par2 = ForgeHooks.onEntityLivingHurt(this, par1DamageSource, par2); ++ if (par2 == 0) ++ { ++ return; ++ } ++ + par2 = this.applyArmorCalculations(par1DamageSource, par2); + par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); + this.health -= par2; +@@ -1075,6 +1095,11 @@ + */ + public void onDeath(DamageSource par1DamageSource) + { ++ if (ForgeHooks.onEntityLivingDeath(this, par1DamageSource)) ++ { ++ return; ++ } ++ + Entity var2 = par1DamageSource.getEntity(); + + if (this.scoreValue >= 0 && var2 != null) +@@ -1098,13 +1123,17 @@ + var3 = EnchantmentHelper.getLootingModifier(((EntityPlayer)var2).inventory); + } + ++ captureDrops = true; ++ capturedDrops.clear(); ++ int var4 = 0; ++ + if (!this.isChild()) + { + this.dropFewItems(this.recentlyHit > 0, var3); + + if (this.recentlyHit > 0) + { +- int var4 = this.rand.nextInt(200) - var3; ++ var4 = this.rand.nextInt(200) - var3; + + if (var4 < 5) + { +@@ -1112,6 +1141,13 @@ + } + } + } ++ ++ captureDrops = false; ++ ForgeHooks.onEntityLivingDrops(this, par1DamageSource, capturedDrops, var3, recentlyHit > 0, var4); ++ for (EntityItem item : capturedDrops) ++ { ++ worldObj.spawnEntityInWorld(item); ++ } + } + + this.worldObj.setEntityState(this, (byte)3); +@@ -1155,6 +1191,11 @@ + */ + protected void fall(float par1) + { ++ if (ForgeHooks.onEntityLivingFall(this, par1)) ++ { ++ return; ++ } ++ + super.fall(par1); + int var2 = (int)Math.ceil((double)(par1 - 3.0F)); + +@@ -1342,7 +1383,7 @@ int var2 = MathHelper.floor_double(this.boundingBox.minY); int var3 = MathHelper.floor_double(this.posZ); int var4 = this.worldObj.getBlockId(var1, var2, var3); @@ -17,4 +138,13 @@ + return Block.blocksList[var4] != null && Block.blocksList[var4].isLadder(worldObj, var1, var2, var3); } + /** +@@ -1613,6 +1654,8 @@ + } + + this.isAirBorne = true; ++ ++ ForgeHooks.onEntityLivingJump(this); + } + /** diff --git a/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch b/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch index f961e3aab..bc421b58b 100644 --- a/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/EntityPlayer.java.patch @@ -60,7 +60,18 @@ { var3 = var2 + (float)(var4 * var4 + 1); } -@@ -983,7 +1003,11 @@ +@@ -978,12 +998,22 @@ + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) + { ++ par2 = ForgeHooks.onEntityLivingHurt(this, par1DamageSource, par2); ++ if (par2 == 0) ++ { ++ return; ++ } ++ + if (!par1DamageSource.isUnblockable() && this.isBlocking()) + { par2 = 1 + par2 >> 1; } @@ -73,7 +84,7 @@ par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); this.addExhaustion(par1DamageSource.getHungerDamage()); this.health -= par2; -@@ -1014,6 +1038,10 @@ +@@ -1014,6 +1044,10 @@ */ public void useCurrentItemOnEntity(Entity par1Entity) { @@ -84,7 +95,7 @@ if (!par1Entity.interact(this)) { ItemStack var2 = this.getCurrentEquippedItem(); -@@ -1044,7 +1072,9 @@ +@@ -1044,7 +1078,9 @@ */ public void destroyCurrentEquippedItem() { @@ -94,7 +105,7 @@ } /** -@@ -1073,6 +1103,15 @@ +@@ -1073,6 +1109,15 @@ */ public void attackTargetEntityWithCurrentItem(Entity par1Entity) { @@ -110,7 +121,7 @@ if (par1Entity.canAttackWithItem()) { int var2 = this.inventory.getDamageVsEntity(par1Entity); -@@ -1215,6 +1254,12 @@ +@@ -1215,6 +1260,12 @@ */ public EnumStatus sleepInBedAt(int par1, int par2, int par3) { @@ -123,7 +134,7 @@ if (!this.worldObj.isRemote) { if (this.isPlayerSleeping() || !this.isEntityAlive()) -@@ -1254,6 +1299,11 @@ +@@ -1254,6 +1305,11 @@ { int var9 = this.worldObj.getBlockMetadata(par1, par2, par3); int var5 = BlockBed.getDirection(var9); @@ -135,7 +146,7 @@ float var10 = 0.5F; float var7 = 0.5F; -@@ -1323,11 +1373,12 @@ +@@ -1323,11 +1379,12 @@ this.resetHeight(); ChunkCoordinates var4 = this.playerLocation; ChunkCoordinates var5 = this.playerLocation; @@ -151,7 +162,7 @@ if (var5 == null) { -@@ -1364,7 +1415,9 @@ +@@ -1364,7 +1421,9 @@ */ private boolean isInBed() { @@ -162,7 +173,7 @@ } /** -@@ -1379,13 +1432,15 @@ +@@ -1379,13 +1438,15 @@ var2.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); var2.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); @@ -180,7 +191,7 @@ return var3; } } -@@ -1397,8 +1452,11 @@ +@@ -1397,8 +1458,11 @@ { if (this.playerLocation != null) { @@ -194,7 +205,7 @@ switch (var2) { -@@ -1688,6 +1746,7 @@ +@@ -1688,6 +1752,7 @@ return 101; } } @@ -202,7 +213,7 @@ } return var3; -@@ -1860,4 +1919,30 @@ +@@ -1860,4 +1925,30 @@ } public void func_50009_aI() {} diff --git a/forge/patches/minecraft/net/minecraft/src/SpawnerAnimals.java.patch b/forge/patches/minecraft/net/minecraft/src/SpawnerAnimals.java.patch index a4f736019..f87acdfec 100644 --- a/forge/patches/minecraft/net/minecraft/src/SpawnerAnimals.java.patch +++ b/forge/patches/minecraft/net/minecraft/src/SpawnerAnimals.java.patch @@ -28,11 +28,16 @@ } } -@@ -211,6 +214,11 @@ +@@ -211,6 +214,16 @@ */ private static void creatureSpecificInit(EntityLiving par0EntityLiving, World par1World, float par2, float par3, float par4) { -+ if (ForgeHooks.onEntitySpawnSpecial(par0EntityLiving, par1World, par2, par3, par4)) ++ if (ForgeHooks.onEntitySpawnSpecial(par0EntityLiving, par1World, par2, par3, par4)) //Deprecated in 1.2.5, remove in 1.3 ++ { ++ return; ++ } ++ ++ if (ForgeHooks.onEntityLivingSpawn(par0EntityLiving, par1World, par2, par3, par4)) + { + return; + } diff --git a/forge/patches/minecraft_server/net/minecraft/src/Entity.java.patch b/forge/patches/minecraft_server/net/minecraft/src/Entity.java.patch index 52388563a..4a42c6d52 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/Entity.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/Entity.java.patch @@ -1,16 +1,25 @@ --- ../src_base/minecraft_server/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src_work/minecraft_server/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000 -@@ -165,6 +165,9 @@ +@@ -1,5 +1,6 @@ + package net.minecraft.src; + ++import java.util.ArrayList; + import java.util.List; + import java.util.Random; + +@@ -165,6 +166,11 @@ public boolean ignoreFrustumCheck; public boolean isAirBorne; + /** Forge: Used to store custom data for each entity. */ + private NBTTagCompound customEntityData; ++ protected boolean captureDrops = false; ++ protected ArrayList capturedDrops = new ArrayList(); + public Entity(World par1World) { this.entityId = nextEntityID++; -@@ -206,6 +209,29 @@ +@@ -206,6 +212,29 @@ protected abstract void entityInit(); @@ -40,7 +49,7 @@ public DataWatcher getDataWatcher() { return this.dataWatcher; -@@ -1215,6 +1241,10 @@ +@@ -1215,6 +1244,10 @@ par1NBTTagCompound.setShort("Fire", (short)this.fire); par1NBTTagCompound.setShort("Air", (short)this.getAir()); par1NBTTagCompound.setBoolean("OnGround", this.onGround); @@ -51,7 +60,7 @@ this.writeEntityToNBT(par1NBTTagCompound); } -@@ -1256,6 +1286,10 @@ +@@ -1256,6 +1289,10 @@ this.onGround = par1NBTTagCompound.getBoolean("OnGround"); this.setPosition(this.posX, this.posY, this.posZ); this.setRotation(this.rotationYaw, this.rotationPitch); @@ -62,3 +71,19 @@ this.readEntityFromNBT(par1NBTTagCompound); } +@@ -1336,7 +1373,14 @@ + { + EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY + (double)par2, this.posZ, par1ItemStack); + var3.delayBeforeCanPickup = 10; +- this.worldObj.spawnEntityInWorld(var3); ++ if (captureDrops) ++ { ++ capturedDrops.add(var3); ++ } ++ else ++ { ++ this.worldObj.spawnEntityInWorld(var3); ++ } + return var3; + } + diff --git a/forge/patches/minecraft_server/net/minecraft/src/EntityLiving.java.patch b/forge/patches/minecraft_server/net/minecraft/src/EntityLiving.java.patch index fa600e457..5019ccc89 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/EntityLiving.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/EntityLiving.java.patch @@ -1,6 +1,15 @@ --- ../src_base/minecraft_server/net/minecraft/src/EntityLiving.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src_work/minecraft_server/net/minecraft/src/EntityLiving.java 0000-00-00 00:00:00.000000000 -0000 -@@ -59,7 +59,7 @@ +@@ -6,6 +6,8 @@ + import java.util.List; + import java.util.Random; + ++import net.minecraft.src.forge.ForgeHooks; ++ + public abstract class EntityLiving extends Entity + { + public int heartsHalvesLife = 20; +@@ -59,7 +61,7 @@ * in each step in the damage calculations, this is set to the 'carryover' that would result if someone was damaged * .25 hearts (for example), and added to the damage in the next step */ @@ -9,7 +18,117 @@ /** Number of ticks since this EntityLiving last produced its sound */ private int livingSoundTime; -@@ -1307,7 +1307,7 @@ +@@ -300,6 +302,7 @@ + public void setAttackTarget(EntityLiving par1EntityLiving) + { + this.attackTarget = par1EntityLiving; ++ ForgeHooks.onEntityLivingSetAttackTarget(this, par1EntityLiving); + } + + public boolean func_48336_a(Class par1Class) +@@ -356,6 +359,7 @@ + { + this.entityLivingToAttack = par1EntityLiving; + this.revengeTimer = this.entityLivingToAttack != null ? 60 : 0; ++ ForgeHooks.onEntityLivingSetAttackTarget(this, par1EntityLiving); + } + + protected void entityInit() +@@ -616,6 +620,11 @@ + */ + public void onUpdate() + { ++ if (ForgeHooks.onEntityLivingUpdate(this)) ++ { ++ return; ++ } ++ + super.onUpdate(); + + if (this.arrowHitTempCounter > 0) +@@ -808,6 +817,11 @@ + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) + { ++ if (ForgeHooks.onEntityLivingAttacked(this, par1DamageSource, par2)) ++ { ++ return false; ++ } ++ + if (this.worldObj.isRemote) + { + return false; +@@ -977,6 +991,12 @@ + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) + { ++ par2 = ForgeHooks.onEntityLivingHurt(this, par1DamageSource, par2); ++ if (par2 == 0) ++ { ++ return; ++ } ++ + par2 = this.applyArmorCalculations(par1DamageSource, par2); + par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); + this.health -= par2; +@@ -1040,6 +1060,11 @@ + */ + public void onDeath(DamageSource par1DamageSource) + { ++ if (ForgeHooks.onEntityLivingDeath(this, par1DamageSource)) ++ { ++ return; ++ } ++ + Entity var2 = par1DamageSource.getEntity(); + + if (this.scoreValue >= 0 && var2 != null) +@@ -1063,13 +1088,17 @@ + var3 = EnchantmentHelper.getLootingModifier(((EntityPlayer)var2).inventory); + } + ++ captureDrops = true; ++ capturedDrops.clear(); ++ int var4 = 0; ++ + if (!this.isChild()) + { + this.dropFewItems(this.recentlyHit > 0, var3); + + if (this.recentlyHit > 0) + { +- int var4 = this.rand.nextInt(200) - var3; ++ var4 = this.rand.nextInt(200) - var3; + + if (var4 < 5) + { +@@ -1077,6 +1106,13 @@ + } + } + } ++ ++ captureDrops = false; ++ ForgeHooks.onEntityLivingDrops(this, par1DamageSource, capturedDrops, var3, recentlyHit > 0, var4); ++ for (EntityItem item : capturedDrops) ++ { ++ worldObj.spawnEntityInWorld(item); ++ } + } + + this.worldObj.setEntityState(this, (byte)3); +@@ -1120,6 +1156,11 @@ + */ + protected void fall(float par1) + { ++ if (ForgeHooks.onEntityLivingFall(this, par1)) ++ { ++ return; ++ } ++ + super.fall(par1); + int var2 = (int)Math.ceil((double)(par1 - 3.0F)); + +@@ -1307,7 +1348,7 @@ int var2 = MathHelper.floor_double(this.boundingBox.minY); int var3 = MathHelper.floor_double(this.posZ); int var4 = this.worldObj.getBlockId(var1, var2, var3); @@ -17,4 +136,13 @@ + return (Block.blocksList[var4] != null && Block.blocksList[var4].isLadder(worldObj, var1, var2, var3)); } + /** +@@ -1578,6 +1619,8 @@ + } + + this.isAirBorne = true; ++ ++ ForgeHooks.onEntityLivingJump(this); + } + /** diff --git a/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch b/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch index 87df56871..4a9e76714 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/EntityPlayer.java.patch @@ -72,7 +72,18 @@ float var3 = var2; int var4 = EnchantmentHelper.getEfficiencyModifier(this.inventory); -@@ -914,7 +944,11 @@ +@@ -909,12 +939,22 @@ + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) + { ++ par2 = ForgeHooks.onEntityLivingHurt(this, par1DamageSource, par2); ++ if (par2 == 0) ++ { ++ return; ++ } ++ + if (!par1DamageSource.isUnblockable() && this.isBlocking()) + { par2 = 1 + par2 >> 1; } @@ -85,7 +96,7 @@ par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); this.addExhaustion(par1DamageSource.getHungerDamage()); this.health -= par2; -@@ -945,6 +979,10 @@ +@@ -945,6 +985,10 @@ */ public void useCurrentItemOnEntity(Entity par1Entity) { @@ -96,7 +107,7 @@ if (!par1Entity.interact(this)) { ItemStack var2 = this.getCurrentEquippedItem(); -@@ -975,7 +1013,9 @@ +@@ -975,7 +1019,9 @@ */ public void destroyCurrentEquippedItem() { @@ -106,7 +117,7 @@ } /** -@@ -1004,6 +1044,16 @@ +@@ -1004,6 +1050,16 @@ */ public void attackTargetEntityWithCurrentItem(Entity par1Entity) { @@ -123,7 +134,7 @@ if (par1Entity.canAttackWithItem()) { int var2 = this.inventory.getDamageVsEntity(par1Entity); -@@ -1142,6 +1192,12 @@ +@@ -1142,6 +1198,12 @@ */ public EnumStatus sleepInBedAt(int par1, int par2, int par3) { @@ -136,7 +147,7 @@ if (!this.worldObj.isRemote) { if (this.isPlayerSleeping() || !this.isEntityAlive()) -@@ -1181,6 +1237,11 @@ +@@ -1181,6 +1243,11 @@ { int var9 = this.worldObj.getBlockMetadata(par1, par2, par3); int var5 = BlockBed.getDirection(var9); @@ -148,7 +159,7 @@ float var10 = 0.5F; float var7 = 0.5F; -@@ -1250,11 +1311,12 @@ +@@ -1250,11 +1317,12 @@ this.resetHeight(); ChunkCoordinates var4 = this.playerLocation; ChunkCoordinates var5 = this.playerLocation; @@ -164,7 +175,7 @@ if (var5 == null) { -@@ -1291,7 +1353,9 @@ +@@ -1291,7 +1359,9 @@ */ private boolean isInBed() { @@ -175,7 +186,7 @@ } /** -@@ -1306,13 +1370,15 @@ +@@ -1306,13 +1376,15 @@ var2.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); var2.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); @@ -193,7 +204,7 @@ return var3; } } -@@ -1719,4 +1785,45 @@ +@@ -1719,4 +1791,45 @@ } public void func_50022_L() {} diff --git a/forge/patches/minecraft_server/net/minecraft/src/SpawnerAnimals.java.patch b/forge/patches/minecraft_server/net/minecraft/src/SpawnerAnimals.java.patch index 55bb1bb00..e5c0a67cb 100644 --- a/forge/patches/minecraft_server/net/minecraft/src/SpawnerAnimals.java.patch +++ b/forge/patches/minecraft_server/net/minecraft/src/SpawnerAnimals.java.patch @@ -28,11 +28,16 @@ } } -@@ -211,6 +214,11 @@ +@@ -211,6 +214,16 @@ */ private static void creatureSpecificInit(EntityLiving par0EntityLiving, World par1World, float par2, float par3, float par4) { -+ if (ForgeHooks.onEntitySpawnSpecial(par0EntityLiving, par1World, par2, par3, par4)) ++ if (ForgeHooks.onEntitySpawnSpecial(par0EntityLiving, par1World, par2, par3, par4)) //Deprecated in 1.2.5, remove in 1.3 ++ { ++ return; ++ } ++ ++ if (ForgeHooks.onEntityLivingSpawn(par0EntityLiving, par1World, par2, par3, par4)) + { + return; + }