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.
This commit is contained in:
bloodshot 2014-01-06 00:17:16 -05:00 committed by Nate Mortensen
parent de97b62b89
commit 576758bc55
39 changed files with 323 additions and 2635 deletions

View file

@ -3,13 +3,9 @@ package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import java.util.ArrayList;
import org.bukkit.Location;
import org.bukkit.TreeType;
import org.bukkit.block.BlockState;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.world.StructureGrowEvent;
// CraftBukkit end
public class BlockMushroom extends BlockPlant implements IBlockFragilePlantElement {
@ -95,37 +91,25 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme
}
}
// CraftBukkit - added bonemeal, player and itemstack
public boolean grow(World world, int i, int j, int k, Random random, boolean bonemeal, org.bukkit.entity.Player player, ItemStack itemstack) {
public boolean grow(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k);
world.setAir(i, j, k);
// CraftBukkit start
boolean grown = false;
StructureGrowEvent event = null;
Location location = new Location(world.getWorld(), i, j, k);
WorldGenHugeMushroom worldgenhugemushroom = null;
if (this == Blocks.BROWN_MUSHROOM) {
event = new StructureGrowEvent(location, TreeType.BROWN_MUSHROOM, bonemeal, player, new ArrayList<BlockState>());
BlockSapling.treeType = TreeType.BROWN_MUSHROOM; // CraftBukkit
worldgenhugemushroom = new WorldGenHugeMushroom(0);
} else if (this == Blocks.RED_MUSHROOM) {
event = new StructureGrowEvent(location, TreeType.RED_MUSHROOM, bonemeal, player, new ArrayList<BlockState>());
BlockSapling.treeType = TreeType.RED_MUSHROOM; // CraftBukkit
worldgenhugemushroom = new WorldGenHugeMushroom(1);
}
if (worldgenhugemushroom != null && event != null) {
grown = worldgenhugemushroom.grow(new org.bukkit.craftbukkit.CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k, event, itemstack, world.getWorld());
if (event.isFromBonemeal() && itemstack != null) {
--itemstack.count;
}
}
if (!grown || event.isCancelled()) {
if (worldgenhugemushroom != null && worldgenhugemushroom.a(world, random, i, j, k)) {
return true;
} else {
world.setTypeAndData(i, j, k, this, l, 3);
return false;
}
return true;
// CraftBukkit end
}
public boolean a(World world, int i, int j, int k, boolean flag) {
@ -137,6 +121,6 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme
}
public void b(World world, Random random, int i, int j, int k) {
this.grow(world, i, j, k, random, false, null, null); // CraftBukkit - Add bonemeal, player, and itemstack
this.grow(world, i, j, k, random);
}
}

View file

