diff --git a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch b/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch index 471635a94..8fbd5f096 100644 --- a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch +++ b/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch @@ -46,15 +46,46 @@ } protected void applyEntityAttributes() -@@ -227,6 +247,7 @@ +@@ -195,7 +215,8 @@ + { + if (this.itemInUse != null) + { +- this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount); ++ if (!ForgeEventFactory.onUseItemStop(this, itemInUse, itemInUseCount)) ++ this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount); + } + + this.clearItemInUse(); +@@ -227,14 +248,23 @@ if (itemstack == this.itemInUse) { -+ itemInUse.getItem().onUsingTick(itemInUse, this, itemInUseCount); - if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0) +- if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0) ++ itemInUseCount = ForgeEventFactory.onItemUseTick(this, itemInUse, itemInUseCount); ++ if (itemInUseCount <= 0) { - this.updateItemUse(itemstack, 5); -@@ -281,7 +302,7 @@ +- this.updateItemUse(itemstack, 5); ++ this.onItemUseFinish(); + } +- +- if (--this.itemInUseCount == 0 && !this.worldObj.isRemote) ++ else + { +- this.onItemUseFinish(); ++ itemInUse.getItem().onUsingTick(itemInUse, this, itemInUseCount); ++ if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0) ++ { ++ this.updateItemUse(itemstack, 5); ++ } ++ ++ if (--this.itemInUseCount == 0 && !this.worldObj.isRemote) ++ { ++ this.onItemUseFinish(); ++ } + } + } + else +@@ -281,7 +311,7 @@ super.onUpdate(); @@ -63,7 +94,22 @@ { this.closeScreen(); this.openContainer = this.inventoryContainer; -@@ -498,11 +519,11 @@ +@@ -416,11 +446,13 @@ + int i = this.itemInUse.stackSize; + ItemStack itemstack = this.itemInUse.onFoodEaten(this.worldObj, this); + ++ itemstack = ForgeEventFactory.onItemUseFinish(this, itemInUse, itemInUseCount, itemstack); ++ + if (itemstack != this.itemInUse || itemstack != null && itemstack.stackSize != i) + { + this.inventory.mainInventory[this.inventory.currentItem] = itemstack; + +- if (itemstack.stackSize == 0) ++ if (itemstack != null && itemstack.stackSize == 0) + { + this.inventory.mainInventory[this.inventory.currentItem] = null; + } +@@ -498,11 +530,11 @@ this.cameraYaw = 0.0F; this.addMountedMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2); @@ -77,7 +123,7 @@ } } } -@@ -632,11 +653,15 @@ +@@ -632,11 +664,15 @@ // JAVADOC METHOD $$ func_70645_a public void onDeath(DamageSource par1DamageSource) { @@ -93,7 +139,7 @@ if (this.getCommandSenderName().equals("Notch")) { this.func_146097_a(new ItemStack(Items.apple, 1), true, false); -@@ -647,6 +672,20 @@ +@@ -647,6 +683,20 @@ this.inventory.dropAllItems(); } @@ -114,7 +160,7 @@ if (par1DamageSource != null) { this.motionX = (double)(-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F); -@@ -702,13 +741,26 @@ +@@ -702,13 +752,26 @@ // JAVADOC METHOD $$ func_71040_bB public EntityItem dropOneItem(boolean par1) { @@ -143,7 +189,7 @@ } public EntityItem func_146097_a(ItemStack p_146097_1_, boolean p_146097_2_, boolean p_146097_3_) -@@ -765,13 +817,25 @@ +@@ -765,13 +828,25 @@ // JAVADOC METHOD $$ func_71012_a public void joinEntityItemWithWorld(EntityItem par1EntityItem) { @@ -170,7 +216,7 @@ if (f > 1.0F) { int i = EnchantmentHelper.getEfficiencyModifier(this); -@@ -781,7 +845,9 @@ +@@ -781,7 +856,9 @@ { float f1 = (float)(i * i + 1); @@ -181,7 +227,7 @@ { f += f1 * 0.08F; } -@@ -812,12 +878,13 @@ +@@ -812,12 +889,13 @@ f /= 5.0F; } @@ -197,7 +243,7 @@ } // JAVADOC METHOD $$ func_70037_a -@@ -847,6 +914,16 @@ +@@ -847,6 +925,16 @@ this.spawnForced = par1NBTTagCompound.getBoolean("SpawnForced"); } @@ -214,7 +260,7 @@ this.foodStats.readNBT(par1NBTTagCompound); this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound); -@@ -878,6 +955,23 @@ +@@ -878,6 +966,23 @@ par1NBTTagCompound.setBoolean("SpawnForced", this.spawnForced); } @@ -238,7 +284,7 @@ this.foodStats.writeNBT(par1NBTTagCompound); this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound); par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT()); -@@ -902,7 +996,7 @@ +@@ -902,7 +1007,7 @@ public float getEyeHeight() { @@ -247,7 +293,7 @@ } // JAVADOC METHOD $$ func_71061_d_ -@@ -914,6 +1008,7 @@ +@@ -914,6 +1019,7 @@ // JAVADOC METHOD $$ func_70097_a public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) { @@ -255,7 +301,7 @@ if (this.isEntityInvulnerable()) { return false; -@@ -1018,12 +1113,15 @@ +@@ -1018,12 +1124,15 @@ { if (!this.isEntityInvulnerable()) { @@ -272,7 +318,7 @@ par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); float f1 = par2; par2 = Math.max(par2 - this.getAbsorptionAmount(), 0.0F); -@@ -1058,6 +1156,7 @@ +@@ -1058,6 +1167,7 @@ public boolean interactWith(Entity par1Entity) { @@ -280,7 +326,7 @@ ItemStack itemstack = this.getCurrentEquippedItem(); ItemStack itemstack1 = itemstack != null ? itemstack.copy() : null; -@@ -1110,7 +1209,9 @@ +@@ -1110,7 +1220,9 @@ // JAVADOC METHOD $$ func_71028_bD public void destroyCurrentEquippedItem() { @@ -290,7 +336,7 @@ } // JAVADOC METHOD $$ func_70033_W -@@ -1122,6 +1223,15 @@ +@@ -1122,6 +1234,15 @@ // JAVADOC METHOD $$ func_71059_n public void attackTargetEntityWithCurrentItem(Entity par1Entity) { @@ -306,7 +352,7 @@ if (par1Entity.canAttackWithItem()) { if (!par1Entity.hitByEntity(this)) -@@ -1273,6 +1383,12 @@ +@@ -1273,6 +1394,12 @@ // JAVADOC METHOD $$ func_71018_a public EntityPlayer.EnumStatus sleepInBedAt(int par1, int par2, int par3) { @@ -319,7 +365,7 @@ if (!this.worldObj.isRemote) { if (this.isPlayerSleeping() || !this.isEntityAlive()) -@@ -1315,8 +1431,7 @@ +@@ -1315,8 +1442,7 @@ if (this.worldObj.blockExists(par1, par2, par3)) { @@ -329,7 +375,7 @@ float f1 = 0.5F; float f = 0.5F; -@@ -1384,11 +1499,12 @@ +@@ -1384,11 +1510,12 @@ this.resetHeight(); ChunkCoordinates chunkcoordinates = this.playerLocation; ChunkCoordinates chunkcoordinates1 = this.playerLocation; @@ -345,7 +391,7 @@ if (chunkcoordinates1 == null) { -@@ -1423,7 +1539,7 @@ +@@ -1423,7 +1550,7 @@ // JAVADOC METHOD $$ func_71065_l private boolean isInBed() { @@ -354,7 +400,7 @@ } // JAVADOC METHOD $$ func_71056_a -@@ -1435,9 +1551,9 @@ +@@ -1435,9 +1562,9 @@ ichunkprovider.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); ichunkprovider.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); @@ -366,7 +412,7 @@ return chunkcoordinates1; } else -@@ -1456,8 +1572,10 @@ +@@ -1456,8 +1583,10 @@ { if (this.playerLocation != null) { @@ -379,7 +425,7 @@ switch (j) { -@@ -1516,19 +1634,26 @@ +@@ -1516,19 +1645,26 @@ public void func_146105_b(IChatComponent p_146105_1_) {} // JAVADOC METHOD $$ func_70997_bJ @@ -408,7 +454,7 @@ if (par1ChunkCoordinates != null) { this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates); -@@ -1710,6 +1835,10 @@ +@@ -1710,6 +1846,10 @@ super.fall(par1); } @@ -419,7 +465,7 @@ } protected String func_146067_o(int p_146067_1_) -@@ -1755,11 +1884,6 @@ +@@ -1755,11 +1895,6 @@ } else { @@ -431,7 +477,7 @@ if (this.itemInUse != null && par1ItemStack.getItem() == Items.bow) { int j = par1ItemStack.getMaxItemUseDuration() - this.itemInUseCount; -@@ -1779,6 +1903,7 @@ +@@ -1779,6 +1914,7 @@ return Items.bow.getItemIconForUseDuration(0); } } @@ -439,7 +485,16 @@ } return iicon; -@@ -1967,6 +2092,17 @@ +@@ -1869,6 +2005,8 @@ + { + if (par1ItemStack != this.itemInUse) + { ++ par2 = ForgeEventFactory.onItemUseStart(this, par1ItemStack, par2); ++ if (par2 <= 0) return; + this.itemInUse = par1ItemStack; + this.itemInUseCount = par2; + +@@ -1967,6 +2105,17 @@ } this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest; @@ -457,7 +512,7 @@ } // JAVADOC METHOD $$ func_70041_e_ -@@ -2013,7 +2149,14 @@ +@@ -2013,7 +2162,14 @@ // JAVADOC METHOD $$ func_70062_b public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { @@ -473,7 +528,7 @@ } // JAVADOC METHOD $$ func_98034_c -@@ -2059,7 +2202,7 @@ +@@ -2059,7 +2215,7 @@ public IChatComponent func_145748_c_() { @@ -482,7 +537,7 @@ chatcomponenttext.func_150256_b().func_150241_a(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/msg " + this.getCommandSenderName() + " ")); return chatcomponenttext; } -@@ -2096,6 +2239,119 @@ +@@ -2096,6 +2252,119 @@ FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z); } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index 56877b6dd..91cd66187 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -2,7 +2,6 @@ package net.minecraftforge.event; import java.util.ArrayList; import java.util.List; - import cpw.mods.fml.common.eventhandler.Event.Result; import net.minecraft.block.Block; import net.minecraft.entity.Entity; @@ -27,6 +26,7 @@ import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; +import net.minecraftforge.event.entity.player.PlayerUseItemEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.WorldEvent; @@ -125,4 +125,28 @@ public class ForgeEventFactory { return MinecraftForge.EVENT_BUS.post(new EntityStruckByLightningEvent(entity, bolt)); } + + public static int onItemUseStart(EntityPlayer player, ItemStack item, int duration) + { + PlayerUseItemEvent event = new PlayerUseItemEvent.Start(player, item, duration); + return MinecraftForge.EVENT_BUS.post(event) ? -1 : event.duration; + } + + public static int onItemUseTick(EntityPlayer player, ItemStack item, int duration) + { + PlayerUseItemEvent event = new PlayerUseItemEvent.Tick(player, item, duration); + return MinecraftForge.EVENT_BUS.post(event) ? -1 : event.duration; + } + + public static boolean onUseItemStop(EntityPlayer player, ItemStack item, int duration) + { + return MinecraftForge.EVENT_BUS.post(new PlayerUseItemEvent.Stop(player, item, duration)); + } + + public static ItemStack onItemUseFinish(EntityPlayer player, ItemStack item, int duration, ItemStack result) + { + PlayerUseItemEvent.Finish event = new PlayerUseItemEvent.Finish(player, item, duration, result); + MinecraftForge.EVENT_BUS.post(event); + return event.result; + } } diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerUseItemEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PlayerUseItemEvent.java new file mode 100644 index 000000000..ff91c6f94 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/entity/player/PlayerUseItemEvent.java @@ -0,0 +1,94 @@ +package net.minecraftforge.event.entity.player; + +import cpw.mods.fml.common.eventhandler.Cancelable; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public abstract class PlayerUseItemEvent extends PlayerEvent +{ + public final ItemStack item; + public int duration; + + private PlayerUseItemEvent(EntityPlayer player, ItemStack item, int duration) + { + super(player); + this.item = item; + this.duration = duration; + } + + /** + * Fired when a player starts 'using' an item, typically when they hold right mouse. + * Examples: + * Drawing a bow + * Eating Food + * Drinking Potions/Milk + * Guarding with a sword + * + * Cancel the event, or set the duration or <= 0 to prevent it from processing. + * + */ + @Cancelable + public static class Start extends PlayerUseItemEvent + { + public Start(EntityPlayer player, ItemStack item, int duration) + { + super(player, item, duration); + } + } + + /** + * Fired every tick that a player is 'using' an item, see {@link Start} for info. + * + * Cancel the event, or set the duration or <= 0 to cause the player to stop using the item. + * + */ + @Cancelable + public static class Tick extends PlayerUseItemEvent + { + public Tick(EntityPlayer player, ItemStack item, int duration) + { + super(player, item, duration); + } + } + + /** + * Fired when a player stops using an item without the use duration timing out. + * Example: + * Stop eating 1/2 way through + * Stop defending with sword + * Stop drawing bow. This case would fire the arrow + * + * Duration on this event is how long the item had left in it's count down before 'finishing' + * + * Canceling this event will prevent the Item from being notified that it has stopped being used, + * The only vanilla item this would effect are bows, and it would cause them NOT to fire there arrow. + */ + @Cancelable + public static class Stop extends PlayerUseItemEvent + { + public Stop(EntityPlayer player, ItemStack item, int duration) + { + super(player, item, duration); + } + } + + /** + * Fired after an item has fully finished being used. + * The item has been notified that it was used, and the item/result stacks reflect after that state. + * This means that when this is fired for a Potion, the potion effect has already been applied. + * + * If you wish to cancel those effects, you should cancel one of the above events. + * + * The result item stack is the stack that is placed in the player's inventory in replacement of the stack that is currently being used. + * + */ + public static class Finish extends PlayerUseItemEvent + { + public ItemStack result; + public Finish(EntityPlayer player, ItemStack item, int duration, ItemStack result) + { + super(player, item, duration); + this.result = result; + } + } +}