diff options
author | bloodshot <jdroque@gmail.com> | 2014-01-06 00:17:16 -0500 |
---|---|---|
committer | Nate Mortensen <nate.richard.mortensen@gmail.com> | 2014-04-23 21:25:55 -0600 |
commit | 576758bc55941e673b1c4bf5727a1e1329ef29cd (patch) | |
tree | b3e114f8d5852efafe2827a9a392d11a7ce519f2 /src/main/java/net/minecraft/server/ItemStack.java | |
parent | de97b62b8945ec7a05c7b6813a6317606f46faaf (diff) | |
download | craftbukkit-576758bc55941e673b1c4bf5727a1e1329ef29cd.tar craftbukkit-576758bc55941e673b1c4bf5727a1e1329ef29cd.tar.gz craftbukkit-576758bc55941e673b1c4bf5727a1e1329ef29cd.tar.lz craftbukkit-576758bc55941e673b1c4bf5727a1e1329ef29cd.tar.xz craftbukkit-576758bc55941e673b1c4bf5727a1e1329ef29cd.zip |
Refactored BlockPlaceEvent and BlockChangeDelegate. Adds BUKKIT-5558
23 classes have been removed as they are no longer needed using the new
capture logic. This should help quite a bit with future MC updates.
BlockPlaceEvent Refactor
Before calling Item.interactWith, a recording flag is turned on for
setTypeAndData to capture a blockstate for each block that attempts to be set.
When a block place event is cancelled, the recorded blockstate, stack
size, and metadata will revert back to the captured state. If the event is
not cancelled, a notification will be sent to clients and block physics
will be updated.
BlockChangeDelegate Refactor
Now that we have the ability to capture blockstates through world, there
is no need to modify world gen classes with BlockChangeDelegate. Instead
we will simply capture blocks during world generation in order to "replay"
all of the captured blockstates to send back to delegates.
StructureGrowDelegate and BlockSapling.TreeGenerator have also been
removed as part of this change. BlockSapling and BlockMushroom will
capture blockstates the same as block placement and revert back any grow
events if needed.
Diffstat (limited to 'src/main/java/net/minecraft/server/ItemStack.java')
-rw-r--r-- | src/main/java/net/minecraft/server/ItemStack.java | 87 |
1 files changed, 85 insertions, 2 deletions
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java index 791467ba..bae352b2 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -6,7 +6,17 @@ import java.util.Random; import net.minecraft.util.com.google.common.collect.HashMultimap; import net.minecraft.util.com.google.common.collect.Multimap; -import org.bukkit.craftbukkit.util.CraftMagicNumbers; // CraftBukkit +// CraftBukkit start +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Player; +import org.bukkit.event.world.StructureGrowEvent; +// CraftBukkit end public final class ItemStack { @@ -75,11 +85,84 @@ public final class ItemStack { } public boolean placeItem(EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) { + // CraftBukkit start - handle all block place event logic here + int data = this.getData(); + int count = this.count; + + if (!(this.getItem() instanceof ItemBucket)) { // if not bucket + world.captureBlockStates = true; + // special case bonemeal + if (this.getItem() instanceof ItemDye && this.getData() == 15) { + Block block = world.getType(i, j, k); + if (block == Blocks.SAPLING || block instanceof BlockMushroom) { + world.captureTreeGeneration = true; + } + } + } boolean flag = this.getItem().interactWith(this, entityhuman, world, i, j, k, l, f, f1, f2); + world.captureBlockStates = false; + if (flag && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { + world.captureTreeGeneration = false; + Location location = new Location(world.getWorld(), i, j, k); + TreeType treeType = BlockSapling.treeType; + BlockSapling.treeType = null; + List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + StructureGrowEvent event = null; + if (treeType != null) { + event = new StructureGrowEvent(location, treeType, false, (Player) entityhuman.getBukkitEntity(), blocks); + org.bukkit.Bukkit.getPluginManager().callEvent(event); + } + if (event == null || !event.isCancelled()) { + for (BlockState blockstate : blocks) { + blockstate.update(true); + } + } + + return flag; + } + world.captureTreeGeneration = false; if (flag) { - entityhuman.a(StatisticList.USE_ITEM_COUNT[Item.b(this.item)], 1); + org.bukkit.event.block.BlockPlaceEvent placeEvent = null; + List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + if (blocks.size() > 1) { + placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, blocks, i, j, k); + } else if (blocks.size() == 1) { + placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blocks.get(0), i, j, k); + } + + if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { + flag = false; // cancel placement + // revert back all captured blocks + for (BlockState blockstate : blocks) { + blockstate.update(true, false); + } + // make sure to restore stack after cancel + this.setData(data); + this.count = count; + } else { + for (BlockState blockstate : blocks) { + int x = blockstate.getX(); + int y = blockstate.getY(); + int z = blockstate.getZ(); + int updateFlag = ((CraftBlockState) blockstate).getFlag(); + org.bukkit.Material mat = blockstate.getType(); + Block oldBlock = CraftMagicNumbers.getBlock(mat); + Block block = world.getType(x, y, z); + + if (block != null && !(block instanceof BlockContainer)) { // Containers get placed automatically + block.onPlace(world, x, y, z); + } + + world.notifyAndUpdatePhysics(x, y, z, null, oldBlock, block, updateFlag); // send null chunk as chunk.k() returns false by this point + } + entityhuman.a(StatisticList.USE_ITEM_COUNT[Item.b(this.item)], 1); + } } + world.capturedBlockStates.clear(); + // CraftBukkit end return flag; } |