From 5ba892804158ba81b655826469363eefa8f0baaa Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Mon, 5 Mar 2012 14:21:43 -0500 Subject: [PATCH] [Bleeding] Added getting and setting drops to all appropriate events. Fixes BUKKIT-397 and fixes BUKKIT-1252 - Allows drops in creative mode by adding items to the getDrops() list - Contents of containers are not reported - Contents of storage minecarts are not reported --- src/main/java/net/minecraft/server/Block.java | 30 +++++++++ .../java/net/minecraft/server/BlockBed.java | 8 ++- .../java/net/minecraft/server/BlockCrops.java | 3 + .../net/minecraft/server/BlockDeadBush.java | 17 +++++ .../java/net/minecraft/server/BlockDoor.java | 5 +- .../net/minecraft/server/BlockLeaves.java | 17 +++++ .../net/minecraft/server/BlockLongGrass.java | 17 +++++ .../server/BlockPistonExtension.java | 23 ++++++- .../java/net/minecraft/server/BlockSnow.java | 14 +++++ .../java/net/minecraft/server/BlockStem.java | 3 + .../java/net/minecraft/server/BlockTNT.java | 11 ++++ .../java/net/minecraft/server/BlockVine.java | 17 +++++ .../java/net/minecraft/server/Entity.java | 10 ++- .../java/net/minecraft/server/EntityBoat.java | 62 +++++++++++++++---- .../net/minecraft/server/EntityMinecart.java | 31 +++++++--- .../minecraft/server/EntityMushroomCow.java | 19 +++++- .../net/minecraft/server/EntityPainting.java | 25 ++++++-- .../net/minecraft/server/EntitySheep.java | 19 +++++- .../minecraft/server/ItemInWorldManager.java | 30 +++------ .../craftbukkit/event/CraftEventFactory.java | 43 +++++++++++++ 20 files changed, 344 insertions(+), 60 deletions(-) diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java index 0cd743ce90..ede8508752 100644 --- a/src/main/java/net/minecraft/server/Block.java +++ b/src/main/java/net/minecraft/server/Block.java @@ -164,6 +164,7 @@ public class Block { public final Material material; public float frictionFactor; private String name; + protected ArrayList dropList; // CraftBukkit protected Block(int i, Material material) { this.bR = true; @@ -358,6 +359,17 @@ public class Block { } protected void a(World world, int i, int j, int k, ItemStack itemstack) { + // CraftBukkit start - the logic of this function is moved into finishDrop + if (this.dropList != null) { + this.dropList.add(itemstack); + } else { + this.finishDrop(world, i, j, k, itemstack); + } + } + + public final void finishDrop(World world, int i, int j, int k, ItemStack itemstack) { + this.dropList = null; + // CraftBukkit end if (!world.isStatic) { float f = 0.7F; double d0 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; @@ -529,6 +541,23 @@ public class Block { public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) { entityhuman.a(StatisticList.C[this.id], 1); entityhuman.c(0.025F); + // CraftBukkit start - A way to separate statistics from the logic of determining what to drop + this.doActualDrop(world, entityhuman, i, j, k, l); + } + + public void doActualDrop(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + for (ItemStack stack : dropList) { + finishDrop(world, i, j, k, stack); + } + } + + public void setDrops(ArrayList drops) { + this.dropList = drops; + } + + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + this.dropList = new ArrayList(); + // CraftBukkit end if (this.b() && !this.isTileEntity && EnchantmentManager.hasSilkTouchEnchantment(entityhuman.inventory)) { ItemStack itemstack = this.a_(l); @@ -540,6 +569,7 @@ public class Block { this.b(world, i, j, k, l, i1); } + return this.dropList; // CraftBukkit } protected ItemStack a_(int i) { diff --git a/src/main/java/net/minecraft/server/BlockBed.java b/src/main/java/net/minecraft/server/BlockBed.java index 68232ad830..cc93b4caf8 100644 --- a/src/main/java/net/minecraft/server/BlockBed.java +++ b/src/main/java/net/minecraft/server/BlockBed.java @@ -129,14 +129,16 @@ public class BlockBed extends BlockDirectional { } } else if (world.getTypeId(i + a[j1][0], j, k + a[j1][1]) != this.id) { world.setTypeId(i, j, k, 0); + /* CraftBukkit - Move this to on break instead of on physics if (!world.isStatic) { this.b(world, i, j, k, i1, 0); } + // */ } } public int getDropType(int i, Random random, int j) { - return d(i) ? 0 : Item.BED.id; + return /* d(i) ? 0 CraftBukkit : */ Item.BED.id; } private void s() { @@ -190,9 +192,9 @@ public class BlockBed extends BlockDirectional { } public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) { - if (!d(l)) { + //if (!d(l)) { // CraftBukkit super.dropNaturally(world, i, j, k, l, f, 0); - } + // } // CraftBukkit } public int g() { diff --git a/src/main/java/net/minecraft/server/BlockCrops.java b/src/main/java/net/minecraft/server/BlockCrops.java index dfdbc746a3..eafc2d7b4a 100644 --- a/src/main/java/net/minecraft/server/BlockCrops.java +++ b/src/main/java/net/minecraft/server/BlockCrops.java @@ -96,6 +96,7 @@ public class BlockCrops extends BlockFlower { for (int k1 = 0; k1 < j1; ++k1) { if (world.random.nextInt(15) <= l) { + /* CraftBukkit start - Identical logic to superclass method; defer to that method float f1 = 0.7F; float f2 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F; float f3 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F; @@ -104,6 +105,8 @@ public class BlockCrops extends BlockFlower { entityitem.pickupDelay = 10; world.addEntity(entityitem); + // */ + this.a(world, i, j, k, new ItemStack(Item.SEEDS)); } } } diff --git a/src/main/java/net/minecraft/server/BlockDeadBush.java b/src/main/java/net/minecraft/server/BlockDeadBush.java index d6e4597a55..9b0c89f8d7 100644 --- a/src/main/java/net/minecraft/server/BlockDeadBush.java +++ b/src/main/java/net/minecraft/server/BlockDeadBush.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.ArrayList; // CraftBukkit import java.util.Random; public class BlockDeadBush extends BlockFlower { @@ -26,9 +27,25 @@ public class BlockDeadBush extends BlockFlower { public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) { if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { entityhuman.a(StatisticList.C[this.id], 1); + /* CraftBukkit start - moved this line into calculateDrops this.a(world, i, j, k, new ItemStack(Block.DEAD_BUSH, 1, l)); + */ + this.doActualDrop(world, entityhuman, i, j, k, l); + // CraftBukkit end } else { super.a(world, entityhuman, i, j, k, l); } } + + // CraftBukkit start - Calculate drops + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { + super.dropList = new ArrayList(); + this.a(world, i, j, k, new ItemStack(Block.DEAD_BUSH, 1, l)); + return super.dropList; + } else { + return super.calculateDrops(world, entityhuman, i, j, k, l); + } + } + // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/BlockDoor.java b/src/main/java/net/minecraft/server/BlockDoor.java index 8ce6fc8d4a..1b81e4664a 100644 --- a/src/main/java/net/minecraft/server/BlockDoor.java +++ b/src/main/java/net/minecraft/server/BlockDoor.java @@ -169,10 +169,11 @@ public class BlockDoor extends Block { } if (flag) { + /* CraftBukkit start - Move the drop to on break instead of on physics if (!world.isStatic) { this.b(world, i, j, k, i1, 0); } - // CraftBukkit start + // */ } else if (l > 0 && Block.byId[l].isPowerSource()) { org.bukkit.World bworld = world.getWorld(); org.bukkit.block.Block block = bworld.getBlockAt(i, j, k); @@ -195,7 +196,7 @@ public class BlockDoor extends Block { } public int getDropType(int i, Random random, int j) { - return (i & 8) != 0 ? 0 : (this.material == Material.ORE ? Item.IRON_DOOR.id : Item.WOOD_DOOR.id); + return /* (i & 8) != 0 ? 0 CraftBukkit : */ (this.material == Material.ORE ? Item.IRON_DOOR.id : Item.WOOD_DOOR.id); } public MovingObjectPosition a(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) { diff --git a/src/main/java/net/minecraft/server/BlockLeaves.java b/src/main/java/net/minecraft/server/BlockLeaves.java index 1f2590b67a..3daf419315 100644 --- a/src/main/java/net/minecraft/server/BlockLeaves.java +++ b/src/main/java/net/minecraft/server/BlockLeaves.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.ArrayList; // CraftBukkit import java.util.Random; import org.bukkit.event.block.LeavesDecayEvent; // CraftBukkit @@ -161,12 +162,28 @@ public class BlockLeaves extends BlockTransparant { public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) { if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { entityhuman.a(StatisticList.C[this.id], 1); + /* CraftBukkit start - moved this line into calculateDrops this.a(world, i, j, k, new ItemStack(Block.LEAVES.id, 1, l & 3)); + */ + this.doActualDrop(world, entityhuman, i, j, k, l); + // CraftBukkit end } else { super.a(world, entityhuman, i, j, k, l); } } + // CraftBukkit start - Calculate drops + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { + super.dropList = new ArrayList(); + this.a(world, i, j, k, new ItemStack(Block.LEAVES.id, 1, l & 3)); + return super.dropList; + } else { + return super.calculateDrops(world, entityhuman, i, j, k, l); + } + } + // CraftBukkit end + protected int getDropData(int i) { return i & 3; } diff --git a/src/main/java/net/minecraft/server/BlockLongGrass.java b/src/main/java/net/minecraft/server/BlockLongGrass.java index 2f192f54da..b5875e16f8 100644 --- a/src/main/java/net/minecraft/server/BlockLongGrass.java +++ b/src/main/java/net/minecraft/server/BlockLongGrass.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.ArrayList; // CraftBukkit import java.util.Random; public class BlockLongGrass extends BlockFlower { @@ -26,9 +27,25 @@ public class BlockLongGrass extends BlockFlower { public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) { if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { entityhuman.a(StatisticList.C[this.id], 1); + /* CraftBukkit start - moved this line into calculateDrops this.a(world, i, j, k, new ItemStack(Block.LONG_GRASS, 1, l)); + */ + this.doActualDrop(world, entityhuman, i, j, k, l); + // CraftBukkit end } else { super.a(world, entityhuman, i, j, k, l); } } + + // CraftBukkit start - Calculate drops + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { + super.dropList = new ArrayList(); + this.a(world, i, j, k, new ItemStack(Block.LONG_GRASS, 1, l)); + return super.dropList; + } else { + return super.calculateDrops(world, entityhuman, i, j, k, l); + } + } + // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/BlockPistonExtension.java b/src/main/java/net/minecraft/server/BlockPistonExtension.java index e6a7b186e0..28adc7f345 100644 --- a/src/main/java/net/minecraft/server/BlockPistonExtension.java +++ b/src/main/java/net/minecraft/server/BlockPistonExtension.java @@ -13,9 +13,28 @@ public class BlockPistonExtension extends Block { this.c(0.5F); } + // CraftBukkit start - Support getDrops() in BlockBreakEvent + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int d) { + super.calculateDrops(world, entityhuman, i, j, k, d); + int l = world.getData(i, j, k) & 0x7; + if (l > 5 || l < 0) return super.dropList; + int i1 = Facing.OPPOSITE_FACING[b(l)]; + + i += Facing.b[i1]; + j += Facing.c[i1]; + k += Facing.d[i1]; + int j1 = world.getTypeId(i, j, k); + + if (j1 == Block.PISTON.id || j1 == Block.PISTON_STICKY.id) { + super.dropList.add(new ItemStack(Block.byId[j1], 1)); + } + return super.dropList; + } + // CraftBukkit end + public void remove(World world, int i, int j, int k) { super.remove(world, i, j, k); - int l = world.getData(i, j, k); + int l = world.getData(i, j, k) & 0x7; if (l > 5 || l < 0) return; // CraftBukkit - fixed a piston AIOOBE issue. int i1 = Facing.OPPOSITE_FACING[b(l)]; @@ -27,7 +46,7 @@ public class BlockPistonExtension extends Block { if (j1 == Block.PISTON.id || j1 == Block.PISTON_STICKY.id) { l = world.getData(i, j, k); if (BlockPiston.e(l)) { - Block.byId[j1].b(world, i, j, k, l, 0); + //Block.byId[j1].b(world, i, j, k, l, 0); // CraftBukkit - drop moved into drop list world.setTypeId(i, j, k, 0); } } diff --git a/src/main/java/net/minecraft/server/BlockSnow.java b/src/main/java/net/minecraft/server/BlockSnow.java index ca871116e7..3c6cfe1597 100644 --- a/src/main/java/net/minecraft/server/BlockSnow.java +++ b/src/main/java/net/minecraft/server/BlockSnow.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.ArrayList; // CraftBukkit import java.util.Random; import org.bukkit.craftbukkit.event.CraftEventFactory; @@ -54,19 +55,32 @@ public class BlockSnow extends Block { } public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + /* CraftBukkit start - This logic is exactly the same as in the superclass method, so defer it there int i1 = Item.SNOW_BALL.id; float f = 0.7F; double d0 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; double d1 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; double d2 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; EntityItem entityitem = new EntityItem(world, (double) i + d0, (double) j + d1, (double) k + d2, new ItemStack(i1, 1, 0)); + // This is done so that getDrops() in the BlockBreakEvent works properly. entityitem.pickupDelay = 10; world.addEntity(entityitem); + // */ + super.doActualDrop(world, entityhuman, i, j, k, l); + // CraftBukkit end world.setTypeId(i, j, k, 0); entityhuman.a(StatisticList.C[this.id], 1); } + // CraftBukkit start - Calculate drops + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + super.dropList = new ArrayList(); + this.a(world, i, j, k, new ItemStack(Item.SNOW_BALL.id, 1, 1)); + return super.dropList; + } + // CraftBukkit end + public int getDropType(int i, Random random, int j) { return Item.SNOW_BALL.id; } diff --git a/src/main/java/net/minecraft/server/BlockStem.java b/src/main/java/net/minecraft/server/BlockStem.java index 4468770313..901b4b4af8 100644 --- a/src/main/java/net/minecraft/server/BlockStem.java +++ b/src/main/java/net/minecraft/server/BlockStem.java @@ -158,6 +158,7 @@ public class BlockStem extends BlockFlower { for (int j1 = 0; j1 < 3; ++j1) { if (world.random.nextInt(15) <= l) { + /* CraftBukkit - Identical logic to superclass method; defer there float f1 = 0.7F; float f2 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F; float f3 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F; @@ -166,6 +167,8 @@ public class BlockStem extends BlockFlower { entityitem.pickupDelay = 10; world.addEntity(entityitem); + // */ + this.a(world, i, j, k, new ItemStack(item)); } } } diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java index f1efb1356e..e8261b5521 100644 --- a/src/main/java/net/minecraft/server/BlockTNT.java +++ b/src/main/java/net/minecraft/server/BlockTNT.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.ArrayList; // CraftBukkit import java.util.Random; public class BlockTNT extends Block { @@ -41,7 +42,9 @@ public class BlockTNT extends Block { public void postBreak(World world, int i, int j, int k, int l) { if (!world.isStatic) { if ((l & 1) == 0) { + /* CraftBukkit - Move this earlier so the block break event can see it this.a(world, i, j, k, new ItemStack(Block.TNT.id, 1, 0)); + // */ } else { EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F)); @@ -51,6 +54,14 @@ public class BlockTNT extends Block { } } + // CraftBukkit start - Calculate drops + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + super.dropList = new ArrayList(); + this.a(world, i, j, k, new ItemStack(Block.TNT.id, 1, 0)); + return super.dropList; + } + // CraftBukkit end + public void attack(World world, int i, int j, int k, EntityHuman entityhuman) { if (entityhuman.T() != null && entityhuman.T().id == Item.FLINT_AND_STEEL.id) { world.setRawData(i, j, k, 1); diff --git a/src/main/java/net/minecraft/server/BlockVine.java b/src/main/java/net/minecraft/server/BlockVine.java index d6bda347c4..633c9585b5 100644 --- a/src/main/java/net/minecraft/server/BlockVine.java +++ b/src/main/java/net/minecraft/server/BlockVine.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.ArrayList; // CraftBukkit import java.util.Random; public class BlockVine extends Block { @@ -286,9 +287,25 @@ public class BlockVine extends Block { public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) { if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { entityhuman.a(StatisticList.C[this.id], 1); + /* CraftBukkit start - moved this line into calculateDrops this.a(world, i, j, k, new ItemStack(Block.VINE, 1, 0)); + */ + this.doActualDrop(world, entityhuman, i, j, k, l); + // CraftBukkit end } else { super.a(world, entityhuman, i, j, k, l); } } + + // CraftBukkit start - Calculate drops + public ArrayList calculateDrops(World world, EntityHuman entityhuman, int i, int j, int k, int l) { + if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) { + super.dropList = new ArrayList(); + this.a(world, i, j, k, new ItemStack(Block.VINE, 1, 0)); + return super.dropList; + } else { + return super.calculateDrops(world, entityhuman, i, j, k, l); + } + } + // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index bc093075a1..f15827a749 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Random; // CraftBukkit start +import java.util.ArrayList; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.block.BlockFace; @@ -17,6 +18,7 @@ import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityDamageByBlockEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -1337,12 +1339,18 @@ public abstract class Entity { final PluginManager pluginManager = Bukkit.getPluginManager(); if (thisBukkitEntity instanceof Painting) { - PaintingBreakByEntityEvent event = new PaintingBreakByEntityEvent((Painting) thisBukkitEntity, stormBukkitEntity); + List drops = new ArrayList(); + PaintingBreakByEntityEvent event = new PaintingBreakByEntityEvent((Painting) thisBukkitEntity, stormBukkitEntity, drops); pluginManager.callEvent(event); if (event.isCancelled()) { return; } + + // Something might've been added to the list of drops, so drop them + for (org.bukkit.inventory.ItemStack stack : drops) { + this.a(CraftItemStack.createNMSItemStack(stack), 0.0f); + } } EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(stormBukkitEntity, thisBukkitEntity, EntityDamageEvent.DamageCause.LIGHTNING, 5); diff --git a/src/main/java/net/minecraft/server/EntityBoat.java b/src/main/java/net/minecraft/server/EntityBoat.java index e447f4c9f2..744610896d 100644 --- a/src/main/java/net/minecraft/server/EntityBoat.java +++ b/src/main/java/net/minecraft/server/EntityBoat.java @@ -1,9 +1,11 @@ package net.minecraft.server; +import java.util.ArrayList; import java.util.List; // CraftBukkit start import org.bukkit.Location; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Vehicle; import org.bukkit.event.vehicle.VehicleCreateEvent; import org.bukkit.event.vehicle.VehicleDamageEvent; @@ -111,7 +113,19 @@ public class EntityBoat extends Entity { this.aV(); if (this.getDamage() > 40) { // CraftBukkit start - VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); + List drops = new ArrayList(); + + int j; + + for (j = 0; j < 3; ++j) { + drops.add(new CraftItemStack(Block.WOOD.id, 1)); + } + + for (j = 0; j < 2; ++j) { + drops.add(new CraftItemStack(Item.STICK.id,1)); + } + + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker, drops); this.world.getServer().getPluginManager().callEvent(destroyEvent); if (destroyEvent.isCancelled()) { @@ -124,6 +138,7 @@ public class EntityBoat extends Entity { this.passenger.mount(this); } + /* CraftBukkit - This logic has been moved up before the event firing int j; for (j = 0; j < 3; ++j) { @@ -133,8 +148,14 @@ public class EntityBoat extends Entity { for (j = 0; j < 2; ++j) { this.a(Item.STICK.id, 1, 0.0F); } + // */ this.die(); + // CraftBukkit start + for (org.bukkit.inventory.ItemStack stack : drops) { + this.a(CraftItemStack.createNMSItemStack(stack), 0.0f); + } + // CraftBukkit end } return true; @@ -302,24 +323,39 @@ public class EntityBoat extends Entity { if (this.positionChanged && d3 > 0.2D) { if (!this.world.isStatic) { // CraftBukkit start + List drops = new ArrayList(); + /* CraftBukkit end + this.die(); + // CraftBukkit - deferred to after the event */ + + int k; + + for (k = 0; k < 3; ++k) { + /* CraftBukkit - add to drop list instead of immediately dropping + this.a(Block.WOOD.id, 1, 0.0F); + // */ + drops.add(new CraftItemStack(Block.WOOD.id, 1)); + } + + for (k = 0; k < 2; ++k) { + /* CraftBukkit - add to drop list instead of immediately dropping + this.a(Item.STICK.id, 1, 0.0F); + // */ + drops.add(new CraftItemStack(Item.STICK.id,1)); + } + // CraftBukkit start + drops.add(new CraftItemStack(Item.MINECART.id,1)); Vehicle vehicle = (Vehicle) this.getBukkitEntity(); - VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null); + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null, drops); this.world.getServer().getPluginManager().callEvent(destroyEvent); if (!destroyEvent.isCancelled()) { - // CraftBukkit end this.die(); - - int k; - - for (k = 0; k < 3; ++k) { - this.a(Block.WOOD.id, 1, 0.0F); + for (org.bukkit.inventory.ItemStack stack : drops) { + this.a(CraftItemStack.createNMSItemStack(stack), 0.0f); } - - for (k = 0; k < 2; ++k) { - this.a(Item.STICK.id, 1, 0.0F); - } - } // CraftBukkit + } + // CraftBukkit end } } else { this.motX *= 0.9900000095367432D; diff --git a/src/main/java/net/minecraft/server/EntityMinecart.java b/src/main/java/net/minecraft/server/EntityMinecart.java index 8e04035170..4945a01a1d 100644 --- a/src/main/java/net/minecraft/server/EntityMinecart.java +++ b/src/main/java/net/minecraft/server/EntityMinecart.java @@ -2,6 +2,7 @@ package net.minecraft.server; // CraftBukkit start import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.bukkit.Location; @@ -17,6 +18,7 @@ import org.bukkit.event.vehicle.VehicleUpdateEvent; import org.bukkit.util.Vector; import org.bukkit.inventory.InventoryHolder; import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit end public class EntityMinecart extends Entity implements IInventory { @@ -146,22 +148,35 @@ public class EntityMinecart extends Entity implements IInventory { this.aV(); this.setDamage(this.getDamage() + i * 10); if (this.getDamage() > 40) { - if (this.passenger != null) { - this.passenger.mount(this); - } - // CraftBukkit start - VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, passenger); + List drops = new ArrayList(); + drops.add(new CraftItemStack(Item.MINECART.id,1)); + if (this.type == 1) { + drops.add(new CraftItemStack(Block.CHEST.id,1)); + } else if (this.type == 2) { + drops.add(new org.bukkit.inventory.ItemStack(Block.FURNACE.id,1)); + } + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, passenger, drops); this.world.getServer().getPluginManager().callEvent(destroyEvent); if (destroyEvent.isCancelled()) { this.setDamage(40); // Maximize damage so this doesn't get triggered again right away return true; } + // CraftBukkit end + if (this.passenger != null) { + this.passenger.mount(this); + } + this.die(); - this.a(Item.MINECART.id, 1, 0.0F); + // CraftBukkit start - Drop items from the event + for(org.bukkit.inventory.ItemStack stack : drops) { + this.a(CraftItemStack.createNMSItemStack(stack), 0.0f); + } + // CraftBukkit end + // this.a(Item.MINECART.id, 1, 0.0F); // CraftBukkit - handled by main drop loop if (this.type == 1) { EntityMinecart entityminecart = this; @@ -193,9 +208,9 @@ public class EntityMinecart extends Entity implements IInventory { } } - this.a(Block.CHEST.id, 1, 0.0F); + // this.a(Block.CHEST.id, 1, 0.0F); // CraftBukkit - handled by main drop loop } else if (this.type == 2) { - this.a(Block.FURNACE.id, 1, 0.0F); + // this.a(Block.FURNACE.id, 1, 0.0F); // CraftBukkit - handled by main drop loop } } diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java index b3860ec9c8..295e081107 100644 --- a/src/main/java/net/minecraft/server/EntityMushroomCow.java +++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java @@ -1,5 +1,12 @@ package net.minecraft.server; +// CraftBukkit start +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.craftbukkit.inventory.CraftItemStack; +// CraftBukkit end + public class EntityMushroomCow extends EntityCow { public EntityMushroomCow(World world) { @@ -16,7 +23,11 @@ public class EntityMushroomCow extends EntityCow { return true; } else if (itemstack != null && itemstack.id == Item.SHEARS.id && this.getAge() >= 0) { // CraftBukkit start - org.bukkit.event.player.PlayerShearEntityEvent event = new org.bukkit.event.player.PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); + List drops = new ArrayList(); + for (int i = 0; i < 5; ++i) { + drops.add(new CraftItemStack(Block.RED_MUSHROOM.id, 1)); + } + org.bukkit.event.player.PlayerShearEntityEvent event = new org.bukkit.event.player.PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity(), drops); this.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -34,9 +45,15 @@ public class EntityMushroomCow extends EntityCow { entitycow.V = this.V; this.world.addEntity(entitycow); + /* CraftBukkit start - This logic moved up to before the event is fired ... for (int i = 0; i < 5; ++i) { this.world.addEntity(new EntityItem(this.world, this.locX, this.locY + (double) this.length, this.locZ, new ItemStack(Block.RED_MUSHROOM))); } + // ... and replaced by this logic */ + for (org.bukkit.inventory.ItemStack stack : drops) { + this.world.addEntity(new EntityItem(this.world, this.locX, this.locY + this.length, this.locZ, CraftItemStack.createNMSItemStack(stack))); + } + // CraftBukkit end } return true; diff --git a/src/main/java/net/minecraft/server/EntityPainting.java b/src/main/java/net/minecraft/server/EntityPainting.java index 45b00fbb6c..510f7d1040 100644 --- a/src/main/java/net/minecraft/server/EntityPainting.java +++ b/src/main/java/net/minecraft/server/EntityPainting.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; // CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Painting; import org.bukkit.event.painting.PaintingBreakByEntityEvent; import org.bukkit.event.painting.PaintingBreakEvent.RemoveCause; @@ -125,6 +126,8 @@ public class EntityPainting extends Entity { this.f = 0; if (!this.survives()) { // CraftBukkit start + List drops = new ArrayList(); + drops.add(new CraftItemStack(Item.PAINTING.id, 1)); Material material = this.world.getMaterial((int) this.locX, (int) this.locY, (int) this.locZ); RemoveCause cause; if (material.equals(Material.WATER)) { @@ -135,7 +138,7 @@ public class EntityPainting extends Entity { } else { cause = RemoveCause.PHYSICS; } - PaintingBreakEvent event = new PaintingBreakEvent((Painting) this.getBukkitEntity(), cause); + PaintingBreakEvent event = new PaintingBreakEvent((Painting) this.getBukkitEntity(), cause, drops); this.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || dead) { @@ -144,7 +147,12 @@ public class EntityPainting extends Entity { // CraftBukkit end this.die(); - this.world.addEntity(new EntityItem(this.world, this.locX, this.locY, this.locZ, new ItemStack(Item.PAINTING))); + // CraftBukkit start - replace following line with the loop + //this.world.addEntity(new EntityItem(this.world, this.locX, this.locY, this.locZ, new ItemStack(Item.PAINTING))); + for (org.bukkit.inventory.ItemStack stack : drops) { + this.world.addEntity(new EntityItem(this.world, this.locX, this.locY, this.locZ, CraftItemStack.createNMSItemStack(stack))); + } + // CraftBukkit end } } } @@ -214,12 +222,14 @@ public class EntityPainting extends Entity { public boolean damageEntity(DamageSource damagesource, int i) { if (!this.dead && !this.world.isStatic) { // CraftBukkit start + List drops = new ArrayList(); + drops.add(new CraftItemStack(Item.PAINTING.id, 1)); PaintingBreakEvent event = null; if (damagesource.getEntity() != null) { - event = new PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity()); + event = new PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), damagesource.getEntity().getBukkitEntity(), drops); } else { if (damagesource == DamageSource.FIRE) { - event = new PaintingBreakEvent((Painting) this.getBukkitEntity(), RemoveCause.FIRE); + event = new PaintingBreakEvent((Painting) this.getBukkitEntity(), RemoveCause.FIRE, drops); } // TODO: Could put other stuff here? } @@ -236,7 +246,12 @@ public class EntityPainting extends Entity { this.die(); this.aV(); - this.world.addEntity(new EntityItem(this.world, this.locX, this.locY, this.locZ, new ItemStack(Item.PAINTING))); + // CraftBukkit start - replace following line with the loop + //this.world.addEntity(new EntityItem(this.world, this.locX, this.locY, this.locZ, new ItemStack(Item.PAINTING))); + for (org.bukkit.inventory.ItemStack stack : drops) { + this.world.addEntity(new EntityItem(this.world, this.locX, this.locY, this.locZ, CraftItemStack.createNMSItemStack(stack))); + } + // CraftBukkit end } return true; diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java index 59f3eb9c10..62e641ba7a 100644 --- a/src/main/java/net/minecraft/server/EntitySheep.java +++ b/src/main/java/net/minecraft/server/EntitySheep.java @@ -3,8 +3,12 @@ package net.minecraft.server; import java.util.Random; // CraftBukkit start +import java.util.ArrayList; +import java.util.List; + import org.bukkit.Material; import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Sheep; // CraftBukkit end @@ -80,7 +84,12 @@ public class EntitySheep extends EntityAnimal { if (itemstack != null && itemstack.id == Item.SHEARS.id && !this.isSheared() && !this.isBaby()) { if (!this.world.isStatic) { // CraftBukkit start - org.bukkit.event.player.PlayerShearEntityEvent event = new org.bukkit.event.player.PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); + int i = 1 + this.random.nextInt(3); + List drops = new ArrayList(); + for (int j = 0; j < i; ++j) { + drops.add(new CraftItemStack(Block.WOOL.id, 1, (short) this.getColor())); + } + org.bukkit.event.player.PlayerShearEntityEvent event = new org.bukkit.event.player.PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity(), drops); this.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -89,11 +98,15 @@ public class EntitySheep extends EntityAnimal { // CraftBukkit end this.setSheared(true); + /* CraftBukkit start - Moved this line to before the event is fired int i = 1 + this.random.nextInt(3); - + // And this logic is changed to use the drop list from the event for (int j = 0; j < i; ++j) { EntityItem entityitem = this.a(new ItemStack(Block.WOOL.id, 1, this.getColor()), 1.0F); - + // */ + for (org.bukkit.inventory.ItemStack stack : drops) { + EntityItem entityitem = this.a(CraftItemStack.createNMSItemStack(stack), 1.0f); + // CraftBukkit end entityitem.motY += (double) (this.random.nextFloat() * 0.05F); entityitem.motX += (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F); entityitem.motZ += (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F); diff --git a/src/main/java/net/minecraft/server/ItemInWorldManager.java b/src/main/java/net/minecraft/server/ItemInWorldManager.java index f0a8c89d6c..d9d512faea 100644 --- a/src/main/java/net/minecraft/server/ItemInWorldManager.java +++ b/src/main/java/net/minecraft/server/ItemInWorldManager.java @@ -1,7 +1,6 @@ package net.minecraft.server; // CraftBukkit start -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.Event; @@ -201,37 +200,24 @@ public class ItemInWorldManager { } public boolean breakBlock(int i, int j, int k) { + int l = this.world.getTypeId(i, j, k); + int i1 = this.world.getData(i, j, k); + // CraftBukkit start - if (this.player instanceof EntityPlayer) { - org.bukkit.block.Block block = this.world.getWorld().getBlockAt(i, j, k); - - // Tell client the block is gone immediately then process events - if (world.getTileEntity(i, j, k) == null) { - Packet53BlockChange packet = new Packet53BlockChange(i, j, k, this.world); - - packet.material = 0; - packet.data = 0; - ((EntityPlayer) this.player).netServerHandler.sendPacket(packet); - } - - BlockBreakEvent event = new BlockBreakEvent(block, (org.bukkit.entity.Player) this.player.getBukkitEntity()); - this.world.getServer().getPluginManager().callEvent(event); - - if (event.isCancelled()) { - // Let the client know the block still exists - ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); + if (player instanceof EntityPlayer) { + if(CraftEventFactory.callBlockBreakEvent(this.world, i, j, k, l, i1, this.isCreative(), this.player)) { return false; } } // CraftBukkit end - int l = this.world.getTypeId(i, j, k); - int i1 = this.world.getData(i, j, k); - this.world.a(this.player, 2001, i, j, k, l + (this.world.getData(i, j, k) << 12)); boolean flag = this.b(i, j, k); if (this.isCreative()) { + // CraftBukkit start - honour additions to drop list + Block.byId[l].doActualDrop(this.world, this.player, i, j, k, i1); + // CraftBukkit end ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); } else { ItemStack itemstack = this.player.T(); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index cebaa8f034..394e52ab76 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1,6 +1,8 @@ package org.bukkit.craftbukkit.event; import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -16,10 +18,12 @@ import net.minecraft.server.EntityItem; import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityPlayer; import net.minecraft.server.EntityPotion; +import net.minecraft.server.IInventory; import net.minecraft.server.InventoryCrafting; import net.minecraft.server.Item; import net.minecraft.server.ItemStack; import net.minecraft.server.Packet101CloseWindow; +import net.minecraft.server.Packet53BlockChange; import net.minecraft.server.World; import net.minecraft.server.WorldServer; @@ -485,6 +489,7 @@ public class CraftEventFactory { public static ItemStack callPreCraftEvent(InventoryCrafting matrix, ItemStack result, InventoryView lastCraftView, boolean isRepair) { CraftInventoryCrafting inventory = new CraftInventoryCrafting(matrix, matrix.resultInventory); inventory.setResult(new CraftItemStack(result)); + PrepareItemCraftEvent event = new PrepareItemCraftEvent(inventory, lastCraftView, isRepair); Bukkit.getPluginManager().callEvent(event); @@ -506,4 +511,42 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(event); return event; } + + public static boolean callBlockBreakEvent(World world, int x, int y, int z, int id, int data, boolean creative, EntityHuman player) { + net.minecraft.server.Block blockType = net.minecraft.server.Block.byId[id]; + Block block = world.getWorld().getBlockAt(x, y, z); + + // Tell client the block is gone immediately then process events + if (world.getTileEntity(x, y, z) == null) { + Packet53BlockChange packet = new Packet53BlockChange(x, y, z, world); + + packet.material = 0; + packet.data = 0; + ((EntityPlayer) player).netServerHandler.sendPacket(packet); + } + + List drops = new ArrayList(); + if (!creative && player.b(blockType)) { + for (ItemStack stack : blockType.calculateDrops(world, player, x, y, z, data)) { + drops.add(new CraftItemStack(stack)); + } + } + + BlockBreakEvent event = new BlockBreakEvent(block, (org.bukkit.entity.Player) player.getBukkitEntity(), drops); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + // Let the client know the block still exists + ((EntityPlayer) player).netServerHandler.sendPacket(new Packet53BlockChange(x, y, z, world)); + return true; + } + + ArrayList toDrop = new ArrayList(); + for (org.bukkit.inventory.ItemStack stack : drops) { + toDrop.add(CraftItemStack.createNMSItemStack(stack)); + } + blockType.setDrops(toDrop); + + return false; // Event not cancelled + } }