diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlockChangeDelegate.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlockChangeDelegate.java deleted file mode 100644 index 5946e7d064..0000000000 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlockChangeDelegate.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.bukkit.craftbukkit; - -import net.minecraft.server.Block; -import net.minecraft.server.World; - -import org.bukkit.BlockChangeDelegate; - -public class CraftBlockChangeDelegate { - private final BlockChangeDelegate delegate; - - public CraftBlockChangeDelegate(BlockChangeDelegate delegate) { - this.delegate = delegate; - } - - public BlockChangeDelegate getDelegate() { - return delegate; - } - - public Block getType(int x, int y, int z) { - return Block.e(this.delegate.getTypeId(x, y, z)); - } - - public void setTypeAndData(int x, int y, int z, Block block, int data, int updateFlag) { - // Layering violation :( - if (delegate instanceof World) { - ((World) delegate).setTypeAndData(x, y, z, block, data, 2); - } else { - delegate.setRawTypeIdAndData(x, y, z, Block.b(block), data); - } - } - - public boolean isEmpty(int x, int y, int z) { - return delegate.isEmpty(x, y, z); - } -} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 4590a713e6..8ef5509e38 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -25,10 +25,13 @@ import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.entity.*; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.metadata.BlockMetadataStore; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.LongHash; import org.bukkit.entity.*; import org.bukkit.entity.Entity; @@ -351,11 +354,7 @@ public class CraftWorld implements World { } public boolean generateTree(Location loc, TreeType type) { - return generateTree(loc, type, world); - } - - public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { - BlockSapling.TreeGenerator gen; + net.minecraft.server.WorldGenerator gen; switch (type) { case BIG_TREE: gen = new WorldGenBigTree(true); @@ -405,7 +404,34 @@ public class CraftWorld implements World { break; } - return gen.generate(new CraftBlockChangeDelegate(delegate), rand, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + return gen.a(world, rand, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + + public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { + world.captureTreeGeneration = true; + world.captureBlockStates = true; + boolean grownTree = generateTree(loc, type); + world.captureBlockStates = false; + world.captureTreeGeneration = false; + if (grownTree) { // Copy block data to delegate + for (BlockState blockstate : world.capturedBlockStates) { + int x = blockstate.getX(); + int y = blockstate.getY(); + int z = blockstate.getZ(); + net.minecraft.server.Block oldBlock = world.getType(x, y, z); + int typeId = blockstate.getTypeId(); + int data = blockstate.getRawData(); + int flag = ((CraftBlockState)blockstate).getFlag(); + delegate.setTypeIdAndData(x, y, z, typeId, data); + net.minecraft.server.Block newBlock = world.getType(x, y, z); + world.notifyAndUpdatePhysics(x, y, z, null, oldBlock, newBlock, flag); + } + world.capturedBlockStates.clear(); + return true; + } else { + world.capturedBlockStates.clear(); + return false; + } } public TileEntity getTileEntityAt(final int x, final int y, final int z) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java index 2072db2801..2297cc756c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -22,6 +22,7 @@ public class CraftBlockState implements BlockState { private final int z; protected int type; protected MaterialData data; + protected int flag; protected final byte light; public CraftBlockState(final Block block) { @@ -32,14 +33,24 @@ public class CraftBlockState implements BlockState { this.type = block.getTypeId(); this.light = block.getLightLevel(); this.chunk = (CraftChunk) block.getChunk(); + this.flag = 3; createData(block.getData()); } + public CraftBlockState(final Block block, int flag) { + this(block); + this.flag = flag; + } + public static CraftBlockState getBlockState(net.minecraft.server.World world, int x, int y, int z) { return new CraftBlockState(world.getWorld().getBlockAt(x, y, z)); } + public static CraftBlockState getBlockState(net.minecraft.server.World world, int x, int y, int z, int flag) { + return new CraftBlockState(world.getWorld().getBlockAt(x, y, z), flag); + } + public World getWorld() { return world; } @@ -96,6 +107,14 @@ public class CraftBlockState implements BlockState { return Material.getMaterial(getTypeId()); } + public void setFlag(int flag) { + this.flag = flag; + } + + public int getFlag() { + return flag; + } + public int getTypeId() { return type; } @@ -224,4 +243,4 @@ public class CraftBlockState implements BlockState { public void removeMetadata(String metadataKey, Plugin owningPlugin) { chunk.getCraftWorld().getBlockMetadata().removeMetadata(getBlock(), metadataKey, owningPlugin); } -} +} \ No newline at end of file diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 30f31d1fc4..522d6b036c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -102,6 +102,27 @@ public class CraftEventFactory { /** * Block place methods */ + public static BlockMultiPlaceEvent callBlockMultiPlaceEvent(World world, EntityHuman who, List blockStates, int clickedX, int clickedY, int clickedZ) { + CraftWorld craftWorld = world.getWorld(); + CraftServer craftServer = world.getServer(); + Player player = (who == null) ? null : (Player) who.getBukkitEntity(); + + Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ); + + boolean canBuild = true; + for (int i = 0; i < blockStates.size(); i++) { + if (!canBuild(craftWorld, player, blockStates.get(i).getX(), blockStates.get(i).getZ())) { + canBuild = false; + break; + } + } + + BlockMultiPlaceEvent event = new BlockMultiPlaceEvent(blockStates, blockClicked, player.getItemInHand(), player, canBuild); + craftServer.getPluginManager().callEvent(event); + + return event; + } + public static BlockPlaceEvent callBlockPlaceEvent(World world, EntityHuman who, BlockState replacedBlockState, int clickedX, int clickedY, int clickedZ) { CraftWorld craftWorld = world.getWorld(); CraftServer craftServer = world.getServer();