@ -3,11 +3,11 @@ package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import java.util.List;
import org.bukkit.Location;
import org.bukkit.TreeType;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate;
import org.bukkit.craftbukkit.util.StructureGrowDelegate;
import org.bukkit.entity.Player;
import org.bukkit.block.BlockState;
import org.bukkit.event.world.StructureGrowEvent;
// CraftBukkit end
@ -15,6 +15,7 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
public static final String[] a = new String[] { "oak", "spruce", "birch", "jungle", "acacia", "roofed_oak"};
private static final IIcon[] b = new IIcon[a.length];
public static TreeType treeType; // CraftBukkit
protected BlockSapling() {
float f = 0.4F;
@ -27,32 +28,50 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
if (!world.isStatic) {
super.a(world, i, j, k, random);
if (world.getLightLevel(i, j + 1, k) >= 9 && random.nextInt(7) == 0) {
this.grow(world, i, j, k, random, false, null, null); // CraftBukkit - added bonemeal, player and itemstack
// CraftBukkit start
world.captureTreeGeneration = true;
// CraftBukkit end
this.grow(world, i, j, k, random);
// CraftBukkit start
world.captureTreeGeneration = false;
if (world.capturedBlockStates.size() > 0)
{
TreeType treeType = BlockSapling.treeType;
BlockSapling.treeType = null;
Location location = new Location(world.getWorld(), i, j, k);
List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone();
world.capturedBlockStates.clear();
StructureGrowEvent event = null;
if (treeType != null) {
event = new StructureGrowEvent(location, treeType, false, null, blocks);
org.bukkit.Bukkit.getPluginManager().callEvent(event);
}
if (event == null || !event.isCancelled()) {
for (BlockState blockstate : blocks) {
blockstate.update(true);
}
}
}
// CraftBukkit end
}
}
}
// CraftBukkit - added bonemeal, player and itemstack
public void grow(World world, int i, int j, int k, Random random, boolean bonemeal, Player player, ItemStack itemstack) {
public void grow(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k);
if ((l & 8) == 0) {
world.setData(i, j, k, l | 8, 4);
} else {
this.d(world, i, j, k, random, bonemeal, player, itemstack); // CraftBukkit
this.d(world, i, j, k, random);
}
}
// CraftBukkit - Added bonemeal, player and itemstack
public void d(World world, int i, int j, int k, Random random, boolean bonemeal, Player player, ItemStack itemstack) {
public void d(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k) & 7;
// CraftBukkit start - Records tree generation and calls StructureGrowEvent
StructureGrowDelegate delegate = new StructureGrowDelegate(world);
TreeType treeType = null;
boolean grownTree = false;
// Turn ternary operator into if statement to set treeType
//Object object = random.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true);
TreeGenerator object; // Changed to TreeGenerator
// CraftBukkit start - Turn ternary operator into if statement to set treeType
// Object object = random.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true);
Object object;
if (random.nextInt(10) == 0) {
treeType = TreeType.BIG_TREE;
object = new WorldGenBigTree(true);
@ -71,11 +90,11 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
break;
case 1:
treeType = TreeType.REDWOOD; // CraftBukkit
label78:
for (i1 = 0; i1 >= -1; --i1) {
for (j1 = 0; j1 >= -1; --j1) {
if (this.a(world, i + i1, j, k + j1, 1) && this.a(world, i + i1 + 1, j, k + j1, 1) && this.a(world, i + i1, j, k + j1 + 1, 1) && this.a(world, i + i1 + 1, j, k + j1 + 1, 1)) {
treeType = TreeType.TALL_REDWOOD; // CraftBukkit
object = new WorldGenMegaTree(false, random.nextBoolean());
flag = true;
break label78;
@ -86,6 +105,7 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
if (!flag) {
j1 = 0;
i1 = 0;
treeType = TreeType.REDWOOD; // CraftBukkit
object = new WorldGenTaiga2(true);
}
break;
@ -150,29 +170,7 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
world.setTypeAndData(i, j, k, block, 0, 4);
}
// CraftBukkit start
grownTree = object.generate(new CraftBlockChangeDelegate(delegate), random, i + i1, j, k + j1);
if (grownTree) {
Location location = new Location(world.getWorld(), i, j, k);
StructureGrowEvent event = new StructureGrowEvent(location, treeType, bonemeal, player, delegate.getBlocks());
org.bukkit.Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
grownTree = false;
} else {
for (org.bukkit.block.BlockState state : event.getBlocks()) {
state.update(true);
}
if (event.isFromBonemeal() && itemstack != null) {
--itemstack.count;
}
}
} else if (bonemeal && itemstack != null) {
// We always consume bonemeal when trying to grow
--itemstack.count;
}
// No need to generate the tree again.
if (!grownTree) {
// CraftBukkit end
if (!((WorldGenerator) object).a(world, random, i + i1, j, k + j1)) {
if (flag) {
world.setTypeAndData(i + i1, j, k + j1, this, l, 4);
world.setTypeAndData(i + i1 + 1, j, k + j1, this, l, 4);
@ -201,15 +199,6 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
}
public void b(World world, Random random, int i, int j, int k) {
this.grow(world, i, j, k, random, false, null, null); // CraftBukkit - added bonemeal, player and itemstack
this.grow(world, i, j, k, random);
}
// CraftBukkit start
public interface TreeGenerator {
public boolean a(World world, Random random, int i, int j, int k);
public boolean generate(org.bukkit.craftbukkit.CraftBlockChangeDelegate world, Random random, int i, int j, int k);
}
// CraftBukkit end
}

View file

@ -480,17 +480,12 @@ public class Chunk {
}
}
// CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer
if (!this.world.isStatic && (!this.world.callingPlaceEvent || (block instanceof BlockContainer))) {
// CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled.
if (!this.world.isStatic && (!this.world.captureBlockStates || block instanceof BlockContainer)) {
block.onPlace(this.world, l1, j, i2);
}
if (block instanceof IContainer) {
// CraftBukkit start - Don't create tile entity if placement failed
if (this.getType(i, j, k) != block) {
return false;
}
// CraftBukkit end
tileentity = this.e(i, j, k);
if (tileentity == null) {

View file

@ -1,61 +0,0 @@
package net.minecraft.server;
public class ItemBed extends Item {
public ItemBed() {
this.a(CreativeModeTab.c);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (world.isStatic) {
return true;
} else if (l != 1) {
return false;
} else {
++j;
BlockBed blockbed = (BlockBed) Blocks.BED;
int i1 = MathHelper.floor((double) (entityhuman.yaw * 4.0F / 360.0F) + 0.5D) & 3;
byte b0 = 0;
byte b1 = 0;
if (i1 == 0) {
b1 = 1;
}
if (i1 == 1) {
b0 = -1;
}
if (i1 == 2) {
b1 = -1;
}
if (i1 == 3) {
b0 = 1;
}
if (entityhuman.a(i, j, k, l, itemstack) && entityhuman.a(i + b0, j, k + b1, l, itemstack)) {
if (world.isEmpty(i, j, k) && world.isEmpty(i + b0, j, k + b1) && World.a((IBlockAccess) world, i, j - 1, k) && World.a((IBlockAccess) world, i + b0, j - 1, k + b1)) {
// CraftBukkit start - fire BlockPlaceEvent
// world.setTypeAndData(i, j, k, blockbed, i1, 3);
if (!ItemBlock.processBlockPlace(world, entityhuman, null, i, j, k, blockbed, i1, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
if (world.getType(i, j, k) == blockbed) {
world.setTypeAndData(i + b0, j, k + b1, blockbed, i1 + 8, 3);
}
--itemstack.count;
return true;
} else {
return false;
}
} else {
return false;
}
}
}
}

View file

@ -1,138 +0,0 @@
package net.minecraft.server;
public class ItemBlock extends Item {
protected final Block block;
public ItemBlock(Block block) {
this.block = block;
}
public ItemBlock b(String s) {
super.c(s);
return this;
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
Block block = world.getType(i, j, k);
if (block == Blocks.SNOW && (world.getData(i, j, k) & 7) < 1) {
l = 1;
} else if (block != Blocks.VINE && block != Blocks.LONG_GRASS && block != Blocks.DEAD_BUSH) {
if (l == 0) {
--j;
}
if (l == 1) {
++j;
}
if (l == 2) {
--k;
}
if (l == 3) {
++k;
}
if (l == 4) {
--i;
}
if (l == 5) {
++i;
}
}
if (itemstack.count == 0) {
return false;
} else if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else if (j == 255 && this.block.getMaterial().isBuildable()) {
return false;
} else if (world.mayPlace(this.block, i, j, k, false, l, entityhuman, itemstack)) {
int i1 = this.filterData(itemstack.getData());
int j1 = this.block.getPlacedData(world, i, j, k, l, f, f1, f2, i1);
// CraftBukkit start - Redirect to common function handler
/*
if (world.setTypeAndData(i, j, k, this.block, j1, 3)) {
if (world.getType(i, j, k) == this.block) {
this.block.postPlace(world, i, j, k, entityhuman, itemstack);
this.block.postPlace(world, i, j, k, j1);
}
world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this.block.stepSound.getPlaceSound(), (this.block.stepSound.getVolume1() + 1.0F) / 2.0F, this.block.stepSound.getVolume2() * 0.8F);
--itemstack.count;
}
return true;
*/
return processBlockPlace(world, entityhuman, itemstack, i, j, k, this.block, j1, clickedX, clickedY, clickedZ);
// CraftBukkit end
} else {
return false;
}
}
// CraftBukkit start - Add method to process block placement
static boolean processBlockPlace(final World world, final EntityHuman entityhuman, final ItemStack itemstack, final int x, final int y, final int z, final Block id, final int data, final int clickedX, final int clickedY, final int clickedZ) {
org.bukkit.block.BlockState blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(world, x, y, z);
world.callingPlaceEvent = true;
// Sign is now 3 not 2.
int flag = (id == Blocks.SIGN_POST || id == Blocks.WALL_SIGN) ? 3 : 2;
world.setTypeAndData(x, y, z, id, data, flag);
org.bukkit.event.block.BlockPlaceEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockstate, clickedX, clickedY, clickedZ);
if (event.isCancelled() || !event.canBuild()) {
blockstate.update(true, false);
world.callingPlaceEvent = false;
return false;
}
world.callingPlaceEvent = false;
Block block = world.getType(x, y, z);
int newData = world.getData(x, y, z);
if (block != null && !(block instanceof BlockContainer)) { // Containers get placed automatically
block.onPlace(world, x, y, z);
}
world.update(x, y, z, block);
// Cocoa beans placed via ItemDye do not need the rest of the processing
if (block == Blocks.COCOA && itemstack != null && itemstack.getItem() instanceof ItemDye) {
return true;
}
// Skulls don't get block data applied to them
if (block != null && block != Blocks.SKULL) {
block.postPlace(world, x, y, z, entityhuman, itemstack);
block.postPlace(world, x, y, z, newData);
world.makeSound((double) ((float) x + 0.5F), (double) ((float) y + 0.5F), (double) ((float) z + 0.5F), block.stepSound.getPlaceSound(), (block.stepSound.getVolume1() + 1.0F) / 2.0F, block.stepSound.getVolume2() * 0.8F);
}
if (itemstack != null) {
--itemstack.count;
}
return true;
}
// CraftBukkit end
public String a(ItemStack itemstack) {
return this.block.a();
}
public String getName() {
return this.block.a();
}
public Item c(String s) {
return this.b(s);
}
}

View file

@ -1,106 +0,0 @@
package net.minecraft.server;
public class ItemDoor extends Item {
private Material a;
public ItemDoor(Material material) {
this.a = material;
this.maxStackSize = 1;
this.a(CreativeModeTab.d);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (l != 1) {
return false;
} else {
++j;
Block block;
if (this.a == Material.WOOD) {
block = Blocks.WOODEN_DOOR;
} else {
block = Blocks.IRON_DOOR_BLOCK;
}
if (entityhuman.a(i, j, k, l, itemstack) && entityhuman.a(i, j + 1, k, l, itemstack)) {
if (!block.canPlace(world, i, j, k)) {
return false;
} else {
int i1 = MathHelper.floor((double) ((entityhuman.yaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
// CraftBukkit start - fire BlockPlaceEvent
if (!place(world, i, j, k, i1, block, entityhuman, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
--itemstack.count;
return true;
}
} else {
return false;
}
}
}
public static void place(World world, int i, int j, int k, int l, Block block) {
// CraftBukkit start
place(world, i, j, k, l, block, null, i, j, k);
}
public static boolean place(World world, int i, int j, int k, int l, Block block, EntityHuman entityhuman, int clickedX, int clickedY, int clickedZ) {
// CraftBukkit end
byte b0 = 0;
byte b1 = 0;
if (l == 0) {
b1 = 1;
}
if (l == 1) {
b0 = -1;
}
if (l == 2) {
b1 = -1;
}
if (l == 3) {
b0 = 1;
}
int i1 = (world.getType(i - b0, j, k - b1).r() ? 1 : 0) + (world.getType(i - b0, j + 1, k - b1).r() ? 1 : 0);
int j1 = (world.getType(i + b0, j, k + b1).r() ? 1 : 0) + (world.getType(i + b0, j + 1, k + b1).r() ? 1 : 0);
boolean flag = world.getType(i - b0, j, k - b1) == block || world.getType(i - b0, j + 1, k - b1) == block;
boolean flag1 = world.getType(i + b0, j, k + b1) == block || world.getType(i + b0, j + 1, k + b1) == block;
boolean flag2 = false;
if (flag && !flag1) {
flag2 = true;
} else if (j1 > i1) {
flag2 = true;
}
// CraftBukkit start - fire BlockPlaceEvent
if (entityhuman != null) {
if (!ItemBlock.processBlockPlace(world, entityhuman, null, i, j, k, block, l, clickedX, clickedY, clickedZ)) {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(i, j + 1, k, world));
return false;
}
if (world.getType(i, j, k) != block) {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(i, j + 1, k, world));
return true;
}
} else {
world.setTypeAndData(i, j, k, block, l, 2);
}
// CraftBukkit end
world.setTypeAndData(i, j + 1, k, block, 8 | (flag2 ? 1 : 0), 2);
world.applyPhysics(i, j, k, block);
world.applyPhysics(i, j + 1, k, block);
return true; // CraftBukkit
}
}

View file

@ -1,9 +1,6 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.entity.Player;
import org.bukkit.event.entity.SheepDyeWoolEvent;
// CraftBukkit end
import org.bukkit.event.entity.SheepDyeWoolEvent; // CraftBukkit
public class ItemDye extends Item {
@ -24,12 +21,11 @@ public class ItemDye extends Item {
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else {
if (itemstack.getData() == 15) {
if (a(itemstack, world, i, j, k, entityhuman)) { // CraftBukkit - pass entity for StructureGrowEvent
if (a(itemstack, world, i, j, k)) {
if (!world.isStatic) {
world.triggerEffect(2005, i, j, k, 0);
}
@ -68,12 +64,7 @@ public class ItemDye extends Item {
if (world.isEmpty(i, j, k)) {
int j1 = Blocks.COCOA.getPlacedData(world, i, j, k, l, f, f1, f2, 0);
// CraftBukkit start - fire BlockPlaceEvent
// world.setTypeAndData(i, j, k, Blocks.COCOA, j1, 2);
if (!ItemBlock.processBlockPlace(world, entityhuman, itemstack, i, j, k, Blocks.COCOA, j1, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
world.setTypeAndData(i, j, k, Blocks.COCOA, j1, 2);
if (!entityhuman.abilities.canInstantlyBuild) {
--itemstack.count;
}
@ -88,12 +79,6 @@ public class ItemDye extends Item {
}
public static boolean a(ItemStack itemstack, World world, int i, int j, int k) {
// CraftBukkit start - add EntityHuman parameter
return a(itemstack, world, i, j, k, null);
}
public static boolean a(ItemStack itemstack, World world, int i, int j, int k, EntityHuman entityhuman) {
// CraftBukkit end
Block block = world.getType(i, j, k);
if (block instanceof IBlockFragilePlantElement) {
@ -102,18 +87,7 @@ public class ItemDye extends Item {
if (iblockfragileplantelement.a(world, i, j, k, world.isStatic)) {
if (!world.isStatic) {
if (iblockfragileplantelement.a(world, world.random, i, j, k)) {
// CraftBukkit start - Special case BlockSapling and BlockMushroom to use our methods
if (block instanceof BlockSapling) {
Player player = (entityhuman instanceof EntityPlayer) ? (Player) entityhuman.getBukkitEntity() : null;
((BlockSapling) block).grow(world, i, j, k, world.random, true, player, null);
} else if (block instanceof BlockMushroom) {
Player player = (entityhuman instanceof EntityPlayer) ? (Player) entityhuman.getBukkitEntity() : null;
((BlockMushroom) block).grow(world, i, j, k, world.random, true, player, null);
} else {
iblockfragileplantelement.b(world, world.random, i, j, k);
}
// CraftBukkit end
iblockfragileplantelement.b(world, world.random, i, j, k);
}
--itemstack.count;

View file

@ -12,7 +12,6 @@ public class ItemFireball extends Item {
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (world.isStatic) {
return true;
} else {
@ -51,21 +50,10 @@ public class ItemFireball extends Item {
}
return false;
}
CraftBlockState blockState = CraftBlockState.getBlockState(world, i, j, k);
// CraftBukkit end
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "fire.ignite", 1.0F, g.nextFloat() * 0.4F + 0.8F);
world.setTypeUpdate(i, j, k, Blocks.FIRE);
// CraftBukkit start
org.bukkit.event.block.BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockState, clickedX, clickedY, clickedZ);
if (placeEvent.isCancelled() || !placeEvent.canBuild()) {
placeEvent.getBlockPlaced().setTypeIdAndData(0, (byte) 0, false);
return false;
}
// CraftBukkit end
}
if (!entityhuman.abilities.canInstantlyBuild) {

View file

@ -1,46 +0,0 @@
package net.minecraft.server;
public class ItemHoe extends Item {
protected EnumToolMaterial a;
public ItemHoe(EnumToolMaterial enumtoolmaterial) {
this.a = enumtoolmaterial;
this.maxStackSize = 1;
this.setMaxDurability(enumtoolmaterial.a());
this.a(CreativeModeTab.i);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else {
Block block = world.getType(i, j, k);
if (l != 0 && world.getType(i, j + 1, k).getMaterial() == Material.AIR && (block == Blocks.GRASS || block == Blocks.DIRT)) {
Block block1 = Blocks.SOIL;
world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), block1.stepSound.getStepSound(), (block1.stepSound.getVolume1() + 1.0F) / 2.0F, block1.stepSound.getVolume2() * 0.8F);
if (world.isStatic) {
return true;
} else {
// CraftBukkit start - Hoes - blockface -1 for 'SELF'
// world.setTypeUpdate(i, j, k, block1);
if (!ItemBlock.processBlockPlace(world, entityhuman, null, i, j, k, block1, 0, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
itemstack.damage(1, entityhuman);
return true;
}
} else {
return false;
}
}
}
public String i() {
return this.a.toString();
}
}

View file

@ -1,57 +0,0 @@
package net.minecraft.server;
public class ItemRedstone extends Item {
public ItemRedstone() {
this.a(CreativeModeTab.d);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (world.getType(i, j, k) != Blocks.SNOW) {
if (l == 0) {
--j;
}
if (l == 1) {
++j;
}
if (l == 2) {
--k;
}
if (l == 3) {
++k;
}
if (l == 4) {
--i;
}
if (l == 5) {
++i;
}
if (!world.isEmpty(i, j, k)) {
return false;
}
}
if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else {
if (Blocks.REDSTONE_WIRE.canPlace(world, i, j, k)) {
// CraftBukkit start - fire BlockPlaceEvent
// --itemstack.count;
// world.setTypeUpdate(i, j, k, Blocks.REDSTONE_WIRE);
if (!ItemBlock.processBlockPlace(world, entityhuman, itemstack, i, j, k, Blocks.REDSTONE_WIRE, 0, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
}
return true;
}
}
}

View file

@ -1,68 +0,0 @@
package net.minecraft.server;
public class ItemReed extends Item {
private Block block;
public ItemReed(Block block) {
this.block = block;
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
Block block = world.getType(i, j, k);
if (block == Blocks.SNOW && (world.getData(i, j, k) & 7) < 1) {
l = 1;
} else if (block != Blocks.VINE && block != Blocks.LONG_GRASS && block != Blocks.DEAD_BUSH) {
if (l == 0) {
--j;
}
if (l == 1) {
++j;
}
if (l == 2) {
--k;
}
if (l == 3) {
++k;
}
if (l == 4) {
--i;
}
if (l == 5) {
++i;
}
}
if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else if (itemstack.count == 0) {
return false;
} else {
if (world.mayPlace(this.block, i, j, k, false, l, (Entity) null, itemstack)) {
int i1 = this.block.getPlacedData(world, i, j, k, l, f, f1, f2, 0);
// CraftBukkit start - Redirect to common handler
ItemBlock.processBlockPlace(world, entityhuman, itemstack, i, j, k, this.block, i1, clickedX, clickedY, clickedZ);
/*
if (world.setTypeAndData(i, j, k, this.block, i1, 3)) {
if (world.getType(i, j, k) == this.block) {
this.block.postPlace(world, i, j, k, entityhuman, itemstack);
this.block.postPlace(world, i, j, k, i1);
}
world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this.block.stepSound.getPlaceSound(), (this.block.stepSound.getVolume1() + 1.0F) / 2.0F, this.block.stepSound.getVolume2() * 0.8F);
--itemstack.count;
}
// CraftBukkit end */
}
return true;
}
}
}

View file

@ -1,35 +0,0 @@
package net.minecraft.server;
public class ItemSeedFood extends ItemFood {
private Block b;
private Block c;
public ItemSeedFood(int i, float f, Block block, Block block1) {
super(i, f, false);
this.b = block;
this.c = block1;
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (l != 1) {
return false;
} else if (entityhuman.a(i, j, k, l, itemstack) && entityhuman.a(i, j + 1, k, l, itemstack)) {
if (world.getType(i, j, k) == this.c && world.isEmpty(i, j + 1, k)) {
// CraftBukkit start - fire BlockPlaceEvent
// world.setTypeUpdate(i, j + 1, k, this.b);
if (!ItemBlock.processBlockPlace(world, entityhuman, null, i, j + 1, k, this.b, 0, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
--itemstack.count;
return true;
} else {
return false;
}
} else {
return false;
}
}
}

View file

@ -1,35 +0,0 @@
package net.minecraft.server;
public class ItemSeeds extends Item {
private Block block;
private Block b;
public ItemSeeds(Block block, Block block1) {
this.block = block;
this.b = block1;
this.a(CreativeModeTab.l);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (l != 1) {
return false;
} else if (entityhuman.a(i, j, k, l, itemstack) && entityhuman.a(i, j + 1, k, l, itemstack)) {
if (world.getType(i, j, k) == this.b && world.isEmpty(i, j + 1, k)) {
// CraftBukkit start - Seeds
// world.setTypeUpdate(i, j + 1, k, this.block);
if (!ItemBlock.processBlockPlace(world, entityhuman, null, i, j + 1, k, this.block, 0, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
--itemstack.count;
return true;
} else {
return false;
}
} else {
return false;
}
}
}

View file

@ -1,72 +0,0 @@
package net.minecraft.server;
public class ItemSign extends Item {
public ItemSign() {
this.maxStackSize = 16;
this.a(CreativeModeTab.c);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (l == 0) {
return false;
} else if (!world.getType(i, j, k).getMaterial().isBuildable()) {
return false;
} else {
if (l == 1) {
++j;
}
if (l == 2) {
--k;
}
if (l == 3) {
++k;
}
if (l == 4) {
--i;
}
if (l == 5) {
++i;
}
if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else if (!Blocks.SIGN_POST.canPlace(world, i, j, k)) {
return false;
} else if (world.isStatic) {
return true;
} else {
// CraftBukkit start - fire BlockPlaceEvent
final Block block;
if (l == 1) {
int i1 = MathHelper.floor((double) ((entityhuman.yaw + 180.0F) * 16.0F / 360.0F) + 0.5D) & 15;
// world.setTypeAndData(i, j, k, Blocks.SIGN_POST, i1, 3);
block = Blocks.SIGN_POST;
l = i1;
} else {
// world.setTypeAndData(i, j, k, Blocks.WALL_SIGN, l, 3);
block = Blocks.WALL_SIGN;
}
if (!ItemBlock.processBlockPlace(world, entityhuman, null, i, j, k, block, l, clickedX, clickedY, clickedZ)) {
return false;
}
// CraftBukkit end
--itemstack.count;
TileEntitySign tileentitysign = (TileEntitySign) world.getTileEntity(i, j, k);
if (tileentitysign != null) {
entityhuman.a((TileEntity) tileentitysign);
}
return true;
}
}
}
}

View file

@ -1,118 +0,0 @@
package net.minecraft.server;
import java.util.UUID;
import net.minecraft.util.com.mojang.authlib.GameProfile;
public class ItemSkull extends Item {
private static final String[] b = new String[] { "skeleton", "wither", "zombie", "char", "creeper"};
public static final String[] a = new String[] { "skeleton", "wither", "zombie", "steve", "creeper"};
public ItemSkull() {
this.a(CreativeModeTab.c);
this.setMaxDurability(0);
this.a(true);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (l == 0) {
return false;
} else if (!world.getType(i, j, k).getMaterial().isBuildable()) {
return false;
} else {
if (l == 1) {
++j;
}
if (l == 2) {
--k;
}
if (l == 3) {
++k;
}
if (l == 4) {
--i;
}
if (l == 5) {
++i;
}
if (!world.isStatic) {
// CraftBukkit start - Handle in ItemBlock
// world.setTypeAndData(i, j, k, Blocks.SKULL, l, 2);
if (!ItemBlock.processBlockPlace(world, entityhuman, null, i, j, k, Blocks.SKULL, l, clickedX, clickedY, clickedZ)) {
return false;
}
l = world.getData(i, j, k);
// CraftBukkit end
int i1 = 0;
if (l == 1) {
i1 = MathHelper.floor((double) (entityhuman.yaw * 16.0F / 360.0F) + 0.5D) & 15;
}
TileEntity tileentity = world.getTileEntity(i, j, k);
if (tileentity != null && tileentity instanceof TileEntitySkull) {
if (itemstack.getData() == 3) {
GameProfile gameprofile = null;
if (itemstack.hasTag()) {
NBTTagCompound nbttagcompound = itemstack.getTag();
if (nbttagcompound.hasKeyOfType("SkullOwner", 10)) {
gameprofile = GameProfileSerializer.a(nbttagcompound.getCompound("SkullOwner"));
} else if (nbttagcompound.hasKeyOfType("SkullOwner", 8) && nbttagcompound.getString("SkullOwner").length() > 0) {
gameprofile = new GameProfile((UUID) null, nbttagcompound.getString("SkullOwner"));
}
}
((TileEntitySkull) tileentity).setGameProfile(gameprofile);
} else {
((TileEntitySkull) tileentity).setSkullType(itemstack.getData());
}
((TileEntitySkull) tileentity).setRotation(i1);
((BlockSkull) Blocks.SKULL).a(world, i, j, k, (TileEntitySkull) tileentity);
}
--itemstack.count;
}
return true;
}
}
public int filterData(int i) {
return i;
}
public String a(ItemStack itemstack) {
int i = itemstack.getData();
if (i < 0 || i >= b.length) {
i = 0;
}
return super.getName() + "." + b[i];
}
public String n(ItemStack itemstack) {
if (itemstack.getData() == 3 && itemstack.hasTag()) {
if (itemstack.getTag().hasKeyOfType("SkullOwner", 10)) {
return LocaleI18n.get("item.skull.player.name", new Object[] { GameProfileSerializer.a(itemstack.getTag().getCompound("SkullOwner")).getName()});
}
if (itemstack.getTag().hasKeyOfType("SkullOwner", 8)) {
return LocaleI18n.get("item.skull.player.name", new Object[] { itemstack.getTag().getString("SkullOwner")});
}
}
return super.n(itemstack);
}
}

View file

@ -1,38 +0,0 @@
package net.minecraft.server;
public class ItemSnow extends ItemBlockWithAuxData {
public ItemSnow(Block block, Block block1) {
super(block, block1);
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (itemstack.count == 0) {
return false;
} else if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else {
Block block = world.getType(i, j, k);
if (block == Blocks.SNOW) {
int i1 = world.getData(i, j, k);
int j1 = i1 & 7;
// CraftBukkit start - Redirect to common handler
if (j1 <= 6 && world.b(this.block.a(world, i, j, k)) && ItemBlock.processBlockPlace(world, entityhuman, itemstack, i, j, k, block, j1 + 1 | i1 & -8, clickedX, clickedY, clickedZ)) {
return true;
}
/*
if (j1 <= 6 && world.b(this.block.a(world, i, j, k)) && world.setData(i, j, k, j1 + 1 | i1 & -8, 2)) {
world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this.block.stepSound.getPlaceSound(), (this.block.stepSound.getVolume1() + 1.0F) / 2.0F, this.block.stepSound.getVolume2() * 0.8F);
--itemstack.count;
return true;
}
// CraftBukkit end */
}
return super.interactWith(itemstack, entityhuman, world, i, j, k, l, f, f1, f2);
}
}
}

View file

@ -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;
}

View file

@ -1,100 +0,0 @@
package net.minecraft.server;
public class ItemStep extends ItemBlock {
private final boolean b;
private final BlockStepAbstract c;
private final BlockStepAbstract d;
public ItemStep(Block block, BlockStepAbstract blockstepabstract, BlockStepAbstract blockstepabstract1, boolean flag) {
super(block);
this.c = blockstepabstract;
this.d = blockstepabstract1;
this.b = flag;
this.setMaxDurability(0);
this.a(true);
}
public int filterData(int i) {
return i;
}
public String a(ItemStack itemstack) {
return this.c.b(itemstack.getData());
}
public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (this.b) {
return super.interactWith(itemstack, entityhuman, world, i, j, k, l, f, f1, f2);
} else if (itemstack.count == 0) {
return false;
} else if (!entityhuman.a(i, j, k, l, itemstack)) {
return false;
} else {
Block block = world.getType(i, j, k);
int i1 = world.getData(i, j, k);
int j1 = i1 & 7;
boolean flag = (i1 & 8) != 0;
if ((l == 1 && !flag || l == 0 && flag) && block == this.c && j1 == itemstack.getData()) {
// CraftBukkit start - world.setTypeIdAndData -> processBlockPlace()
// if (world.b(this.d.a(world, i, j, k)) && world.setTypeAndData(i, j, k, this.d, j1, 3)) {
if (world.b(this.d.a(world, i, j, k)) && processBlockPlace(world, entityhuman, null, i, j, k, this.d, j1, clickedX, clickedY, clickedZ)) {
// world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this.d.stepSound.getPlaceSound(), (this.d.stepSound.getVolume1() + 1.0F) / 2.0F, this.d.stepSound.getVolume2() * 0.8F);
// CraftBukkit end
--itemstack.count;
}
return true;
} else {
return this.a(itemstack, entityhuman, world, i, j, k, l) ? true : super.interactWith(itemstack, entityhuman, world, i, j, k, l, f, f1, f2);
}
}
}
private boolean a(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l) {
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (l == 0) {
--j;
}
if (l == 1) {
++j;
}
if (l == 2) {
--k;
}
if (l == 3) {
++k;
}
if (l == 4) {
--i;
}
if (l == 5) {
++i;
}
Block block = world.getType(i, j, k);
int i1 = world.getData(i, j, k);
int j1 = i1 & 7;
if (block == this.c && j1 == itemstack.getData()) {
// CraftBukkit start - world.setTypeIdAndData -> processBlockPlace()
// if (world.b(this.d.a(world, i, j, k)) && world.setTypeAndData(i, j, k, this.d, j1, 3)) {
if (world.b(this.d.a(world, i, j, k)) && processBlockPlace(world, entityhuman, null, i, j, k, this.d, j1, clickedX, clickedY, clickedZ)) {
// world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this.d.stepSound.getPlaceSound(), (this.d.stepSound.getVolume1() + 1.0F) / 2.0F, this.d.stepSound.getVolume2() * 0.8F);
// CraftBukkit end
--itemstack.count;
}
return true;
} else {
return false;
}
}
}

View file

@ -16,7 +16,6 @@ public class ItemWaterLily extends ItemWithAuxData {
int i = movingobjectposition.b;
int j = movingobjectposition.c;
int k = movingobjectposition.d;
final int clickedX = i, clickedY = j, clickedZ = k; // CraftBukkit
if (!world.a(entityhuman, i, j, k)) {
return itemstack;
@ -27,12 +26,7 @@ public class ItemWaterLily extends ItemWithAuxData {
}
if (world.getType(i, j, k).getMaterial() == Material.WATER && world.getData(i, j, k) == 0 && world.isEmpty(i, j + 1, k)) {
// CraftBukkit start - fire BlockPlaceEvent
// world.setTypeUpdate(i, j + 1, k, Blocks.WATER_LILY);
if (!processBlockPlace(world, entityhuman, null, i, j + 1, k, Blocks.WATER_LILY, 0, clickedX, clickedY, clickedZ)) {
return itemstack;
}
// CraftBukkit end
world.setTypeUpdate(i, j + 1, k, Blocks.WATER_LILY);
if (!entityhuman.abilities.canInstantlyBuild) {
--itemstack.count;

View file

@ -13,6 +13,7 @@ import java.util.concurrent.Callable;
// CraftBukkit start
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.LongHashSet;
import org.bukkit.generator.ChunkGenerator;
@ -66,7 +67,9 @@ public abstract class World implements IBlockAccess {
public boolean allowMonsters;
public boolean allowAnimals;
// Added the following
public boolean callingPlaceEvent = false;
public boolean captureBlockStates = false;
public boolean captureTreeGeneration = false;
public ArrayList<BlockState> capturedBlockStates= new ArrayList<BlockState>();
public long ticksPerAnimalSpawns;
public long ticksPerMonsterSpawns;
public boolean populating;
@ -196,6 +199,17 @@ public abstract class World implements IBlockAccess {
}
public Block getType(int i, int j, int k) {
// CraftBukkit start - tree generation
if (captureTreeGeneration) {
Iterator<BlockState> it = capturedBlockStates.iterator();
while (it.hasNext()) {
BlockState previous = it.next();
if (previous.getX() == i && previous.getY() == j && previous.getZ() == k) {
return CraftMagicNumbers.getBlock(previous.getTypeId());
}
}
}
// CraftBukkit end
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000 && j >= 0 && j < 256) {
Chunk chunk = null;
@ -262,6 +276,26 @@ public abstract class World implements IBlockAccess {
}
public boolean setTypeAndData(int i, int j, int k, Block block, int l, int i1) {
// CraftBukkit start - tree generation
if (this.captureTreeGeneration) {
BlockState blockstate = null;
Iterator<BlockState> it = capturedBlockStates.iterator();
while (it.hasNext()) {
BlockState previous = it.next();
if (previous.getX() == i && previous.getY() == j && previous.getZ() == k) {
blockstate = previous;
it.remove();
break;
}
}
if (blockstate == null) {
blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, i, j, k, i1);
}
blockstate.setTypeId(CraftMagicNumbers.getId(block));
blockstate.setRawData((byte) l);
this.capturedBlockStates.add(blockstate);
return true;
}
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
if (j < 0) {
return false;
@ -275,22 +309,30 @@ public abstract class World implements IBlockAccess {
block1 = chunk.getType(i & 15, j, k & 15);
}
// CraftBukkit start - capture blockstates
BlockState blockstate = null;
if (this.captureBlockStates) {
blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, i, j, k, i1);
this.capturedBlockStates.add(blockstate);
}
// CraftBukkit end
boolean flag = chunk.a(i & 15, j, k & 15, block, l);
// CraftBukkit start - remove blockstate if failed
if (!flag && this.captureBlockStates) {
this.capturedBlockStates.remove(blockstate);
}
// CraftBukkit end
this.methodProfiler.a("checkLight");
this.t(i, j, k);
this.methodProfiler.b();
if (flag) {
if ((i1 & 2) != 0 && (!this.isStatic || (i1 & 4) == 0) && chunk.k()) {
this.notify(i, j, k);
}
if (!this.isStatic && (i1 & 1) != 0) {
this.update(i, j, k, block1);
if (block.M()) {
this.f(i, j, k, block);
}
}
// CraftBukkit start
if (flag && !this.captureBlockStates) { // Don't notify clients or update physics while capturing blockstates
// Modularize client and physic updates
this.notifyAndUpdatePhysics(i, j, k, chunk, block1, block, i1);
// CraftBukkit end
}
return flag;
@ -300,7 +342,35 @@ public abstract class World implements IBlockAccess {
}
}
// CraftBukkit start - Split off from original setTypeAndData(int i, int j, int k, Block block, int l, int i1) method in order to directly send client and physic updates
public void notifyAndUpdatePhysics(int i, int j, int k, Chunk chunk, Block oldBlock, Block newBlock, int flag)
{
// should be isReady()
if ((flag & 2) != 0 && (chunk == null || chunk.k())) { // allow chunk to be null here as chunk.k() is false when we send our notification during block placement
this.notify(i, j, k);
}
if ((flag & 1) != 0) {
this.update(i, j, k, oldBlock);
if (newBlock.M()) { // should be isComplexRedstone()
this.f(i, j, k, newBlock); // should be updateAdjacentComparators
}
}
}
// CraftBukkit end
public int getData(int i, int j, int k) {
// CraftBukkit start - tree generation
if (captureTreeGeneration) {
Iterator<BlockState> it = capturedBlockStates.iterator();
while (it.hasNext()) {
BlockState previous = it.next();
if (previous.getX() == i && previous.getY() == j && previous.getZ() == k) {
return previous.getRawData();
}
}
}
// CraftBukkit end
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
if (j < 0) {
return 0;
@ -319,6 +389,26 @@ public abstract class World implements IBlockAccess {
}
public boolean setData(int i, int j, int k, int l, int i1) {
// CraftBukkit start - tree generation
if (this.captureTreeGeneration) {
BlockState blockstate = null;
Iterator<BlockState> it = capturedBlockStates.iterator();
while (it.hasNext()) {
BlockState previous = it.next();
if (previous.getX() == i && previous.getY() == j && previous.getZ() == k) {
blockstate = previous;
it.remove();
break;
}
}
if (blockstate == null) {
blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, i, j, k, i1);
}
blockstate.setRawData((byte) l);
this.capturedBlockStates.add(blockstate);
return true;
}
// CraftBukkit end
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
if (j < 0) {
return false;

View file

@ -1,169 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenAcaciaTree extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
public WorldGenAcaciaTree(boolean flag) {
super(flag);
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = random.nextInt(3) + random.nextInt(3) + 5;
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
int i1;
int j1;
for (int k1 = j; k1 <= j + 1 + l; ++k1) {
byte b0 = 1;
if (k1 == j) {
b0 = 0;
}
if (k1 >= j + 1 + l - 2) {
b0 = 2;
}
for (i1 = i - b0; i1 <= i + b0 && flag; ++i1) {
for (j1 = k - b0; j1 <= k + b0 && flag; ++j1) {
if (k1 >= 0 && k1 < 256) {
Block block = world.getType(i1, k1, j1);
if (!this.a(block)) {
flag = false;
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT) && j < 256 - l - 1) {
this.setType(world, i, j - 1, k, Blocks.DIRT);
int l1 = random.nextInt(4);
i1 = l - random.nextInt(4) - 1;
j1 = 3 - random.nextInt(3);
int i2 = i;
int j2 = k;
int k2 = 0;
int l2;
int i3;
for (l2 = 0; l2 < l; ++l2) {
i3 = j + l2;
if (l2 >= i1 && j1 > 0) {
i2 += Direction.a[l1];
j2 += Direction.b[l1];
--j1;
}
Block block2 = world.getType(i2, i3, j2);
if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i2, i3, j2, Blocks.LOG2, 0);
k2 = i3;
}
}
for (l2 = -1; l2 <= 1; ++l2) {
for (i3 = -1; i3 <= 1; ++i3) {
this.a(world, i2 + l2, k2 + 1, j2 + i3);
}
}
this.a(world, i2 + 2, k2 + 1, j2);
this.a(world, i2 - 2, k2 + 1, j2);
this.a(world, i2, k2 + 1, j2 + 2);
this.a(world, i2, k2 + 1, j2 - 2);
for (l2 = -3; l2 <= 3; ++l2) {
for (i3 = -3; i3 <= 3; ++i3) {
if (Math.abs(l2) != 3 || Math.abs(i3) != 3) {
this.a(world, i2 + l2, k2, j2 + i3);
}
}
}
i2 = i;
j2 = k;
l2 = random.nextInt(4);
if (l2 != l1) {
i3 = i1 - random.nextInt(2) - 1;
int j3 = 1 + random.nextInt(3);
k2 = 0;
int k3;
int l3;
for (l3 = i3; l3 < l && j3 > 0; --j3) {
if (l3 >= 1) {
k3 = j + l3;
i2 += Direction.a[l2];
j2 += Direction.b[l2];
Block block3 = world.getType(i2, k3, j2);
if (block3.getMaterial() == Material.AIR || block3.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i2, k3, j2, Blocks.LOG2, 0);
k2 = k3;
}
}
++l3;
}
if (k2 > 0) {
for (l3 = -1; l3 <= 1; ++l3) {
for (k3 = -1; k3 <= 1; ++k3) {
this.a(world, i2 + l3, k2 + 1, j2 + k3);
}
}
for (l3 = -2; l3 <= 2; ++l3) {
for (k3 = -2; k3 <= 2; ++k3) {
if (Math.abs(l3) != 2 || Math.abs(k3) != 2) {
this.a(world, i2 + l3, k2, j2 + k3);
}
}
}
}
}
return true;
} else {
return false;
}
}
} else {
return false;
}
}
// CraftBukkit - Changed signature
private void a(CraftBlockChangeDelegate world, int i, int j, int k) {
Block block = world.getType(i, j, k);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j, k, Blocks.LEAVES2, 0);
}
}
}

View file

@ -2,13 +2,11 @@ package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenBigTree extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
public class WorldGenBigTree extends WorldGenTreeAbstract {
static final byte[] a = new byte[] { (byte) 2, (byte) 0, (byte) 0, (byte) 1, (byte) 2, (byte) 1};
Random b = new Random();
CraftBlockChangeDelegate world; // CraftBukkit - Change type
World world;
int[] d = new int[] { 0, 0, 0};
int e;
int f;
@ -350,16 +348,6 @@ public class WorldGenBigTree extends WorldGenTreeAbstract implements BlockSaplin
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
// sk: The idea is to have (our) WorldServer implement
// BlockChangeDelegate and then we can implicitly cast World to
// WorldServer (a safe cast, AFAIK) and no code will be broken. This
// then allows plugins to catch manually-invoked generation events
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
this.world = world;
long l = random.nextLong();

View file

@ -1,109 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenForest extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
private boolean a;
public WorldGenForest(boolean flag, boolean flag1) {
super(flag);
this.a = flag1;
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = random.nextInt(3) + 5;
if (this.a) {
l += random.nextInt(7);
}
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
int i1;
int j1;
for (int k1 = j; k1 <= j + 1 + l; ++k1) {
byte b0 = 1;
if (k1 == j) {
b0 = 0;
}
if (k1 >= j + 1 + l - 2) {
b0 = 2;
}
for (i1 = i - b0; i1 <= i + b0 && flag; ++i1) {
for (j1 = k - b0; j1 <= k + b0 && flag; ++j1) {
if (k1 >= 0 && k1 < 256) {
Block block = world.getType(i1, k1, j1);
if (!this.a(block)) {
flag = false;
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT || block1 == Blocks.SOIL) && j < 256 - l - 1) {
this.setType(world, i, j - 1, k, Blocks.DIRT);
int l1;
for (l1 = j - 3 + l; l1 <= j + l; ++l1) {
i1 = l1 - (j + l);
j1 = 1 - i1 / 2;
for (int i2 = i - j1; i2 <= i + j1; ++i2) {
int j2 = i2 - i;
for (int k2 = k - j1; k2 <= k + j1; ++k2) {
int l2 = k2 - k;
if (Math.abs(j2) != j1 || Math.abs(l2) != j1 || random.nextInt(2) != 0 && i1 != 0) {
Block block2 = world.getType(i2, l1, k2);
if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i2, l1, k2, Blocks.LEAVES, 2);
}
}
}
}
}
for (l1 = 0; l1 < l; ++l1) {
Block block3 = world.getType(i, j + l1, k);
if (block3.getMaterial() == Material.AIR || block3.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + l1, k, Blocks.LOG, 2);
}
}
return true;
} else {
return false;
}
}
} else {
return false;
}
}
}

View file

@ -1,175 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenForestTree extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
public WorldGenForestTree(boolean flag) {
super(flag);
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = random.nextInt(3) + random.nextInt(2) + 6;
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
int i1;
int j1;
for (int k1 = j; k1 <= j + 1 + l; ++k1) {
byte b0 = 1;
if (k1 == j) {
b0 = 0;
}
if (k1 >= j + 1 + l - 2) {
b0 = 2;
}
for (i1 = i - b0; i1 <= i + b0 && flag; ++i1) {
for (j1 = k - b0; j1 <= k + b0 && flag; ++j1) {
if (k1 >= 0 && k1 < 256) {
Block block = world.getType(i1, k1, j1);
if (!this.a(block)) {
flag = false;
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT) && j < 256 - l - 1) {
this.setType(world, i, j - 1, k, Blocks.DIRT);
this.setType(world, i + 1, j - 1, k, Blocks.DIRT);
this.setType(world, i + 1, j - 1, k + 1, Blocks.DIRT);
this.setType(world, i, j - 1, k + 1, Blocks.DIRT);
int l1 = random.nextInt(4);
i1 = l - random.nextInt(4);
j1 = 2 - random.nextInt(3);
int i2 = i;
int j2 = k;
int k2 = 0;
int l2;
int i3;
for (l2 = 0; l2 < l; ++l2) {
i3 = j + l2;
if (l2 >= i1 && j1 > 0) {
i2 += Direction.a[l1];
j2 += Direction.b[l1];
--j1;
}
Block block2 = world.getType(i2, i3, j2);
if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i2, i3, j2, Blocks.LOG2, 1);
this.setTypeAndData(world, i2 + 1, i3, j2, Blocks.LOG2, 1);
this.setTypeAndData(world, i2, i3, j2 + 1, Blocks.LOG2, 1);
this.setTypeAndData(world, i2 + 1, i3, j2 + 1, Blocks.LOG2, 1);
k2 = i3;
}
}
for (l2 = -2; l2 <= 0; ++l2) {
for (i3 = -2; i3 <= 0; ++i3) {
byte b1 = -1;
this.a(world, i2 + l2, k2 + b1, j2 + i3);
this.a(world, 1 + i2 - l2, k2 + b1, j2 + i3);
this.a(world, i2 + l2, k2 + b1, 1 + j2 - i3);
this.a(world, 1 + i2 - l2, k2 + b1, 1 + j2 - i3);
if ((l2 > -2 || i3 > -1) && (l2 != -1 || i3 != -2)) {
byte b2 = 1;
this.a(world, i2 + l2, k2 + b2, j2 + i3);
this.a(world, 1 + i2 - l2, k2 + b2, j2 + i3);
this.a(world, i2 + l2, k2 + b2, 1 + j2 - i3);
this.a(world, 1 + i2 - l2, k2 + b2, 1 + j2 - i3);
}
}
}
if (random.nextBoolean()) {
this.a(world, i2, k2 + 2, j2);
this.a(world, i2 + 1, k2 + 2, j2);
this.a(world, i2 + 1, k2 + 2, j2 + 1);
this.a(world, i2, k2 + 2, j2 + 1);
}
for (l2 = -3; l2 <= 4; ++l2) {
for (i3 = -3; i3 <= 4; ++i3) {
if ((l2 != -3 || i3 != -3) && (l2 != -3 || i3 != 4) && (l2 != 4 || i3 != -3) && (l2 != 4 || i3 != 4) && (Math.abs(l2) < 3 || Math.abs(i3) < 3)) {
this.a(world, i2 + l2, k2, j2 + i3);
}
}
}
for (l2 = -1; l2 <= 2; ++l2) {
for (i3 = -1; i3 <= 2; ++i3) {
if ((l2 < 0 || l2 > 1 || i3 < 0 || i3 > 1) && random.nextInt(3) <= 0) {
int j3 = random.nextInt(3) + 2;
int k3;
for (k3 = 0; k3 < j3; ++k3) {
this.setTypeAndData(world, i + l2, k2 - k3 - 1, k + i3, Blocks.LOG2, 1);
}
int l3;
for (k3 = -1; k3 <= 1; ++k3) {
for (l3 = -1; l3 <= 1; ++l3) {
this.a(world, i2 + l2 + k3, k2 - 0, j2 + i3 + l3);
}
}
for (k3 = -2; k3 <= 2; ++k3) {
for (l3 = -2; l3 <= 2; ++l3) {
if (Math.abs(k3) != 2 || Math.abs(l3) != 2) {
this.a(world, i2 + l2 + k3, k2 - 1, j2 + i3 + l3);
}
}
}
}
}
}
return true;
} else {
return false;
}
}
} else {
return false;
}
}
// CraftBukkit - Changed signature
private void a(CraftBlockChangeDelegate world, int i, int j, int k) {
Block block = world.getType(i, j, k);
if (block.getMaterial() == Material.AIR) {
this.setTypeAndData(world, i, j, k, Blocks.LEAVES2, 1);
}
}
}

View file

@ -2,8 +2,6 @@ package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenGroundBush extends WorldGenTrees {
private int a;
@ -16,13 +14,6 @@ public class WorldGenGroundBush extends WorldGenTrees {
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
@Override
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
Block block;
while (((block = world.getType(i, j, k)).getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) && j > 0) {

View file

@ -1,215 +0,0 @@
package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.CraftBlockChangeDelegate;
import org.bukkit.block.BlockState;
import org.bukkit.material.MaterialData;
// CraftBukkit end
public class WorldGenHugeMushroom extends WorldGenerator implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
private int a = -1;
public WorldGenHugeMushroom(int i) {
super(true);
this.a = i;
}
public WorldGenHugeMushroom() {
super(false);
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return grow(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k, null, null, null);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
return grow(world, random, i, j, k, null, null, null);
}
public boolean grow(CraftBlockChangeDelegate world, Random random, int i, int j, int k, org.bukkit.event.world.StructureGrowEvent event, ItemStack itemstack, org.bukkit.craftbukkit.CraftWorld bukkitWorld) {
// CraftBukkit end
int l = random.nextInt(2);
if (this.a >= 0) {
l = this.a;
}
int i1 = random.nextInt(3) + 4;
boolean flag = true;
if (j >= 1 && j + i1 + 1 < 256) {
int j1;
int k1;
for (int l1 = j; l1 <= j + 1 + i1; ++l1) {
byte b0 = 3;
if (l1 <= j + 3) {
b0 = 0;
}
for (j1 = i - b0; j1 <= i + b0 && flag; ++j1) {
for (k1 = k - b0; k1 <= k + b0 && flag; ++k1) {
if (l1 >= 0 && l1 < 256) {
Block block = world.getType(j1, l1, k1);
if (block.getMaterial() != Material.AIR && block.getMaterial() != Material.LEAVES) {
flag = false;
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if (block1 != Blocks.DIRT && block1 != Blocks.GRASS && block1 != Blocks.MYCEL) {
return false;
} else {
// CraftBukkit start
if (event == null) {
this.setTypeAndData(world, i, j - 1, k, Blocks.DIRT, 0);
} else {
BlockState dirtState = bukkitWorld.getBlockAt(i, j - 1, k).getState();
dirtState.setTypeId(Block.b(Blocks.DIRT));
event.getBlocks().add(dirtState);
}
// CraftBukkit end
int i2 = j + i1;
if (l == 1) {
i2 = j + i1 - 3;
}
for (j1 = i2; j1 <= j + i1; ++j1) {
k1 = 1;
if (j1 < j + i1) {
++k1;
}
if (l == 0) {
k1 = 3;
}
for (int j2 = i - k1; j2 <= i + k1; ++j2) {
for (int k2 = k - k1; k2 <= k + k1; ++k2) {
int l2 = 5;
if (j2 == i - k1) {
--l2;
}
if (j2 == i + k1) {
++l2;
}
if (k2 == k - k1) {
l2 -= 3;
}
if (k2 == k + k1) {
l2 += 3;
}
if (l == 0 || j1 < j + i1) {
if ((j2 == i - k1 || j2 == i + k1) && (k2 == k - k1 || k2 == k + k1)) {
continue;
}
if (j2 == i - (k1 - 1) && k2 == k - k1) {
l2 = 1;
}
if (j2 == i - k1 && k2 == k - (k1 - 1)) {
l2 = 1;
}
if (j2 == i + (k1 - 1) && k2 == k - k1) {
l2 = 3;
}
if (j2 == i + k1 && k2 == k - (k1 - 1)) {
l2 = 3;
}
if (j2 == i - (k1 - 1) && k2 == k + k1) {
l2 = 7;
}
if (j2 == i - k1 && k2 == k + (k1 - 1)) {
l2 = 7;
}
if (j2 == i + (k1 - 1) && k2 == k + k1) {
l2 = 9;
}
if (j2 == i + k1 && k2 == k + (k1 - 1)) {
l2 = 9;
}
}
if (l2 == 5 && j1 < j + i1) {
l2 = 0;
}
if ((l2 != 0 || j >= j + i1 - 1) && !world.getType(j2, j1, k2).j()) {
// CraftBukkit start
if (event == null) {
this.setTypeAndData(world, j2, j1, k2, Block.e(Block.b(Blocks.BIG_MUSHROOM_1) + l), l2);
} else {
BlockState state = bukkitWorld.getBlockAt(j2, j1, k2).getState();
state.setTypeId(Block.b(Blocks.BIG_MUSHROOM_1) + l);
state.setData(new MaterialData(Block.b(Blocks.BIG_MUSHROOM_1) + l, (byte) l2));
event.getBlocks().add(state);
}
// CraftBukkit end
}
}
}
}
for (j1 = 0; j1 < i1; ++j1) {
Block block2 = world.getType(i, j + j1, k);
if (!block2.j()) {
// CraftBukkit start
if (event == null) {
this.setTypeAndData(world, i, j + j1, k, Block.e(Block.b(Blocks.BIG_MUSHROOM_1) + l), 10);
} else {
BlockState state = bukkitWorld.getBlockAt(i, j + j1, k).getState();
state.setTypeId(Block.b(Blocks.BIG_MUSHROOM_1) + l);
state.setData(new MaterialData(Block.b(Blocks.BIG_MUSHROOM_1) + l, (byte) 10));
event.getBlocks().add(state);
}
// CraftBukkit end
}
}
// CraftBukkit start
if (event != null) {
org.bukkit.Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
for (BlockState state : event.getBlocks()) {
state.update(true);
}
}
}
// CraftBukkit end
return true;
}
}
} else {
return false;
}
}
}

View file

@ -1,124 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenJungleTree extends WorldGenMegaTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
public WorldGenJungleTree(boolean flag, int i, int j, int k, int l) {
super(flag, i, j, k, l);
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = this.a(random);
if (!this.a(world, random, i, j, k, l)) {
return false;
} else {
this.c(world, i, k, j + l, 2, random);
for (int i1 = j + l - 2 - random.nextInt(4); i1 > j + l / 2; i1 -= 2 + random.nextInt(4)) {
float f = random.nextFloat() * 3.1415927F * 2.0F;
int j1 = i + (int) (0.5F + MathHelper.cos(f) * 4.0F);
int k1 = k + (int) (0.5F + MathHelper.sin(f) * 4.0F);
int l1;
for (l1 = 0; l1 < 5; ++l1) {
j1 = i + (int) (1.5F + MathHelper.cos(f) * (float) l1);
k1 = k + (int) (1.5F + MathHelper.sin(f) * (float) l1);
this.setTypeAndData(world, j1, i1 - 3 + l1 / 2, k1, Blocks.LOG, this.b);
}
l1 = 1 + random.nextInt(2);
int i2 = i1;
for (int j2 = i1 - l1; j2 <= i2; ++j2) {
int k2 = j2 - i2;
this.b(world, j1, j2, k1, 1 - k2, random);
}
}
for (int l2 = 0; l2 < l; ++l2) {
Block block = world.getType(i, j + l2, k);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + l2, k, Blocks.LOG, this.b);
if (l2 > 0) {
if (random.nextInt(3) > 0 && world.isEmpty(i - 1, j + l2, k)) {
this.setTypeAndData(world, i - 1, j + l2, k, Blocks.VINE, 8);
}
if (random.nextInt(3) > 0 && world.isEmpty(i, j + l2, k - 1)) {
this.setTypeAndData(world, i, j + l2, k - 1, Blocks.VINE, 1);
}
}
}
if (l2 < l - 1) {
block = world.getType(i + 1, j + l2, k);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i + 1, j + l2, k, Blocks.LOG, this.b);
if (l2 > 0) {
if (random.nextInt(3) > 0 && world.isEmpty(i + 2, j + l2, k)) {
this.setTypeAndData(world, i + 2, j + l2, k, Blocks.VINE, 2);
}
if (random.nextInt(3) > 0 && world.isEmpty(i + 1, j + l2, k - 1)) {
this.setTypeAndData(world, i + 1, j + l2, k - 1, Blocks.VINE, 1);
}
}
}
block = world.getType(i + 1, j + l2, k + 1);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i + 1, j + l2, k + 1, Blocks.LOG, this.b);
if (l2 > 0) {
if (random.nextInt(3) > 0 && world.isEmpty(i + 2, j + l2, k + 1)) {
this.setTypeAndData(world, i + 2, j + l2, k + 1, Blocks.VINE, 2);
}
if (random.nextInt(3) > 0 && world.isEmpty(i + 1, j + l2, k + 2)) {
this.setTypeAndData(world, i + 1, j + l2, k + 2, Blocks.VINE, 4);
}
}
}
block = world.getType(i, j + l2, k + 1);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + l2, k + 1, Blocks.LOG, this.b);
if (l2 > 0) {
if (random.nextInt(3) > 0 && world.isEmpty(i - 1, j + l2, k + 1)) {
this.setTypeAndData(world, i - 1, j + l2, k + 1, Blocks.VINE, 8);
}
if (random.nextInt(3) > 0 && world.isEmpty(i, j + l2, k + 2)) {
this.setTypeAndData(world, i, j + l2, k + 2, Blocks.VINE, 4);
}
}
}
}
}
return true;
}
}
// CraftBukkit - Changed signature
private void c(CraftBlockChangeDelegate world, int i, int j, int k, int l, Random random) {
byte b0 = 2;
for (int i1 = k - b0; i1 <= k; ++i1) {
int j1 = i1 - k;
this.a(world, i, i1, j, l + 1 - j1, random);
}
}
}

View file

@ -1,124 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenMegaTree extends WorldGenMegaTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
private boolean e;
public WorldGenMegaTree(boolean flag, boolean flag1) {
super(flag, 13, 15, 1, 1);
this.e = flag1;
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = this.a(random);
if (!this.a(world, random, i, j, k, l)) {
return false;
} else {
this.c(world, i, k, j + l, 0, random);
for (int i1 = 0; i1 < l; ++i1) {
Block block = world.getType(i, j + i1, k);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + i1, k, Blocks.LOG, this.b);
}
if (i1 < l - 1) {
block = world.getType(i + 1, j + i1, k);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i + 1, j + i1, k, Blocks.LOG, this.b);
}
block = world.getType(i + 1, j + i1, k + 1);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i + 1, j + i1, k + 1, Blocks.LOG, this.b);
}
block = world.getType(i, j + i1, k + 1);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + i1, k + 1, Blocks.LOG, this.b);
}
}
}
}
return true;
}
// CraftBukkit - Changed signature
private void c(CraftBlockChangeDelegate world, int i, int j, int k, int l, Random random) {
int i1 = random.nextInt(5);
if (this.e) {
i1 += this.a;
} else {
i1 += 3;
}
int j1 = 0;
for (int k1 = k - i1; k1 <= k; ++k1) {
int l1 = k - k1;
int i2 = l + MathHelper.d((float) l1 / (float) i1 * 3.5F);
this.a(world, i, k1, j, i2 + (l1 > 0 && i2 == j1 && (k1 & 1) == 0 ? 1 : 0), random);
j1 = i2;
}
}
// CraftBukkit - Changed signature
public void b(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
this.c(world, random, i - 1, j, k - 1);
this.c(world, random, i + 2, j, k - 1);
this.c(world, random, i - 1, j, k + 2);
this.c(world, random, i + 2, j, k + 2);
for (int l = 0; l < 5; ++l) {
int i1 = random.nextInt(64);
int j1 = i1 % 8;
int k1 = i1 / 8;
if (j1 == 0 || j1 == 7 || k1 == 0 || k1 == 7) {
this.c(world, random, i - 3 + j1, j, k - 3 + k1);
}
}
}
// CraftBukkit - Changed signature
private void c(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
for (int l = -2; l <= 2; ++l) {
for (int i1 = -2; i1 <= 2; ++i1) {
if (Math.abs(l) != 2 || Math.abs(i1) != 2) {
this.a(world, i + l, j, k + i1);
}
}
}
}
// CraftBukkit - Changed signature
private void a(CraftBlockChangeDelegate world, int i, int j, int k) {
for (int l = j + 2; l >= j - 3; --l) {
Block block = world.getType(i, l, k);
if (block == Blocks.GRASS || block == Blocks.DIRT) {
this.setTypeAndData(world, i, l, k, Blocks.DIRT, 2);
break;
}
if (block.getMaterial() != Material.AIR && l < j) {
break;
}
}
}
}

View file

@ -2,8 +2,6 @@ package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public abstract class WorldGenMegaTreeAbstract extends WorldGenTreeAbstract {
protected final int a;
@ -29,8 +27,7 @@ public abstract class WorldGenMegaTreeAbstract extends WorldGenTreeAbstract {
return i;
}
// CraftBukkit - Changed world to CraftBlockChangeDelegate
private boolean b(CraftBlockChangeDelegate world, Random random, int i, int j, int k, int l) {
private boolean b(World world, Random random, int i, int j, int k, int l) {
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
@ -67,8 +64,7 @@ public abstract class WorldGenMegaTreeAbstract extends WorldGenTreeAbstract {
}
}
// CraftBukkit - Change world to CraftBlockChangeDelegate
private boolean c(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
private boolean c(World world, Random random, int i, int j, int k) {
Block block = world.getType(i, j - 1, k);
if ((block == Blocks.GRASS || block == Blocks.DIRT) && j >= 2) {
@ -82,13 +78,11 @@ public abstract class WorldGenMegaTreeAbstract extends WorldGenTreeAbstract {
}
}
// CraftBukkit - Change world to CraftBlockChangeDelegate
protected boolean a(CraftBlockChangeDelegate world, Random random, int i, int j, int k, int l) {
protected boolean a(World world, Random random, int i, int j, int k, int l) {
return this.b(world, random, i, j, k, l) && this.c(world, random, i, j, k);
}
// CraftBukkit - Change world to CraftBlockChangeDelegate
protected void a(CraftBlockChangeDelegate world, int i, int j, int k, int l, Random random) {
protected void a(World world, int i, int j, int k, int l, Random random) {
int i1 = l * l;
for (int j1 = i - l; j1 <= i + l + 1; ++j1) {
@ -110,8 +104,7 @@ public abstract class WorldGenMegaTreeAbstract extends WorldGenTreeAbstract {
}
}
// CraftBukkit - Change world to CraftBlockChangeDelegate
protected void b(CraftBlockChangeDelegate world, int i, int j, int k, int l, Random random) {
protected void b(World world, int i, int j, int k, int l, Random random) {
int i1 = l * l;
for (int j1 = i - l; j1 <= i + l; ++j1) {

View file

@ -1,151 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenSwampTree extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
public WorldGenSwampTree() {
super(false);
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l;
for (l = random.nextInt(4) + 5; world.getType(i, j - 1, k).getMaterial() == Material.WATER; --j) {
;
}
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
int i1;
int j1;
for (int k1 = j; k1 <= j + 1 + l; ++k1) {
byte b0 = 1;
if (k1 == j) {
b0 = 0;
}
if (k1 >= j + 1 + l - 2) {
b0 = 3;
}
for (i1 = i - b0; i1 <= i + b0 && flag; ++i1) {
for (j1 = k - b0; j1 <= k + b0 && flag; ++j1) {
if (k1 >= 0 && k1 < 256) {
Block block = world.getType(i1, k1, j1);
if (block.getMaterial() != Material.AIR && block.getMaterial() != Material.LEAVES) {
if (block != Blocks.STATIONARY_WATER && block != Blocks.WATER) {
flag = false;
} else if (k1 > j) {
flag = false;
}
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT) && j < 256 - l - 1) {
this.setType(world, i, j - 1, k, Blocks.DIRT);
int l1;
int i2;
int j2;
for (j2 = j - 3 + l; j2 <= j + l; ++j2) {
i1 = j2 - (j + l);
j1 = 2 - i1 / 2;
for (i2 = i - j1; i2 <= i + j1; ++i2) {
l1 = i2 - i;
for (int k2 = k - j1; k2 <= k + j1; ++k2) {
int l2 = k2 - k;
if ((Math.abs(l1) != j1 || Math.abs(l2) != j1 || random.nextInt(2) != 0 && i1 != 0) && !world.getType(i2, j2, k2).j()) {
this.setType(world, i2, j2, k2, Blocks.LEAVES);
}
}
}
}
for (j2 = 0; j2 < l; ++j2) {
Block block2 = world.getType(i, j + j2, k);
if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES || block2 == Blocks.WATER || block2 == Blocks.STATIONARY_WATER) {
this.setType(world, i, j + j2, k, Blocks.LOG);
}
}
for (j2 = j - 3 + l; j2 <= j + l; ++j2) {
i1 = j2 - (j + l);
j1 = 2 - i1 / 2;
for (i2 = i - j1; i2 <= i + j1; ++i2) {
for (l1 = k - j1; l1 <= k + j1; ++l1) {
if (world.getType(i2, j2, l1).getMaterial() == Material.LEAVES) {
if (random.nextInt(4) == 0 && world.getType(i2 - 1, j2, l1).getMaterial() == Material.AIR) {
this.a(world, i2 - 1, j2, l1, 8);
}
if (random.nextInt(4) == 0 && world.getType(i2 + 1, j2, l1).getMaterial() == Material.AIR) {
this.a(world, i2 + 1, j2, l1, 2);
}
if (random.nextInt(4) == 0 && world.getType(i2, j2, l1 - 1).getMaterial() == Material.AIR) {
this.a(world, i2, j2, l1 - 1, 1);
}
if (random.nextInt(4) == 0 && world.getType(i2, j2, l1 + 1).getMaterial() == Material.AIR) {
this.a(world, i2, j2, l1 + 1, 4);
}
}
}
}
}
return true;
} else {
return false;
}
}
} else {
return false;
}
}
// CraftBukkit - change signature
private void a(CraftBlockChangeDelegate world, int i, int j, int k, int l) {
this.setTypeAndData(world, i, j, k, Blocks.VINE, l);
int i1 = 4;
while (true) {
--j;
if (world.getType(i, j, k).getMaterial() != Material.AIR || i1 <= 0) {
return;
}
this.setTypeAndData(world, i, j, k, Blocks.VINE, l);
--i1;
}
}
}

View file

@ -1,101 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenTaiga1 extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
public WorldGenTaiga1() {
super(false);
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = random.nextInt(5) + 7;
int i1 = l - random.nextInt(2) - 3;
int j1 = l - i1;
int k1 = 1 + random.nextInt(j1 + 1);
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
int l1;
int i2;
int j2;
for (int k2 = j; k2 <= j + 1 + l && flag; ++k2) {
boolean flag1 = true;
if (k2 - j < i1) {
j2 = 0;
} else {
j2 = k1;
}
for (l1 = i - j2; l1 <= i + j2 && flag; ++l1) {
for (i2 = k - j2; i2 <= k + j2 && flag; ++i2) {
if (k2 >= 0 && k2 < 256) {
Block block = world.getType(l1, k2, i2);
if (!this.a(block)) {
flag = false;
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT) && j < 256 - l - 1) {
this.setType(world, i, j - 1, k, Blocks.DIRT);
j2 = 0;
for (l1 = j + l; l1 >= j + i1; --l1) {
for (i2 = i - j2; i2 <= i + j2; ++i2) {
int l2 = i2 - i;
for (int i3 = k - j2; i3 <= k + j2; ++i3) {
int j3 = i3 - k;
if ((Math.abs(l2) != j2 || Math.abs(j3) != j2 || j2 <= 0) && !world.getType(i2, l1, i3).j()) {
this.setTypeAndData(world, i2, l1, i3, Blocks.LEAVES, 1);
}
}
}
if (j2 >= 1 && l1 == j + i1 + 1) {
--j2;
} else if (j2 < k1) {
++j2;
}
}
for (l1 = 0; l1 < l - 1; ++l1) {
Block block2 = world.getType(i, j + l1, k);
if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + l1, k, Blocks.LOG, 1);
}
}
return true;
} else {
return false;
}
}
} else {
return false;
}
}
}

View file

@ -1,114 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenTaiga2 extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
public WorldGenTaiga2(boolean flag) {
super(flag);
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = random.nextInt(4) + 6;
int i1 = 1 + random.nextInt(2);
int j1 = l - i1;
int k1 = 2 + random.nextInt(2);
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
int l1;
int i2;
for (int j2 = j; j2 <= j + 1 + l && flag; ++j2) {
boolean flag1 = true;
if (j2 - j < i1) {
i2 = 0;
} else {
i2 = k1;
}
for (l1 = i - i2; l1 <= i + i2 && flag; ++l1) {
for (int k2 = k - i2; k2 <= k + i2 && flag; ++k2) {
if (j2 >= 0 && j2 < 256) {
Block block = world.getType(l1, j2, k2);
if (block.getMaterial() != Material.AIR && block.getMaterial() != Material.LEAVES) {
flag = false;
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT || block1 == Blocks.SOIL) && j < 256 - l - 1) {
this.setType(world, i, j - 1, k, Blocks.DIRT);
i2 = random.nextInt(2);
l1 = 1;
byte b0 = 0;
int l2;
int i3;
for (i3 = 0; i3 <= j1; ++i3) {
l2 = j + l - i3;
for (int j3 = i - i2; j3 <= i + i2; ++j3) {
int k3 = j3 - i;
for (int l3 = k - i2; l3 <= k + i2; ++l3) {
int i4 = l3 - k;
if ((Math.abs(k3) != i2 || Math.abs(i4) != i2 || i2 <= 0) && !world.getType(j3, l2, l3).j()) {
this.setTypeAndData(world, j3, l2, l3, Blocks.LEAVES, 1);
}
}
}
if (i2 >= l1) {
i2 = b0;
b0 = 1;
++l1;
if (l1 > k1) {
l1 = k1;
}
} else {
++i2;
}
}
i3 = random.nextInt(3);
for (l2 = 0; l2 < l - i3; ++l2) {
Block block2 = world.getType(i, j + l2, k);
if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + l2, k, Blocks.LOG, 1);
}
}
return true;
} else {
return false;
}
}
} else {
return false;
}
}
}

View file

@ -1,190 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public class WorldGenTrees extends WorldGenTreeAbstract implements BlockSapling.TreeGenerator { // CraftBukkit - add interface
private final int a;
private final boolean b;
private final int c;
private final int d;
public WorldGenTrees(boolean flag) {
this(flag, 4, 0, 0, false);
}
public WorldGenTrees(boolean flag, int i, int j, int k, boolean flag1) {
super(flag);
this.a = i;
this.c = j;
this.d = k;
this.b = flag1;
}
public boolean a(World world, Random random, int i, int j, int k) {
// CraftBukkit start - Moved to generate
return this.generate(new CraftBlockChangeDelegate((org.bukkit.BlockChangeDelegate) world), random, i, j, k);
}
public boolean generate(CraftBlockChangeDelegate world, Random random, int i, int j, int k) {
// CraftBukkit end
int l = random.nextInt(3) + this.a;
boolean flag = true;
if (j >= 1 && j + l + 1 <= 256) {
byte b0;
int i1;
Block block;
for (int j1 = j; j1 <= j + 1 + l; ++j1) {
b0 = 1;
if (j1 == j) {
b0 = 0;
}
if (j1 >= j + 1 + l - 2) {
b0 = 2;
}
for (int k1 = i - b0; k1 <= i + b0 && flag; ++k1) {
for (i1 = k - b0; i1 <= k + b0 && flag; ++i1) {
if (j1 >= 0 && j1 < 256) {
block = world.getType(k1, j1, i1);
if (!this.a(block)) {
flag = false;
}
} else {
flag = false;
}
}
}
}
if (!flag) {
return false;
} else {
Block block1 = world.getType(i, j - 1, k);
if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT || block1 == Blocks.SOIL) && j < 256 - l - 1) {
this.setType(world, i, j - 1, k, Blocks.DIRT);
b0 = 3;
byte b1 = 0;
int l1;
int i2;
int j2;
int k2;
for (i1 = j - b0 + l; i1 <= j + l; ++i1) {
k2 = i1 - (j + l);
l1 = b1 + 1 - k2 / 2;
for (i2 = i - l1; i2 <= i + l1; ++i2) {
j2 = i2 - i;
for (int l2 = k - l1; l2 <= k + l1; ++l2) {
int i3 = l2 - k;
if (Math.abs(j2) != l1 || Math.abs(i3) != l1 || random.nextInt(2) != 0 && k2 != 0) {
Block block2 = world.getType(i2, i1, l2);
if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i2, i1, l2, Blocks.LEAVES, this.d);
}
}
}
}
}
for (i1 = 0; i1 < l; ++i1) {
block = world.getType(i, j + i1, k);
if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) {
this.setTypeAndData(world, i, j + i1, k, Blocks.LOG, this.c);
if (this.b && i1 > 0) {
if (random.nextInt(3) > 0 && world.isEmpty(i - 1, j + i1, k)) {
this.setTypeAndData(world, i - 1, j + i1, k, Blocks.VINE, 8);
}
if (random.nextInt(3) > 0 && world.isEmpty(i + 1, j + i1, k)) {
this.setTypeAndData(world, i + 1, j + i1, k, Blocks.VINE, 2);
}
if (random.nextInt(3) > 0 && world.isEmpty(i, j + i1, k - 1)) {
this.setTypeAndData(world, i, j + i1, k - 1, Blocks.VINE, 1);
}
if (random.nextInt(3) > 0 && world.isEmpty(i, j + i1, k + 1)) {
this.setTypeAndData(world, i, j + i1, k + 1, Blocks.VINE, 4);
}
}
}
}
if (this.b) {
for (i1 = j - 3 + l; i1 <= j + l; ++i1) {
k2 = i1 - (j + l);
l1 = 2 - k2 / 2;
for (i2 = i - l1; i2 <= i + l1; ++i2) {
for (j2 = k - l1; j2 <= k + l1; ++j2) {
if (world.getType(i2, i1, j2).getMaterial() == Material.LEAVES) {
if (random.nextInt(4) == 0 && world.getType(i2 - 1, i1, j2).getMaterial() == Material.AIR) {
this.a(world, i2 - 1, i1, j2, 8);
}
if (random.nextInt(4) == 0 && world.getType(i2 + 1, i1, j2).getMaterial() == Material.AIR) {
this.a(world, i2 + 1, i1, j2, 2);
}
if (random.nextInt(4) == 0 && world.getType(i2, i1, j2 - 1).getMaterial() == Material.AIR) {
this.a(world, i2, i1, j2 - 1, 1);
}
if (random.nextInt(4) == 0 && world.getType(i2, i1, j2 + 1).getMaterial() == Material.AIR) {
this.a(world, i2, i1, j2 + 1, 4);
}
}
}
}
}
if (random.nextInt(5) == 0 && l > 5) {
for (i1 = 0; i1 < 2; ++i1) {
for (k2 = 0; k2 < 4; ++k2) {
if (random.nextInt(4 - i1) == 0) {
l1 = random.nextInt(3);
this.setTypeAndData(world, i + Direction.a[Direction.f[k2]], j + l - 5 + i1, k + Direction.b[Direction.f[k2]], Blocks.COCOA, l1 << 2 | k2);
}
}
}
}
}
return true;
} else {
return false;
}
}
} else {
return false;
}
}
// CraftBukkit - Changed world to BlockChangeDelegate
private void a(CraftBlockChangeDelegate world, int i, int j, int k, int l) {
this.setTypeAndData(world, i, j, k, Blocks.VINE, l);
int i1 = 4;
while (true) {
--j;
if (world.getType(i, j, k).getMaterial() != Material.AIR || i1 <= 0) {
return;
}
this.setTypeAndData(world, i, j, k, Blocks.VINE, l);
--i1;
}
}
}

View file

@ -1,50 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.CraftBlockChangeDelegate; // CraftBukkit
public abstract class WorldGenerator {
private final boolean a;
public WorldGenerator() {
this.a = false;
}
public WorldGenerator(boolean flag) {
this.a = flag;
}
public abstract boolean a(World world, Random random, int i, int j, int k);
public void a(double d0, double d1, double d2) {}
protected void setType(World world, int i, int j, int k, Block block) {
this.setTypeAndData(world, i, j, k, block, 0);
}
// CraftBukkit start - Duplicate method to add support for CraftBlockChangeDelegate
protected void setType(CraftBlockChangeDelegate world, int i, int j, int k, Block block) {
this.setTypeAndData(world, i, j, k, block, 0);
}
// CraftBukkit end
protected void setTypeAndData(World world, int i, int j, int k, Block block, int l) {
if (this.a) {
world.setTypeAndData(i, j, k, block, l, 3);
} else {
world.setTypeAndData(i, j, k, block, l, 2);
}
}
// CraftBukkit start - Duplicate method to add support for CraftBlockChangeDelegate
protected void setTypeAndData(CraftBlockChangeDelegate world, int i, int j, int k, Block block, int l) {
if (this.a) {
world.setTypeAndData(i, j, k, block, l, 3);
} else {
world.setTypeAndData(i, j, k, block, l, 2);
}
}
// CraftBukkit end
}

View file

@ -22,9 +22,9 @@ import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.weather.LightningStrikeEvent;
import org.bukkit.event.weather.ThunderChangeEvent;
import org.bukkit.event.weather.WeatherChangeEvent;
// CraftBukkit end
public class WorldServer extends World implements org.bukkit.BlockChangeDelegate {
// CraftBukkit end
public class WorldServer extends World {
private static final Logger a = LogManager.getLogger();
private final MinecraftServer server;
@ -998,23 +998,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate
}
}
// CraftBukkit start - Compatibility methods for BlockChangeDelegate
public boolean setRawTypeId(int x, int y, int z, int typeId) {
return this.setTypeAndData(x, y, z, Block.e(typeId), 0, 4);
}
public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data) {
return this.setTypeAndData(x, y, z, Block.e(typeId), data, 4);
}
public boolean setTypeId(int x, int y, int z, int typeId) {
return this.setTypeAndData(x, y, z, Block.e(typeId), 0, 3);
}
public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data) {
return this.setTypeAndData(x, y, z, Block.e(typeId), data, 3);
}
// CraftBukkit start - Helper method
public int getTypeId(int x, int y, int z) {
return Block.b(getType(x, y, z));
}

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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;
}

View file

@ -102,6 +102,27 @@ public class CraftEventFactory {
/**
* Block place methods
*/
public static BlockMultiPlaceEvent callBlockMultiPlaceEvent(World world, EntityHuman who, List<BlockState> 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();