summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Hennig <lukas@wirsindwir.de>2017-08-05 14:37:19 +1000
committermd_5 <git@md-5.net>2017-08-05 14:37:19 +1000
commit19507baf8b7903427bc3efab7118de6e7c1c931e (patch)
tree84fc0f5af1af5016ffc032752ae4e4bc43901dfd
parent63029f4ff3745380bedc1d6557b81c1a183d45ec (diff)
downloadcraftbukkit-19507baf8b7903427bc3efab7118de6e7c1c931e.tar
craftbukkit-19507baf8b7903427bc3efab7118de6e7c1c931e.tar.gz
craftbukkit-19507baf8b7903427bc3efab7118de6e7c1c931e.tar.lz
craftbukkit-19507baf8b7903427bc3efab7118de6e7c1c931e.tar.xz
craftbukkit-19507baf8b7903427bc3efab7118de6e7c1c931e.zip
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.
-rw-r--r--nms-patches/TileEntityBrewingStand.patch18
-rw-r--r--nms-patches/TileEntityContainer.patch3
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java58
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java66
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftBed.java32
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java9
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java120
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java7
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java42
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftChest.java55
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java43
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftComparator.java22
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java26
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java32
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftDaylightDetector.java22
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java44
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java41
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftEnchantingTable.java25
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftEndGateway.java47
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java22
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftFlowerPot.java32
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java44
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java30
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java70
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java20
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java39
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java30
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftSign.java44
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java55
-rw-r--r--src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java19
-rw-r--r--src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java52
31 files changed, 524 insertions, 645 deletions
diff --git a/nms-patches/TileEntityBrewingStand.patch b/nms-patches/TileEntityBrewingStand.patch
index 11833f96..fe3d21e3 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 3484ee4f..e49e2ca9 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 7bf72699..f374385e 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<TileEntityBanner> implements Banner {
- private final TileEntityBanner banner;
private DyeColor base;
private List<Pattern> patterns = new ArrayList<Pattern>();
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);
-
- if (result) {
- banner.color = EnumColor.fromInvColorIndex(base.getDyeData());
-
- NBTTagList newPatterns = new NBTTagList();
+ public void applyTo(TileEntityBanner banner) {
+ super.applyTo(banner);
- for (Pattern p : patterns) {
- NBTTagCompound compound = new NBTTagCompound();
- compound.setInt("Color", p.getColor().getDyeData());
- compound.setString("Pattern", p.getPattern().getIdentifier());
- newPatterns.add(compound);
- }
+ banner.color = EnumColor.fromInvColorIndex(base.getDyeData());
- banner.patterns = newPatterns;
+ NBTTagList newPatterns = new NBTTagList();
- 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 a679221a..afec900c 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<TileEntityBeacon> 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 BeaconInventory getSnapshotInventory() {
+ return new CraftInventoryBeacon(this.getSnapshot());
}
@Override
- public boolean update(boolean force, boolean applyPhysics) {
- boolean result = super.update(force, applyPhysics);
-
- if (result) {
- beacon.update();
+ 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<LivingEntity> getEntitiesInRange() {
- Collection<EntityHuman> nms = beacon.getHumansInRange();
- Collection<LivingEntity> bukkit = new ArrayList<LivingEntity>(nms.size());
+ TileEntity tileEntity = this.getTileEntityFromWorld();
+ if (tileEntity instanceof TileEntityBeacon) {
+ TileEntityBeacon beacon = (TileEntityBeacon) tileEntity;
+
+ Collection<EntityHuman> nms = beacon.getHumansInRange();
+ Collection<LivingEntity> bukkit = new ArrayList<LivingEntity>(nms.size());
+
+ for (EntityHuman human : nms) {
+ bukkit.add(human.getBukkitEntity());
+ }
- for (EntityHuman human : nms) {
- bukkit.add(human.getBukkitEntity());
+ return bukkit;
}
- return bukkit;
+ // block is no longer a beacon
+ return new ArrayList<LivingEntity>();
}
@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 f6083565..27756d85 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<TileEntityBed> 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);
-
- if (result) {
- bed.a(EnumColor.fromColorIndex(color.getWoolData()));
- bed.update();
- }
+ public void applyTo(TileEntityBed bed) {
+ super.applyTo(bed);
- 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 a2d63379..ba1cdc18 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<TileEntity>(this, (Class<TileEntity>) 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 00000000..cf94c062
--- /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<T extends TileEntity> extends CraftBlockState {
+
+ private final Class<T> tileEntityClass;
+ private final T tileEntity;
+ private final T snapshot;
+
+ public CraftBlockEntityState(Block block, Class<T> 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<T>) 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 5d83155a..2a1b731c 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 78e8c9c6..4f717f28 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<TileEntityBrewingStand> 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 BrewerInventory getSnapshotInventory() {
+ return new CraftInventoryBrewer(this.getSnapshot());
}
@Override
- public boolean update(boolean force, boolean applyPhysics) {
- boolean result = super.update(force, applyPhysics);
-
- if (result) {
- brewingStand.update();
+ public BrewerInventory getInventory() {
+ if (!this.isPlaced()) {
+ return this.getSnapshotInventory();
}
- return result;
+ return new CraftInventoryBrewer(this.getTileEntity());
}
+ @Override
public int getBrewingTime() {
- return brewingStand.getProperty(0);
- }
-
- public void setBrewingTime(int brewTime) {
- brewingStand.setProperty(0, brewTime);
+ return this.getSnapshot().getProperty(0);
}
@Override
- public TileEntityBrewingStand getTileEntity() {
- return brewingStand;
+ 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 3de7e14d..85f3bb27 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<TileEntityChest> 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 9bbc7905..dd5b83cf 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<TileEntityCommand> 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 d39e2fcc..2e6a738a 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<TileEntityComparator> 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 6aad6663..06a1d447 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<T extends TileEntityContainer> extends CraftBlockEntityState<T> 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<T> 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 1596b9cc..67f4c730 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<TileEntityMobSpawner> 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 039df2fd..1c9b84c6 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<TileEntityLightDetector> 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 cc0d28f2..1dc8bfec 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<TileEntityDispenser> 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 8786d049..27f6e66e 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<TileEntityDropper> 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 e20bb498..c5a1326d 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<TileEntityEnchantTable> 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 45f22212..6deb17d3 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<TileEntityEndGateway> 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 9c4b553a..2004ee2f 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<TileEntityEnderChest> 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 e6a5bc1a..c9097ac8 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<TileEntityFlowerPot> 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);
-
- if (result) {
- pot.setContents(contents == null ? ItemStack.a : CraftItemStack.asNMSCopy(contents.toItemStack(1)));
- pot.update();
- }
+ public void applyTo(TileEntityFlowerPot pot) {
+ super.applyTo(pot);
- 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 9865ff06..fbde4433 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<TileEntityFurnace> 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 FurnaceInventory getSnapshotInventory() {
+ return new CraftInventoryFurnace(this.getSnapshot());
}
@Override
- public boolean update(boolean force, boolean applyPhysics) {
- boolean result = super.update(force, applyPhysics);
-
- if (result) {
- furnace.update();
+ 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 b7a04bd8..6566554a 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<TileEntityHopper> 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 Inventory getSnapshotInventory() {
+ return new CraftInventory(this.getSnapshot());
}
@Override
- public boolean update(boolean force, boolean applyPhysics) {
- boolean result = super.update(force, applyPhysics);
-
- if (result) {
- hopper.update();
+ 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 25365f11..d259cfb8 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<TileEntityRecordPlayer> 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 c75b1024..306a47ba 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<T extends TileEntityLootable> extends CraftContainer<T> 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<T> 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 0507f3b8..880831d4 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<TileEntityNote> 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 788c6026..c029a124 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<TileEntityShulkerBox> 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 42a6f9a7..7a8d4452 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<TileEntitySign> implements Sign {
- public CraftSign(final Block block) {
- super(block);
+ private String[] lines;
- 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);
+ public CraftSign(final Block block) {
+ 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);
-
- if (result) {
- IChatBaseComponent[] newLines = sanitizeLines(lines);
- System.arraycopy(newLines, 0, sign.lines, 0, 4);
- sign.update();
- }
+ public void applyTo(TileEntitySign sign) {
+ super.applyTo(sign);
- 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 89e4e725..f2865688 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<TileEntitySkull> 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);
-
- if (result) {
- if (skullType == SkullType.PLAYER) {
- skull.setGameProfile(profile);
- } else {
- skull.setSkullType(getSkullType(skullType));
- }
+ public void applyTo(TileEntitySkull skull) {
+ super.applyTo(skull);
- 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 36520729..ecf12ee3 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<TileEntityStructure> {
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 03d0f5c3..fe874e0d 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();
}
}