Fix TileEntities and Blocks getting out of sync. Fixes BUKKIT-3501

Also fixes: BUKKIT-3477 and BUKKIT-3488

Minecraft likes to double check that tile entities get set after they
are placed, however we didn't set tile entities until after our event
was called. This caused the world to have multiple tile entities in a
single block location; to fix this we now set tile entities before
the event.
Dieser Commit ist enthalten in:
feildmaster 2013-01-27 09:13:06 -06:00
Ursprung 6e438ccb32
Commit 528bbbdcd8
3 geänderte Dateien mit 9 neuen und 11 gelöschten Zeilen

Datei anzeigen

@ -428,13 +428,10 @@ public class Chunk {
TileEntity tileentity;
if (l != 0) {
if (!this.world.isStatic) {
// CraftBukkit start - Don't "place" if we're processing the event
if (!this.world.suppressPhysics) {
// CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer
if (!this.world.isStatic && (!this.world.callingPlaceEvent || (Block.byId[l] instanceof BlockContainer))) {
Block.byId[l].onPlace(this.world, j2, j, k2);
}
// CraftBukkit end
}
if (Block.byId[l] instanceof BlockContainer) {
// CraftBukkit start - don't create tile entity if placement failed

Datei anzeigen

@ -80,22 +80,25 @@ public class ItemBlock extends Item {
org.bukkit.block.BlockState blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(world, x, y, z);
world.suppressPhysics = true;
world.callingPlaceEvent = true;
world.setRawTypeIdAndData(x, y, z, id, data);
org.bukkit.event.block.BlockPlaceEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockstate, x, y, z);
if (event.isCancelled() || !event.canBuild()) {
blockstate.update(true);
world.suppressPhysics = false;
world.callingPlaceEvent = false;
return false;
}
world.suppressPhysics = false;
world.callingPlaceEvent = false;
int newId = world.getTypeId(x, y, z);
int newData = world.getData(x, y, z);
Block block = Block.byId[newId];
if (block != null) {
if (block != null && !(block instanceof BlockContainer)) { // Containers get placed automatically
block.onPlace(world, x, y, z);
}

Datei anzeigen

@ -45,6 +45,7 @@ public abstract class World implements IBlockAccess {
protected float p;
public int q = 0;
public boolean suppressPhysics = false;
public boolean callingPlaceEvent = false; // CraftBukkit
public int difficulty;
public Random random = new Random();
public WorldProvider worldProvider; // CraftBukkit - remove final
@ -394,11 +395,8 @@ public abstract class World implements IBlockAccess {
}
public boolean setTypeId(int i, int j, int k, int l) {
// CraftBukkit start
int old = this.getTypeId(i, j, k);
if (this.setRawTypeId(i, j, k, l)) {
this.update(i, j, k, l == 0 ? old : l);
// CraftBukkit end
this.update(i, j, k, l);
return true;
} else {
return false;