From 19507baf8b7903427bc3efab7118de6e7c1c931e Mon Sep 17 00:00:00 2001 From: Lukas Hennig Date: Sat, 5 Aug 2017 14:37:19 +1000 Subject: [PATCH] Improvements to BlockStates * Actually capture all the data of TileEntities. This is done by creating a copy of the TileEntity. The methods of BlockState which currently directly access the TileEntity reference will modify the data of that TileEntity-snapshot instead. * With the call to BlockState.update, the captured TileEntity data gets applied to the current TileEntity in the world. * Methods which trigger block specific actions will use the current TileEntity from the world. * CraftBlockState does not hand out the wrapped or the snapshot TileEntity directly. Instead, it provides an applyTo method to copy the data to a given TileEntity and a method to directly get a copy of the TileEntity NBT data represented by the BlockState. CraftMetaBlockState was updated to make use of that. * Added #getSnapshotInventory() to bukkit which allows modifiying the captured inventory snapshots of containers. * Tried to clarify which methods only work if the BlockState is placed, which methods require the block in the world to still be of the same type (methods which trigger actions), and that .getInventory() directly modifies the inventory of the block in the world if the BlockState is placed and becomes invalid if the block type is changed. Backwards compatibility * If the BlockState acts as InventoryHolder, getInventory() will still return the inventory directly backed by the TileEntity in the world (like before), and not the snapshot inventory. This compromise should reduce the potential of these changes to break existing plugins, or craftbukkit's own use of BlockState. * The snapshot's inventory can be accessed by a new method getSnapshotInventory() * In case the BlockState is not placed (if it was retrieved from the MetaBlockState of an item), the getInventory() method will however return the snapshot inventory. So that when the BlockState gets applied back to the item, the inventory changes are properly included. * With the changes to CraftMetaBlockState it is no longer required to call the update method before passing a modified BlockState to the CraftMetaBlockState. For backwards compatibility the update method will simply return true for a non-placed BlockState, without actually doing anything. Impact on plugins * Restoring blocks now actually works as expected, properly restoring the TileEntity data, reglardless if the block changed its type in the meantime. * Plugins are now consistently required to call the update method in order to apply changes to blocks. Though, regarding the Javadoc they should have been required to do so anyways. * New feature: Plugins can take and modify inventory snapshots. * Breaking change: If a plugin gets the BlockState of a block in the world, modifies the inventory returned by .getInventory(), and then tries to use the same BlockState to apply the TileEntity data to an ItemStack block meta, the ItemStack will use the snapshot inventory, disregarding the changes made to the inventory returned by .getInventory(). This is the compromise of .getInventory() returning the inventory directly backed by the TileEntity in the world. Other fixes related to BlockState: * TileEntityContainer#getLocation() will run into a NPE if the TileEntity is non-placed (ex. when getting the BlockState from a CraftMetaBlockState). * Beacon.getEntitiesInRange() would previously throw a NPE if called for a non-placed BlockState. It was changed to now require to be placed and use the current TileEntity in the world. If the TileEntity in the world is no longer a beacon, it will return an empty list. * EndGateway now supports setting and getting the exit location even for non-placed EndGateways (inside BlockStateMeta) by using / returning a location with world being null. --- nms-patches/TileEntityBrewingStand.patch | 18 +-- nms-patches/TileEntityContainer.patch | 3 +- .../bukkit/craftbukkit/block/CraftBanner.java | 58 +++------ .../bukkit/craftbukkit/block/CraftBeacon.java | 68 +++++----- .../bukkit/craftbukkit/block/CraftBed.java | 32 ++--- .../bukkit/craftbukkit/block/CraftBlock.java | 9 +- .../block/CraftBlockEntityState.java | 120 ++++++++++++++++++ .../craftbukkit/block/CraftBlockState.java | 7 - .../craftbukkit/block/CraftBrewingStand.java | 50 +++----- .../bukkit/craftbukkit/block/CraftChest.java | 55 ++++---- .../craftbukkit/block/CraftCommandBlock.java | 43 +++---- .../craftbukkit/block/CraftComparator.java | 22 +--- .../craftbukkit/block/CraftContainer.java | 26 ++-- .../block/CraftCreatureSpawner.java | 32 ++--- .../block/CraftDaylightDetector.java | 22 +--- .../craftbukkit/block/CraftDispenser.java | 44 +++---- .../craftbukkit/block/CraftDropper.java | 41 +++--- .../block/CraftEnchantingTable.java | 25 +--- .../craftbukkit/block/CraftEndGateway.java | 47 ++----- .../craftbukkit/block/CraftEnderChest.java | 22 +--- .../craftbukkit/block/CraftFlowerPot.java | 32 ++--- .../craftbukkit/block/CraftFurnace.java | 46 +++---- .../bukkit/craftbukkit/block/CraftHopper.java | 32 ++--- .../craftbukkit/block/CraftJukebox.java | 70 +++++----- .../craftbukkit/block/CraftLootable.java | 20 +-- .../craftbukkit/block/CraftNoteBlock.java | 39 +++--- .../craftbukkit/block/CraftShulkerBox.java | 30 ++--- .../bukkit/craftbukkit/block/CraftSign.java | 44 +++---- .../bukkit/craftbukkit/block/CraftSkull.java | 55 ++++---- .../block/CraftStructureBlock.java | 19 +-- .../inventory/CraftMetaBlockState.java | 52 ++++---- 31 files changed, 531 insertions(+), 652 deletions(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java diff --git a/nms-patches/TileEntityBrewingStand.patch b/nms-patches/TileEntityBrewingStand.patch index 11833f9693..fe3d21e34d 100644 --- a/nms-patches/TileEntityBrewingStand.patch +++ b/nms-patches/TileEntityBrewingStand.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/TileEntityBrewingStand.java +++ b/net/minecraft/server/TileEntityBrewingStand.java -@@ -3,6 +3,15 @@ +@@ -3,6 +3,16 @@ import java.util.Arrays; import java.util.Iterator; @@ -11,12 +11,13 @@ +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.BrewEvent; +import org.bukkit.event.inventory.BrewingStandFuelEvent; ++import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end + public class TileEntityBrewingStand extends TileEntityContainer implements ITickable, IWorldInventory { private static final int[] a = new int[] { 3}; -@@ -14,6 +23,31 @@ +@@ -14,6 +24,31 @@ private Item k; private String l; private int fuelLevel; @@ -48,7 +49,7 @@ public TileEntityBrewingStand() { this.items = NonNullList.a(5, ItemStack.a); -@@ -55,8 +89,19 @@ +@@ -55,8 +90,19 @@ ItemStack itemstack = (ItemStack) this.items.get(4); if (this.fuelLevel <= 0 && itemstack.getItem() == Items.BLAZE_POWDER) { @@ -70,7 +71,7 @@ this.update(); } -@@ -64,9 +109,14 @@ +@@ -64,9 +110,14 @@ boolean flag1 = this.brewTime > 0; ItemStack itemstack1 = (ItemStack) this.items.get(3); @@ -87,13 +88,14 @@ if (flag2 && flag) { this.p(); -@@ -140,6 +190,15 @@ +@@ -140,6 +191,16 @@ private void p() { ItemStack itemstack = (ItemStack) this.items.get(3); + // CraftBukkit start -+ if (getOwner() != null) { -+ BrewEvent event = new BrewEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), (org.bukkit.inventory.BrewerInventory) this.getOwner().getInventory(), this.fuelLevel); ++ InventoryHolder owner = this.getOwner(); ++ if (owner != null) { ++ BrewEvent event = new BrewEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), (org.bukkit.inventory.BrewerInventory) owner.getInventory(), this.fuelLevel); + org.bukkit.Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; @@ -103,7 +105,7 @@ for (int i = 0; i < 3; ++i) { this.items.set(i, PotionBrewer.d(itemstack, (ItemStack) this.items.get(i))); -@@ -210,7 +269,7 @@ +@@ -210,7 +271,7 @@ } public int getMaxStackSize() { diff --git a/nms-patches/TileEntityContainer.patch b/nms-patches/TileEntityContainer.patch index 3484ee4f41..e49e2ca979 100644 --- a/nms-patches/TileEntityContainer.patch +++ b/nms-patches/TileEntityContainer.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/TileEntityContainer.java +++ b/net/minecraft/server/TileEntityContainer.java -@@ -37,4 +37,11 @@ +@@ -37,4 +37,12 @@ public IChatBaseComponent getScoreboardDisplayName() { return (IChatBaseComponent) (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatMessage(this.getName(), new Object[0])); } @@ -8,6 +8,7 @@ + // CraftBukkit start + @Override + public org.bukkit.Location getLocation() { ++ if (world == null) return null; + return new org.bukkit.Location(world.getWorld(), position.getX(), position.getY(), position.getZ()); + } + // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java index 7bf7269945..f374385e91 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java @@ -12,33 +12,23 @@ import org.bukkit.block.Banner; import org.bukkit.block.Block; import org.bukkit.block.banner.Pattern; import org.bukkit.block.banner.PatternType; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftBanner extends CraftBlockState implements Banner { +public class CraftBanner extends CraftBlockEntityState implements Banner { - private final TileEntityBanner banner; private DyeColor base; private List patterns = new ArrayList(); public CraftBanner(final Block block) { - super(block); - - CraftWorld world = (CraftWorld) block.getWorld(); - banner = (TileEntityBanner) world.getTileEntityAt(getX(), getY(), getZ()); - - base = DyeColor.getByDyeData((byte) banner.color.getInvColorIndex()); - - if (banner.patterns != null) { - for (int i = 0; i < banner.patterns.size(); i++) { - NBTTagCompound p = (NBTTagCompound) banner.patterns.get(i); - patterns.add(new Pattern(DyeColor.getByDyeData((byte) p.getInt("Color")), PatternType.getByIdentifier(p.getString("Pattern")))); - } - } + super(block, TileEntityBanner.class); } public CraftBanner(final Material material, final TileEntityBanner te) { - super(material); - banner = te; + super(material, te); + } + + @Override + public void load(TileEntityBanner banner) { + super.load(banner); base = DyeColor.getByDyeData((byte) banner.color.getInvColorIndex()); @@ -96,31 +86,19 @@ public class CraftBanner extends CraftBlockState implements Banner { } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public void applyTo(TileEntityBanner banner) { + super.applyTo(banner); - if (result) { - banner.color = EnumColor.fromInvColorIndex(base.getDyeData()); + banner.color = EnumColor.fromInvColorIndex(base.getDyeData()); - NBTTagList newPatterns = new NBTTagList(); + NBTTagList newPatterns = new NBTTagList(); - for (Pattern p : patterns) { - NBTTagCompound compound = new NBTTagCompound(); - compound.setInt("Color", p.getColor().getDyeData()); - compound.setString("Pattern", p.getPattern().getIdentifier()); - newPatterns.add(compound); - } - - banner.patterns = newPatterns; - - banner.update(); + for (Pattern p : patterns) { + NBTTagCompound compound = new NBTTagCompound(); + compound.setInt("Color", p.getColor().getDyeData()); + compound.setString("Pattern", p.getPattern().getIdentifier()); + newPatterns.add(compound); } - - return result; - } - - @Override - public TileEntityBanner getTileEntity() { - return banner; + banner.patterns = newPatterns; } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java index a679221a41..afec900c67 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java @@ -4,98 +4,94 @@ import java.util.ArrayList; import java.util.Collection; import net.minecraft.server.EntityHuman; import net.minecraft.server.MobEffectList; +import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityBeacon; import org.bukkit.Material; import org.bukkit.block.Beacon; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftInventoryBeacon; import org.bukkit.entity.LivingEntity; -import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.BeaconInventory; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -public class CraftBeacon extends CraftContainer implements Beacon { - private final CraftWorld world; - private final TileEntityBeacon beacon; +public class CraftBeacon extends CraftContainer implements Beacon { public CraftBeacon(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - beacon = (TileEntityBeacon) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityBeacon.class); } public CraftBeacon(final Material material, final TileEntityBeacon te) { super(material, te); - world = null; - beacon = te; - } - - public Inventory getInventory() { - return new CraftInventoryBeacon(beacon); } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public BeaconInventory getSnapshotInventory() { + return new CraftInventoryBeacon(this.getSnapshot()); + } - if (result) { - beacon.update(); + @Override + public BeaconInventory getInventory() { + if (!this.isPlaced()) { + return this.getSnapshotInventory(); } - return result; - } - - @Override - public TileEntityBeacon getTileEntity() { - return beacon; + return new CraftInventoryBeacon(this.getTileEntity()); } @Override public Collection getEntitiesInRange() { - Collection nms = beacon.getHumansInRange(); - Collection bukkit = new ArrayList(nms.size()); + TileEntity tileEntity = this.getTileEntityFromWorld(); + if (tileEntity instanceof TileEntityBeacon) { + TileEntityBeacon beacon = (TileEntityBeacon) tileEntity; - for (EntityHuman human : nms) { - bukkit.add(human.getBukkitEntity()); + Collection nms = beacon.getHumansInRange(); + Collection bukkit = new ArrayList(nms.size()); + + for (EntityHuman human : nms) { + bukkit.add(human.getBukkitEntity()); + } + + return bukkit; } - return bukkit; + // block is no longer a beacon + return new ArrayList(); } @Override public int getTier() { - return beacon.levels; + return this.getSnapshot().levels; } @Override public PotionEffect getPrimaryEffect() { - return beacon.getPrimaryEffect(); + return this.getSnapshot().getPrimaryEffect(); } @Override public void setPrimaryEffect(PotionEffectType effect) { - beacon.primaryEffect = (effect != null) ? MobEffectList.fromId(effect.getId()) : null; + this.getSnapshot().primaryEffect = (effect != null) ? MobEffectList.fromId(effect.getId()) : null; } @Override public PotionEffect getSecondaryEffect() { - return beacon.getSecondaryEffect(); + return this.getSnapshot().getSecondaryEffect(); } @Override public void setSecondaryEffect(PotionEffectType effect) { - beacon.secondaryEffect = (effect != null) ? MobEffectList.fromId(effect.getId()) : null; + this.getSnapshot().secondaryEffect = (effect != null) ? MobEffectList.fromId(effect.getId()) : null; } @Override public String getCustomName() { + TileEntityBeacon beacon = this.getSnapshot(); return beacon.hasCustomName() ? beacon.getName() : null; } @Override public void setCustomName(String name) { - beacon.setCustomName(name); + this.getSnapshot().setCustomName(name); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBed.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBed.java index f6083565bd..27756d8587 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBed.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBed.java @@ -2,36 +2,29 @@ package org.bukkit.craftbukkit.block; import com.google.common.base.Preconditions; import net.minecraft.server.EnumColor; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityBed; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.block.Bed; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftBed extends CraftBlockState implements Bed { +public class CraftBed extends CraftBlockEntityState implements Bed { - private final TileEntityBed bed; private DyeColor color; public CraftBed(Block block) { - super(block); - - bed = (TileEntityBed) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); - color = DyeColor.getByWoolData((byte) bed.a().getColorIndex()); + super(block, TileEntityBed.class); } public CraftBed(Material material, TileEntityBed te) { - super(material); - - bed = te; - color = DyeColor.getByWoolData((byte) bed.a().getColorIndex()); + super(material, te); } @Override - public TileEntity getTileEntity() { - return bed; + public void load(TileEntityBed bed) { + super.load(bed); + + color = DyeColor.getByWoolData((byte) bed.a().getColorIndex()); } @Override @@ -47,14 +40,9 @@ public class CraftBed extends CraftBlockState implements Bed { } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public void applyTo(TileEntityBed bed) { + super.applyTo(bed); - if (result) { - bed.a(EnumColor.fromColorIndex(color.getWoolData())); - bed.update(); - } - - return result; + bed.a(EnumColor.fromColorIndex(color.getWoolData())); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index a2d633797e..ba1cdc18fe 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -336,7 +336,14 @@ public class CraftBlock implements Block { case BED_BLOCK: return new CraftBed(this); default: - return new CraftBlockState(this); + TileEntity tileEntity = chunk.getCraftWorld().getTileEntityAt(x, y, z); + if (tileEntity != null) { + // block with unhandled TileEntity: + return new CraftBlockEntityState(this, (Class) tileEntity.getClass()); + } else { + // Block without TileEntity: + return new CraftBlockState(this); + } } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java new file mode 100644 index 0000000000..cf94c06269 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java @@ -0,0 +1,120 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.TileEntity; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.CraftWorld; + +public class CraftBlockEntityState extends CraftBlockState { + + private final Class tileEntityClass; + private final T tileEntity; + private final T snapshot; + + public CraftBlockEntityState(Block block, Class tileEntityClass) { + super(block); + + this.tileEntityClass = tileEntityClass; + + // get tile entity from block: + CraftWorld world = (CraftWorld) this.getWorld(); + this.tileEntity = tileEntityClass.cast(world.getTileEntityAt(this.getX(), this.getY(), this.getZ())); + + // copy tile entity data: + this.snapshot = this.createSnapshot(tileEntity); + this.load(snapshot); + } + + public CraftBlockEntityState(Material material, T tileEntity) { + super(material); + + this.tileEntityClass = (Class) tileEntity.getClass(); + this.tileEntity = tileEntity; + + // copy tile entity data: + this.snapshot = this.createSnapshot(tileEntity); + this.load(snapshot); + } + + private T createSnapshot(T tileEntity) { + if (tileEntity == null) { + return null; + } + + NBTTagCompound nbtTagCompound = tileEntity.save(new NBTTagCompound()); + T snapshot = (T) TileEntity.create(null, nbtTagCompound); + + return snapshot; + } + + // copies the TileEntity-specific data, retains the position + private void copyData(T from, T to) { + BlockPosition pos = to.getPosition(); + NBTTagCompound nbtTagCompound = from.save(new NBTTagCompound()); + to.load(nbtTagCompound); + + // reset the original position: + to.setPosition(pos); + } + + // gets the wrapped TileEntity + protected T getTileEntity() { + return tileEntity; + } + + // gets the cloned TileEntity which is used to store the captured data + protected T getSnapshot() { + return snapshot; + } + + // gets the current TileEntity from the world at this position + protected TileEntity getTileEntityFromWorld() { + requirePlaced(); + + return ((CraftWorld) this.getWorld()).getTileEntityAt(this.getX(), this.getY(), this.getZ()); + } + + // gets the NBT data of the TileEntity represented by this block state + public NBTTagCompound getSnapshotNBT() { + // update snapshot + applyTo(snapshot); + + return snapshot.save(new NBTTagCompound()); + } + + // copies the data of the given tile entity data to this block state + protected void load(T tileEntity) { + if (tileEntity != null && tileEntity != snapshot) { + copyData(tileEntity, snapshot); + } + } + + // applies the TileEntity data of this block state to the given TileEntity + protected void applyTo(T tileEntity) { + if (tileEntity != null && tileEntity != snapshot) { + copyData(snapshot, tileEntity); + } + } + + protected boolean isApplicable(TileEntity tileEntity) { + return tileEntityClass.isInstance(tileEntity); + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result && this.isPlaced()) { + TileEntity tile = getTileEntityFromWorld(); + + if (isApplicable(tile)) { + applyTo(tileEntityClass.cast(tile)); + tile.update(); + } + } + + return result; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java index 5d83155a12..2a1b731c0c 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -3,7 +3,6 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.BlockPosition; import org.bukkit.Location; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.World; @@ -17,9 +16,7 @@ import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import java.util.List; -import net.minecraft.server.EnumDirection; import net.minecraft.server.IBlockData; -import net.minecraft.server.TileEntity; public class CraftBlockState implements BlockState { private final CraftWorld world; @@ -256,10 +253,6 @@ public class CraftBlockState implements BlockState { return hash; } - public TileEntity getTileEntity() { - return null; - } - public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { requirePlaced(); chunk.getCraftWorld().getBlockMetadata().setMetadata(getBlock(), metadataKey, newMetadataValue); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java index 78e8c9c605..4f717f2849 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java @@ -4,69 +4,61 @@ import net.minecraft.server.TileEntityBrewingStand; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BrewingStand; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; import org.bukkit.inventory.BrewerInventory; -public class CraftBrewingStand extends CraftContainer implements BrewingStand { - private final TileEntityBrewingStand brewingStand; +public class CraftBrewingStand extends CraftContainer implements BrewingStand { public CraftBrewingStand(Block block) { - super(block); - - brewingStand = (TileEntityBrewingStand) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityBrewingStand.class); } public CraftBrewingStand(final Material material, final TileEntityBrewingStand te) { super(material, te); - brewingStand = te; - } - - public BrewerInventory getInventory() { - return new CraftInventoryBrewer(brewingStand); } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public BrewerInventory getSnapshotInventory() { + return new CraftInventoryBrewer(this.getSnapshot()); + } - if (result) { - brewingStand.update(); + @Override + public BrewerInventory getInventory() { + if (!this.isPlaced()) { + return this.getSnapshotInventory(); } - return result; - } - - public int getBrewingTime() { - return brewingStand.getProperty(0); - } - - public void setBrewingTime(int brewTime) { - brewingStand.setProperty(0, brewTime); + return new CraftInventoryBrewer(this.getTileEntity()); } @Override - public TileEntityBrewingStand getTileEntity() { - return brewingStand; + public int getBrewingTime() { + return this.getSnapshot().getProperty(0); + } + + @Override + public void setBrewingTime(int brewTime) { + this.getSnapshot().setProperty(0, brewTime); } @Override public int getFuelLevel() { - return brewingStand.getProperty(1); + return this.getSnapshot().getProperty(1); } @Override public void setFuelLevel(int level) { - brewingStand.setProperty(1, level); + this.getSnapshot().setProperty(1, level); } @Override public String getCustomName() { + TileEntityBrewingStand brewingStand = this.getSnapshot(); return brewingStand.hasCustomName() ? brewingStand.getName() : null; } @Override public void setCustomName(String name) { - brewingStand.setCustomName(name); + this.getSnapshot().setCustomName(name); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java index 3de7e14d80..85f3bb2720 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java @@ -11,36 +11,43 @@ import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest; import org.bukkit.inventory.Inventory; -public class CraftChest extends CraftLootable implements Chest { - private final CraftWorld world; - private final TileEntityChest chest; +public class CraftChest extends CraftLootable implements Chest { public CraftChest(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - chest = (TileEntityChest) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityChest.class); } public CraftChest(final Material material, final TileEntityChest te) { super(material, te); - chest = te; - world = null; } + @Override + public Inventory getSnapshotInventory() { + return new CraftInventory(this.getSnapshot()); + } + + @Override public Inventory getBlockInventory() { - return new CraftInventory(chest); + if (!this.isPlaced()) { + return this.getSnapshotInventory(); + } + + return new CraftInventory(this.getTileEntity()); } + @Override public Inventory getInventory() { - int x = getX(); - int y = getY(); - int z = getZ(); - // The logic here is basically identical to the logic in BlockChest.interact - CraftInventory inventory = new CraftInventory(chest); + CraftInventory inventory = (CraftInventory) this.getBlockInventory(); if (!isPlaced()) { return inventory; } + + // The logic here is basically identical to the logic in BlockChest.interact + int x = this.getX(); + int y = this.getY(); + int z = this.getZ(); + CraftWorld world = (CraftWorld) this.getWorld(); + int id; if (world.getBlockTypeIdAt(x, y, z) == Material.CHEST.getId()) { id = Material.CHEST.getId(); @@ -51,7 +58,7 @@ public class CraftChest extends CraftLootable implements Chest { } if (world.getBlockTypeIdAt(x - 1, y, z) == id) { - CraftInventory left = new CraftInventory((TileEntityChest)world.getHandle().getTileEntity(new BlockPosition(x - 1, y, z))); + CraftInventory left = new CraftInventory((TileEntityChest) world.getHandle().getTileEntity(new BlockPosition(x - 1, y, z))); inventory = new CraftInventoryDoubleChest(left, inventory); } if (world.getBlockTypeIdAt(x + 1, y, z) == id) { @@ -68,20 +75,4 @@ public class CraftChest extends CraftLootable implements Chest { } return inventory; } - - @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); - - if (result) { - chest.update(); - } - - return result; - } - - @Override - public TileEntityChest getTileEntity() { - return chest; - } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java index 9bbc790509..dd5b83cf55 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java @@ -4,58 +4,53 @@ import net.minecraft.server.TileEntityCommand; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.CommandBlock; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftCommandBlock extends CraftBlockState implements CommandBlock { - private final TileEntityCommand commandBlock; +public class CraftCommandBlock extends CraftBlockEntityState implements CommandBlock { + private String command; private String name; public CraftCommandBlock(Block block) { - super(block); - - CraftWorld world = (CraftWorld) block.getWorld(); - commandBlock = (TileEntityCommand) world.getTileEntityAt(getX(), getY(), getZ()); - command = commandBlock.getCommandBlock().getCommand(); - name = commandBlock.getCommandBlock().getName(); + super(block, TileEntityCommand.class); } public CraftCommandBlock(final Material material, final TileEntityCommand te) { - super(material); - commandBlock = te; + super(material, te); + } + + @Override + public void load(TileEntityCommand commandBlock) { + super.load(commandBlock); + command = commandBlock.getCommandBlock().getCommand(); name = commandBlock.getCommandBlock().getName(); } + @Override public String getCommand() { return command; } + @Override public void setCommand(String command) { this.command = command != null ? command : ""; } + @Override public String getName() { return name; } + @Override public void setName(String name) { this.name = name != null ? name : "@"; } - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); - - if (result) { - commandBlock.getCommandBlock().setCommand(command); - commandBlock.getCommandBlock().setName(name); - } - - return result; - } - @Override - public TileEntityCommand getTileEntity() { - return commandBlock; + public void applyTo(TileEntityCommand commandBlock) { + super.applyTo(commandBlock); + + commandBlock.getCommandBlock().setCommand(command); + commandBlock.getCommandBlock().setName(name); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftComparator.java b/src/main/java/org/bukkit/craftbukkit/block/CraftComparator.java index d39e2fcc7f..2e6a738ac7 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftComparator.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftComparator.java @@ -1,33 +1,17 @@ package org.bukkit.craftbukkit.block; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityComparator; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Comparator; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftComparator extends CraftBlockState implements Comparator { - - private final CraftWorld world; - private final TileEntityComparator comparator; +public class CraftComparator extends CraftBlockEntityState implements Comparator { public CraftComparator(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - comparator = (TileEntityComparator) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityComparator.class); } public CraftComparator(final Material material, final TileEntityComparator te) { - super(material); - - comparator = te; - world = null; - } - - @Override - public TileEntity getTileEntity() { - return comparator; + super(material, te); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java index 6aad6663db..06a1d4473a 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java @@ -1,41 +1,33 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.ChestLock; -import net.minecraft.server.ITileInventory; import net.minecraft.server.TileEntityContainer; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.block.Lockable; -import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.block.Container; -public class CraftContainer extends CraftBlockState implements Lockable { +public abstract class CraftContainer extends CraftBlockEntityState implements Container { - private final ITileInventory container; - - public CraftContainer(Block block) { - super(block); - - container = (TileEntityContainer) ((CraftWorld) block.getWorld()).getTileEntityAt(block.getX(), block.getY(), block.getZ()); + public CraftContainer(Block block, Class tileEntityClass) { + super(block, tileEntityClass); } - public CraftContainer(final Material material, ITileInventory tileEntity) { - super(material); - - container = tileEntity; + public CraftContainer(final Material material, T tileEntity) { + super(material, tileEntity); } @Override public boolean isLocked() { - return container.isLocked(); + return this.getSnapshot().isLocked(); } @Override public String getLock() { - return container.getLock().getKey(); + return this.getSnapshot().getLock().getKey(); } @Override public void setLock(String key) { - container.setLock(key == null ? ChestLock.a : new ChestLock(key)); + this.getSnapshot().setLock(key == null ? ChestLock.a : new ChestLock(key)); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java index 1596b9cc39..67f4c73036 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java @@ -6,40 +6,39 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.CreatureSpawner; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.EntityType; -public class CraftCreatureSpawner extends CraftBlockState implements CreatureSpawner { - private final TileEntityMobSpawner spawner; +public class CraftCreatureSpawner extends CraftBlockEntityState implements CreatureSpawner { public CraftCreatureSpawner(final Block block) { - super(block); - - spawner = (TileEntityMobSpawner) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityMobSpawner.class); } public CraftCreatureSpawner(final Material material, TileEntityMobSpawner te) { - super(material); - spawner = te; + super(material, te); } + @Override public EntityType getSpawnedType() { - MinecraftKey key = spawner.getSpawner().getMobName(); + MinecraftKey key = this.getSnapshot().getSpawner().getMobName(); return (key == null) ? EntityType.PIG : EntityType.fromName(key.getKey()); } + @Override public void setSpawnedType(EntityType entityType) { if (entityType == null || entityType.getName() == null) { throw new IllegalArgumentException("Can't spawn EntityType " + entityType + " from mobspawners!"); } - spawner.getSpawner().setMobName(new MinecraftKey(entityType.getName())); + this.getSnapshot().getSpawner().setMobName(new MinecraftKey(entityType.getName())); } + @Override public String getCreatureTypeName() { - return spawner.getSpawner().getMobName().getKey(); + return this.getSnapshot().getSpawner().getMobName().getKey(); } + @Override public void setCreatureTypeByName(String creatureType) { // Verify input EntityType type = EntityType.fromName(creatureType); @@ -49,16 +48,13 @@ public class CraftCreatureSpawner extends CraftBlockState implements CreatureSpa setSpawnedType(type); } + @Override public int getDelay() { - return spawner.getSpawner().spawnDelay; - } - - public void setDelay(int delay) { - spawner.getSpawner().spawnDelay = delay; + return this.getSnapshot().getSpawner().spawnDelay; } @Override - public TileEntityMobSpawner getTileEntity() { - return spawner; + public void setDelay(int delay) { + this.getSnapshot().getSpawner().spawnDelay = delay; } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDaylightDetector.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDaylightDetector.java index 039df2fd9c..1c9b84c69c 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftDaylightDetector.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDaylightDetector.java @@ -1,33 +1,17 @@ package org.bukkit.craftbukkit.block; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityLightDetector; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.DaylightDetector; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftDaylightDetector extends CraftBlockState implements DaylightDetector { - - private final CraftWorld world; - private final TileEntityLightDetector detector; +public class CraftDaylightDetector extends CraftBlockEntityState implements DaylightDetector { public CraftDaylightDetector(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - detector = (TileEntityLightDetector) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityLightDetector.class); } public CraftDaylightDetector(final Material material, final TileEntityLightDetector te) { - super(material); - - detector = te; - world = null; - } - - @Override - public TileEntity getTileEntity() { - return detector; + super(material, te); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java index cc0d28f217..1dc8bfecd2 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java @@ -14,27 +14,31 @@ import org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource; import org.bukkit.inventory.Inventory; import org.bukkit.projectiles.BlockProjectileSource; -public class CraftDispenser extends CraftLootable implements Dispenser { - private final CraftWorld world; - private final TileEntityDispenser dispenser; +public class CraftDispenser extends CraftLootable implements Dispenser { public CraftDispenser(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - dispenser = (TileEntityDispenser) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityDispenser.class); } public CraftDispenser(final Material material, final TileEntityDispenser te) { super(material, te); - world = null; - dispenser = te; } + @Override + public Inventory getSnapshotInventory() { + return new CraftInventory(this.getSnapshot()); + } + + @Override public Inventory getInventory() { - return new CraftInventory(dispenser); + if (!this.isPlaced()) { + return this.getSnapshotInventory(); + } + + return new CraftInventory(this.getTileEntity()); } + @Override public BlockProjectileSource getBlockProjectileSource() { Block block = getBlock(); @@ -42,13 +46,15 @@ public class CraftDispenser extends CraftLootable implements Dispenser { return null; } - return new CraftBlockProjectileSource(dispenser); + return new CraftBlockProjectileSource((TileEntityDispenser) this.getTileEntityFromWorld()); } + @Override public boolean dispense() { Block block = getBlock(); if (block.getType() == Material.DISPENSER) { + CraftWorld world = (CraftWorld) this.getWorld(); BlockDispenser dispense = (BlockDispenser) Blocks.DISPENSER; dispense.dispense(world.getHandle(), new BlockPosition(getX(), getY(), getZ())); @@ -57,20 +63,4 @@ public class CraftDispenser extends CraftLootable implements Dispenser { return false; } } - - @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); - - if (result) { - dispenser.update(); - } - - return result; - } - - @Override - public TileEntityDispenser getTileEntity() { - return dispenser; - } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java index 8786d049e7..27f6e66ec8 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java @@ -12,50 +12,39 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.inventory.Inventory; -public class CraftDropper extends CraftLootable implements Dropper { - private final CraftWorld world; - private final TileEntityDropper dropper; +public class CraftDropper extends CraftLootable implements Dropper { public CraftDropper(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - dropper = (TileEntityDropper) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityDropper.class); } public CraftDropper(final Material material, TileEntityDropper te) { super(material, te); - world = null; - dropper = te; } + @Override + public Inventory getSnapshotInventory() { + return new CraftInventory(this.getSnapshot()); + } + + @Override public Inventory getInventory() { - return new CraftInventory(dropper); + if (!this.isPlaced()) { + return this.getSnapshotInventory(); + } + + return new CraftInventory(this.getTileEntity()); } + @Override public void drop() { Block block = getBlock(); if (block.getType() == Material.DROPPER) { + CraftWorld world = (CraftWorld) this.getWorld(); BlockDropper drop = (BlockDropper) Blocks.DROPPER; drop.dispense(world.getHandle(), new BlockPosition(getX(), getY(), getZ())); } } - - @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); - - if (result) { - dropper.update(); - } - - return result; - } - - @Override - public TileEntityDropper getTileEntity() { - return dropper; - } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftEnchantingTable.java b/src/main/java/org/bukkit/craftbukkit/block/CraftEnchantingTable.java index e20bb4983f..c5a1326d45 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftEnchantingTable.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftEnchantingTable.java @@ -1,43 +1,28 @@ package org.bukkit.craftbukkit.block; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityEnchantTable; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.block.EnchantingTable; -public class CraftEnchantingTable extends CraftBlockState implements EnchantingTable { - - private final CraftWorld world; - private final TileEntityEnchantTable enchant; +public class CraftEnchantingTable extends CraftBlockEntityState implements EnchantingTable { public CraftEnchantingTable(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - enchant = (TileEntityEnchantTable) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityEnchantTable.class); } public CraftEnchantingTable(final Material material, final TileEntityEnchantTable te) { - super(material); - - enchant = te; - world = null; - } - - @Override - public TileEntity getTileEntity() { - return enchant; + super(material, te); } @Override public String getCustomName() { + TileEntityEnchantTable enchant = this.getSnapshot(); return enchant.hasCustomName() ? enchant.getName() : null; } @Override public void setCustomName(String name) { - enchant.setCustomName(name); + this.getSnapshot().setCustomName(name); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftEndGateway.java b/src/main/java/org/bukkit/craftbukkit/block/CraftEndGateway.java index 45f222122a..6deb17d3c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftEndGateway.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftEndGateway.java @@ -6,66 +6,41 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.EndGateway; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftEndGateway extends CraftBlockState implements EndGateway { - - private final CraftWorld world; - private final TileEntityEndGateway gateway; +public class CraftEndGateway extends CraftBlockEntityState implements EndGateway { public CraftEndGateway(Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - gateway = (TileEntityEndGateway) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityEndGateway.class); } public CraftEndGateway(final Material material, TileEntityEndGateway te) { - super(material); - world = null; - this.gateway = te; + super(material, te); } - + @Override public Location getExitLocation() { - BlockPosition pos = gateway.exitPortal; - return pos == null ? null : new Location(world, pos.getX(), pos.getY(), pos.getZ()); + BlockPosition pos = this.getSnapshot().exitPortal; + return pos == null ? null : new Location(this.isPlaced() ? this.getWorld() : null, pos.getX(), pos.getY(), pos.getZ()); } @Override public void setExitLocation(Location location) { if (location == null) { - gateway.exitPortal = null; - } else if (location.getWorld() != world) { + this.getSnapshot().exitPortal = null; + } else if (location.getWorld() != (this.isPlaced() ? this.getWorld() : null)) { throw new IllegalArgumentException("Cannot set exit location to different world"); } else { - gateway.exitPortal = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + this.getSnapshot().exitPortal = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()); } } @Override public boolean isExactTeleport() { - return gateway.exactTeleport; + return this.getSnapshot().exactTeleport; } @Override public void setExactTeleport(boolean exact) { - gateway.exactTeleport = exact; - } - - @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); - - if (result) { - gateway.update(); - } - - return result; - } - - @Override - public TileEntityEndGateway getTileEntity() { - return gateway; + this.getSnapshot().exactTeleport = exact; } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java index 9c4b553a80..2004ee2f3a 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java @@ -1,33 +1,17 @@ package org.bukkit.craftbukkit.block; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityEnderChest; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.EnderChest; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftEnderChest extends CraftBlockState implements EnderChest { - - private final CraftWorld world; - private final TileEntityEnderChest chest; +public class CraftEnderChest extends CraftBlockEntityState implements EnderChest { public CraftEnderChest(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - chest = (TileEntityEnderChest) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityEnderChest.class); } public CraftEnderChest(final Material material, final TileEntityEnderChest te) { - super(material); - - chest = te; - world = null; - } - - @Override - public TileEntity getTileEntity() { - return chest; + super(material, te); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFlowerPot.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFlowerPot.java index e6a5bc1ad0..c9097ac84b 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftFlowerPot.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFlowerPot.java @@ -1,37 +1,30 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.ItemStack; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityFlowerPot; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.FlowerPot; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.material.MaterialData; -public class CraftFlowerPot extends CraftBlockState implements FlowerPot { +public class CraftFlowerPot extends CraftBlockEntityState implements FlowerPot { - private final TileEntityFlowerPot pot; private MaterialData contents; public CraftFlowerPot(Block block) { - super(block); - - pot = (TileEntityFlowerPot) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); - contents = (pot.getItem() == null) ? null : CraftItemStack.asBukkitCopy(pot.getContents()).getData(); + super(block, TileEntityFlowerPot.class); } public CraftFlowerPot(Material material, TileEntityFlowerPot te) { - super(material); - - pot = te; - contents = (pot.getItem() == null) ? null : CraftItemStack.asBukkitCopy(pot.getContents()).getData(); + super(material, te); } @Override - public TileEntity getTileEntity() { - return pot; + public void load(TileEntityFlowerPot pot) { + super.load(pot); + + contents = (pot.getItem() == null) ? null : CraftItemStack.asBukkitCopy(pot.getContents()).getData(); } @Override @@ -45,14 +38,9 @@ public class CraftFlowerPot extends CraftBlockState implements FlowerPot { } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public void applyTo(TileEntityFlowerPot pot) { + super.applyTo(pot); - if (result) { - pot.setContents(contents == null ? ItemStack.a : CraftItemStack.asNMSCopy(contents.toItemStack(1))); - pot.update(); - } - - return result; + pot.setContents(contents == null ? ItemStack.a : CraftItemStack.asNMSCopy(contents.toItemStack(1))); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java index 9865ff06b1..fbde4433ea 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java @@ -4,67 +4,61 @@ import net.minecraft.server.TileEntityFurnace; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Furnace; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; import org.bukkit.inventory.FurnaceInventory; -public class CraftFurnace extends CraftContainer implements Furnace { - private final TileEntityFurnace furnace; +public class CraftFurnace extends CraftContainer implements Furnace { public CraftFurnace(final Block block) { - super(block); - - furnace = (TileEntityFurnace) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityFurnace.class); } public CraftFurnace(final Material material, final TileEntityFurnace te) { super(material, te); - furnace = te; - } - - public FurnaceInventory getInventory() { - return new CraftInventoryFurnace(furnace); } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public FurnaceInventory getSnapshotInventory() { + return new CraftInventoryFurnace(this.getSnapshot()); + } - if (result) { - furnace.update(); + @Override + public FurnaceInventory getInventory() { + if (!this.isPlaced()) { + return this.getSnapshotInventory(); } - return result; + return new CraftInventoryFurnace(this.getTileEntity()); } + @Override public short getBurnTime() { - return (short) furnace.getProperty(0); + return (short) this.getSnapshot().getProperty(0); } + @Override public void setBurnTime(short burnTime) { - furnace.setProperty(0, burnTime); + this.getSnapshot().setProperty(0, burnTime); } + @Override public short getCookTime() { - return (short) furnace.getProperty(2); + return (short) this.getSnapshot().getProperty(2); } + @Override public void setCookTime(short cookTime) { - furnace.setProperty(2, cookTime); + this.getSnapshot().setProperty(2, cookTime); } @Override public String getCustomName() { + TileEntityFurnace furnace = this.getSnapshot(); return furnace.hasCustomName() ? furnace.getName() : null; } @Override public void setCustomName(String name) { - furnace.setCustomName(name); - } - - @Override - public TileEntityFurnace getTileEntity() { - return furnace; + this.getSnapshot().setCustomName(name); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java b/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java index b7a04bd847..6566554ab6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java @@ -4,42 +4,30 @@ import net.minecraft.server.TileEntityHopper; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Hopper; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.inventory.Inventory; -public class CraftHopper extends CraftLootable implements Hopper { - private final TileEntityHopper hopper; +public class CraftHopper extends CraftLootable implements Hopper { public CraftHopper(final Block block) { - super(block); - - hopper = (TileEntityHopper) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityHopper.class); } public CraftHopper(final Material material, final TileEntityHopper te) { super(material, te); - - hopper = te; - } - - public Inventory getInventory() { - return new CraftInventory(hopper); } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public Inventory getSnapshotInventory() { + return new CraftInventory(this.getSnapshot()); + } - if (result) { - hopper.update(); + @Override + public Inventory getInventory() { + if (!this.isPlaced()) { + return this.getSnapshotInventory(); } - return result; - } - - @Override - public TileEntityHopper getTileEntity() { - return hopper; + return new CraftInventory(this.getTileEntity()); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java index 25365f1189..d259cfb82f 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java @@ -1,7 +1,11 @@ package org.bukkit.craftbukkit.block; -import net.minecraft.server.*; +import net.minecraft.server.BlockJukeBox; import net.minecraft.server.BlockJukeBox.TileEntityRecordPlayer; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.Blocks; +import net.minecraft.server.ItemStack; +import net.minecraft.server.TileEntity; import org.bukkit.Effect; import org.bukkit.Material; import org.bukkit.block.Block; @@ -9,26 +13,41 @@ import org.bukkit.block.Jukebox; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.util.CraftMagicNumbers; -public class CraftJukebox extends CraftBlockState implements Jukebox { - private final CraftWorld world; - private final TileEntityRecordPlayer jukebox; +public class CraftJukebox extends CraftBlockEntityState implements Jukebox { public CraftJukebox(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - jukebox = (TileEntityRecordPlayer) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityRecordPlayer.class); } public CraftJukebox(final Material material, TileEntityRecordPlayer te) { - super(material); - world = null; - jukebox = te; + super(material, te); + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result && this.isPlaced() && this.getType() == Material.JUKEBOX) { + CraftWorld world = (CraftWorld) this.getWorld(); + Material record = this.getPlaying(); + if (record == Material.AIR) { + world.getHandle().setTypeAndData(new BlockPosition(this.getX(), this.getY(), this.getZ()), + Blocks.JUKEBOX.getBlockData() + .set(BlockJukeBox.HAS_RECORD, false), 3); + } else { + world.getHandle().setTypeAndData(new BlockPosition(this.getX(), this.getY(), this.getZ()), + Blocks.JUKEBOX.getBlockData() + .set(BlockJukeBox.HAS_RECORD, true), 3); + } + world.playEffect(this.getLocation(), Effect.RECORD_PLAY, record.getId()); + } + + return result; } @Override public Material getPlaying() { - ItemStack record = jukebox.getRecord(); + ItemStack record = this.getSnapshot().getRecord(); if (record.isEmpty()) { return Material.AIR; } @@ -41,38 +60,29 @@ public class CraftJukebox extends CraftBlockState implements Jukebox { record = Material.AIR; } - jukebox.setRecord(new ItemStack(CraftMagicNumbers.getItem(record), 1)); - if (!isPlaced()) { - return; - } - jukebox.update(); + this.getSnapshot().setRecord(new ItemStack(CraftMagicNumbers.getItem(record), 1)); if (record == Material.AIR) { setRawData((byte) 0); - world.getHandle().setTypeAndData(new BlockPosition(getX(), getY(), getZ()), - Blocks.JUKEBOX.getBlockData() - .set(BlockJukeBox.HAS_RECORD, false), 3); } else { setRawData((byte) 1); - world.getHandle().setTypeAndData(new BlockPosition(getX(), getY(), getZ()), - Blocks.JUKEBOX.getBlockData() - .set(BlockJukeBox.HAS_RECORD, true), 3); } - world.playEffect(getLocation(), Effect.RECORD_PLAY, record.getId()); } + @Override public boolean isPlaying() { return getRawData() == 1; } + @Override public boolean eject() { requirePlaced(); - boolean result = isPlaying(); + TileEntity tileEntity = this.getTileEntityFromWorld(); + if (!(tileEntity instanceof TileEntityRecordPlayer)) return false; + + TileEntityRecordPlayer jukebox = (TileEntityRecordPlayer) tileEntity; + boolean result = !jukebox.getRecord().isEmpty(); + CraftWorld world = (CraftWorld) this.getWorld(); ((BlockJukeBox) Blocks.JUKEBOX).dropRecord(world.getHandle(), new BlockPosition(getX(), getY(), getZ()), null); return result; } - - @Override - public TileEntityRecordPlayer getTileEntity() { - return jukebox; - } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java index c75b102417..306a47ba83 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java @@ -4,31 +4,25 @@ import net.minecraft.server.TileEntityLootable; import org.bukkit.Material; import org.bukkit.Nameable; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftLootable extends CraftContainer implements Nameable { +public abstract class CraftLootable extends CraftContainer implements Nameable { - private final TileEntityLootable te; - - public CraftLootable(Block block) { - super(block); - - te = (TileEntityLootable) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + public CraftLootable(Block block, Class tileEntityClass) { + super(block, tileEntityClass); } - public CraftLootable(Material material, TileEntityLootable tileEntity) { + public CraftLootable(Material material, T tileEntity) { super(material, tileEntity); - - te = tileEntity; } @Override public String getCustomName() { - return te.hasCustomName() ? te.getName() : null; + T lootable = this.getSnapshot(); + return lootable.hasCustomName() ? lootable.getName() : null; } @Override public void setCustomName(String name) { - te.setCustomName(name); + this.getSnapshot().setCustomName(name); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java index 0507f3b804..880831d417 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java @@ -11,43 +11,43 @@ import org.bukkit.block.NoteBlock; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.util.CraftMagicNumbers; -public class CraftNoteBlock extends CraftBlockState implements NoteBlock { - private final CraftWorld world; - private final TileEntityNote note; +public class CraftNoteBlock extends CraftBlockEntityState implements NoteBlock { public CraftNoteBlock(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - note = (TileEntityNote) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityNote.class); } public CraftNoteBlock(final Material material, final TileEntityNote te) { - super(material); - world = null; - note = te; + super(material, te); } + @Override public Note getNote() { - return new Note(note.note); + return new Note(this.getSnapshot().note); } + @Override public byte getRawNote() { - return note.note; + return this.getSnapshot().note; } - public void setNote(Note n) { - note.note = n.getId(); + @Override + public void setNote(Note note) { + this.getSnapshot().note = note.getId(); } - public void setRawNote(byte n) { - note.note = n; + @Override + public void setRawNote(byte note) { + this.getSnapshot().note = note; } + @Override public boolean play() { Block block = getBlock(); if (block.getType() == Material.NOTE_BLOCK) { + TileEntityNote note = (TileEntityNote) this.getTileEntityFromWorld(); + CraftWorld world = (CraftWorld) this.getWorld(); note.play(world.getHandle(), new BlockPosition(getX(), getY(), getZ())); return true; } else { @@ -60,6 +60,7 @@ public class CraftNoteBlock extends CraftBlockState implements NoteBlock { Block block = getBlock(); if (block.getType() == Material.NOTE_BLOCK) { + CraftWorld world = (CraftWorld) this.getWorld(); world.getHandle().playBlockAction(new BlockPosition(getX(), getY(), getZ()), CraftMagicNumbers.getBlock(block), instrument, note); return true; } else { @@ -72,15 +73,11 @@ public class CraftNoteBlock extends CraftBlockState implements NoteBlock { Block block = getBlock(); if (block.getType() == Material.NOTE_BLOCK) { + CraftWorld world = (CraftWorld) this.getWorld(); world.getHandle().playBlockAction(new BlockPosition(getX(), getY(), getZ()), CraftMagicNumbers.getBlock(block), instrument.getType(), note.getId()); return true; } else { return false; } } - - @Override - public TileEntityNote getTileEntity() { - return note; - } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java index 788c602631..c029a12441 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java @@ -1,47 +1,43 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.BlockShulkerBox; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityShulkerBox; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.ShulkerBox; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.Inventory; -public class CraftShulkerBox extends CraftLootable implements ShulkerBox { - - private final CraftWorld world; - private final TileEntityShulkerBox box; +public class CraftShulkerBox extends CraftLootable implements ShulkerBox { public CraftShulkerBox(final Block block) { - super(block); - - world = (CraftWorld) block.getWorld(); - box = (TileEntityShulkerBox) world.getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityShulkerBox.class); } public CraftShulkerBox(final Material material, final TileEntityShulkerBox te) { super(material, te); - - box = te; - world = null; } @Override - public TileEntity getTileEntity() { - return box; + public Inventory getSnapshotInventory() { + return new CraftInventory(this.getSnapshot()); } @Override public Inventory getInventory() { - return new CraftInventory(box); + if (!this.isPlaced()) { + return this.getSnapshotInventory(); + } + + return new CraftInventory(this.getTileEntity()); } @Override public DyeColor getColor() { - return DyeColor.getByWoolData((byte) ((BlockShulkerBox) box.getBlock()).color.getColorIndex()); + net.minecraft.server.Block block = CraftMagicNumbers.getBlock(this.getType()); + + return DyeColor.getByWoolData((byte) ((BlockShulkerBox) block).color.getColorIndex()); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java index 42a6f9a7db..7a8d445299 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java @@ -6,52 +6,49 @@ import net.minecraft.server.TileEntitySign; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Sign; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.util.CraftChatMessage; -public class CraftSign extends CraftBlockState implements Sign { - private final TileEntitySign sign; - private final String[] lines; +public class CraftSign extends CraftBlockEntityState implements Sign { + + private String[] lines; public CraftSign(final Block block) { - super(block); - - CraftWorld world = (CraftWorld) block.getWorld(); - sign = (TileEntitySign) world.getTileEntityAt(getX(), getY(), getZ()); - lines = new String[sign.lines.length]; - System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length); + super(block, TileEntitySign.class); } public CraftSign(final Material material, final TileEntitySign te) { - super(material); - sign = te; + super(material, te); + } + + @Override + public void load(TileEntitySign sign) { + super.load(sign); + lines = new String[sign.lines.length]; System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length); } + @Override public String[] getLines() { return lines; } + @Override public String getLine(int index) throws IndexOutOfBoundsException { return lines[index]; } + @Override public void setLine(int index, String line) throws IndexOutOfBoundsException { lines[index] = line; } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public void applyTo(TileEntitySign sign) { + super.applyTo(sign); - if (result) { - IChatBaseComponent[] newLines = sanitizeLines(lines); - System.arraycopy(newLines, 0, sign.lines, 0, 4); - sign.update(); - } - - return result; + IChatBaseComponent[] newLines = sanitizeLines(lines); + System.arraycopy(newLines, 0, sign.lines, 0, 4); } public static IChatBaseComponent[] sanitizeLines(String[] lines) { @@ -79,9 +76,4 @@ public class CraftSign extends CraftBlockState implements Sign { private static String revertComponent(IChatBaseComponent component) { return CraftChatMessage.fromComponent(component); } - - @Override - public TileEntitySign getTileEntity() { - return sign; - } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java index 89e4e72570..f2865688a5 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java @@ -12,28 +12,26 @@ import org.bukkit.SkullType; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Skull; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftSkull extends CraftBlockState implements Skull { +public class CraftSkull extends CraftBlockEntityState implements Skull { + private static final int MAX_OWNER_LENGTH = 16; - private final TileEntitySkull skull; private GameProfile profile; private SkullType skullType; private byte rotation; public CraftSkull(final Block block) { - super(block); - - CraftWorld world = (CraftWorld) block.getWorld(); - skull = (TileEntitySkull) world.getTileEntityAt(getX(), getY(), getZ()); - profile = skull.getGameProfile(); - skullType = getSkullType(skull.getSkullType()); - rotation = (byte) skull.rotation; + super(block, TileEntitySkull.class); } public CraftSkull(final Material material, final TileEntitySkull te) { - super(material); - skull = te; + super(material, te); + } + + @Override + public void load(TileEntitySkull skull) { + super.load(skull); + profile = skull.getGameProfile(); skullType = getSkullType(skull.getSkullType()); rotation = (byte) skull.rotation; @@ -153,14 +151,17 @@ public class CraftSkull extends CraftBlockState implements Skull { } } + @Override public boolean hasOwner() { return profile != null; } + @Override public String getOwner() { return hasOwner() ? profile.getName() : null; } + @Override public boolean setOwner(String name) { if (name == null || name.length() > MAX_OWNER_LENGTH) { return false; @@ -205,18 +206,22 @@ public class CraftSkull extends CraftBlockState implements Skull { this.profile = new GameProfile(player.getUniqueId(), player.getName()); } + @Override public BlockFace getRotation() { - return getBlockFace(rotation); + return getBlockFace(rotation); } + @Override public void setRotation(BlockFace rotation) { this.rotation = getBlockFace(rotation); } + @Override public SkullType getSkullType() { return skullType; } + @Override public void setSkullType(SkullType skullType) { this.skullType = skullType; @@ -226,25 +231,15 @@ public class CraftSkull extends CraftBlockState implements Skull { } @Override - public boolean update(boolean force, boolean applyPhysics) { - boolean result = super.update(force, applyPhysics); + public void applyTo(TileEntitySkull skull) { + super.applyTo(skull); - if (result) { - if (skullType == SkullType.PLAYER) { - skull.setGameProfile(profile); - } else { - skull.setSkullType(getSkullType(skullType)); - } - - skull.setRotation(rotation); - skull.update(); + if (skullType == SkullType.PLAYER) { + skull.setGameProfile(profile); + } else { + skull.setSkullType(getSkullType(skullType)); } - return result; - } - - @Override - public TileEntitySkull getTileEntity() { - return skull; + skull.setRotation(rotation); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java index 36520729d8..ecf12ee380 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java @@ -1,29 +1,16 @@ package org.bukkit.craftbukkit.block; -import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityStructure; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.CraftWorld; -public class CraftStructureBlock extends CraftBlockState { - - private final TileEntityStructure structure; +public class CraftStructureBlock extends CraftBlockEntityState { public CraftStructureBlock(Block block) { - super(block); - - this.structure = (TileEntityStructure) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + super(block, TileEntityStructure.class); } public CraftStructureBlock(Material material, TileEntityStructure structure) { - super(material); - - this.structure = structure; - } - - @Override - public TileEntity getTileEntity() { - return structure; + super(material, structure); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java index 03d0f5c3c1..fe874e0da1 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -34,7 +34,7 @@ import org.bukkit.block.BlockState; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.block.CraftBanner; import org.bukkit.craftbukkit.block.CraftBeacon; -import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.block.CraftBlockEntityState; import org.bukkit.craftbukkit.block.CraftBrewingStand; import org.bukkit.craftbukkit.block.CraftChest; import org.bukkit.craftbukkit.block.CraftCommandBlock; @@ -384,7 +384,6 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta } return new CraftComparator(material, (TileEntityComparator) te); case PISTON_BASE: - default: throw new IllegalStateException("Missing blockState for " + material); } @@ -393,70 +392,68 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta @Override public void setBlockState(BlockState blockState) { Validate.notNull(blockState, "blockState must not be null"); - TileEntity te = ((CraftBlockState) blockState).getTileEntity(); - Validate.notNull(te, "Invalid tile for " + blockState); boolean valid; switch (material) { case SIGN: case SIGN_POST: case WALL_SIGN: - valid = te instanceof TileEntitySign; + valid = blockState instanceof CraftSign; break; case CHEST: case TRAPPED_CHEST: - valid = te instanceof TileEntityChest; + valid = blockState instanceof CraftChest; break; case BURNING_FURNACE: case FURNACE: - valid = te instanceof TileEntityFurnace; + valid = blockState instanceof CraftFurnace; break; case DISPENSER: - valid = te instanceof TileEntityDispenser; + valid = blockState instanceof CraftDispenser; break; case DROPPER: - valid = te instanceof TileEntityDropper; + valid = blockState instanceof CraftDropper; break; case END_GATEWAY: - valid = te instanceof TileEntityEndGateway; + valid = blockState instanceof CraftEndGateway; break; case HOPPER: - valid = te instanceof TileEntityHopper; + valid = blockState instanceof CraftHopper; break; case MOB_SPAWNER: - valid = te instanceof TileEntityMobSpawner; + valid = blockState instanceof CraftCreatureSpawner; break; case NOTE_BLOCK: - valid = te instanceof TileEntityNote; + valid = blockState instanceof CraftNoteBlock; break; case JUKEBOX: - valid = te instanceof BlockJukeBox.TileEntityRecordPlayer; + valid = blockState instanceof CraftJukebox; break; case BREWING_STAND_ITEM: - valid = te instanceof TileEntityBrewingStand; + valid = blockState instanceof CraftBrewingStand; break; case SKULL: - valid = te instanceof TileEntitySkull; + valid = blockState instanceof CraftSkull; break; case COMMAND: case COMMAND_REPEATING: case COMMAND_CHAIN: - valid = te instanceof TileEntityCommand; + valid = blockState instanceof CraftCommandBlock; break; case BEACON: - valid = te instanceof TileEntityBeacon; + valid = blockState instanceof CraftBeacon; break; case SHIELD: case BANNER: case WALL_BANNER: case STANDING_BANNER: - valid = te instanceof TileEntityBanner; + valid = blockState instanceof CraftBanner; break; case FLOWER_POT_ITEM: - valid = te instanceof TileEntityFlowerPot; + valid = blockState instanceof CraftFlowerPot; break; case STRUCTURE_BLOCK: - valid = te instanceof TileEntityStructure; + valid = blockState instanceof CraftStructureBlock; break; case WHITE_SHULKER_BOX: case ORANGE_SHULKER_BOX: @@ -474,20 +471,20 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta case GREEN_SHULKER_BOX: case RED_SHULKER_BOX: case BLACK_SHULKER_BOX: - valid = te instanceof TileEntityShulkerBox; + valid = blockState instanceof CraftShulkerBox; break; case ENCHANTMENT_TABLE: - valid = te instanceof TileEntityEnchantTable; + valid = blockState instanceof CraftEnchantingTable; break; case ENDER_CHEST: - valid = te instanceof TileEntityEnderChest; + valid = blockState instanceof CraftEnderChest; break; case DAYLIGHT_DETECTOR: case DAYLIGHT_DETECTOR_INVERTED: - valid = te instanceof TileEntityLightDetector; + valid = blockState instanceof CraftDaylightDetector; break; case REDSTONE_COMPARATOR: - valid = te instanceof TileEntityComparator; + valid = blockState instanceof CraftComparator; break; default: valid = false; @@ -496,7 +493,6 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta Validate.isTrue(valid, "Invalid blockState for " + material); - blockEntityTag = new NBTTagCompound(); - te.save(blockEntityTag); + blockEntityTag = ((CraftBlockEntityState) blockState).getSnapshotNBT(); } }