diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java index 5a76958d86..f233b7ab36 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java @@ -6,6 +6,7 @@ import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagList; import net.minecraft.server.TileEntityBanner; import org.bukkit.DyeColor; +import org.bukkit.Material; import org.bukkit.block.Banner; import org.bukkit.block.Block; import org.bukkit.block.banner.Pattern; @@ -34,6 +35,20 @@ public class CraftBanner extends CraftBlockState implements Banner { } } + public CraftBanner(final Material material, final TileEntityBanner te) { + super(material); + banner = te; + + base = DyeColor.getByDyeData((byte) banner.color); + + 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")))); + } + } + } + @Override public DyeColor getBaseColor() { return this.base; diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java index fc9846392a..632b22d0c0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.TileEntityBeacon; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Beacon; @@ -19,6 +20,12 @@ public class CraftBeacon extends CraftBlockState implements Beacon { beacon = (TileEntityBeacon) world.getTileEntityAt(getX(), getY(), getZ()); } + public CraftBeacon(final Material material, final TileEntityBeacon te) { + super(material); + world = null; + beacon = te; + } + public Inventory getInventory() { return new CraftInventoryBeacon(beacon); } @@ -33,5 +40,10 @@ public class CraftBeacon extends CraftBlockState implements Beacon { return result; } + + @Override + public TileEntityBeacon getTileEntity() { + return beacon; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java index bf6841c93e..4a8c8141b0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -14,6 +14,7 @@ import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import java.util.List; +import net.minecraft.server.TileEntity; public class CraftBlockState implements BlockState { private final CraftWorld world; @@ -44,6 +45,14 @@ public class CraftBlockState implements BlockState { this.flag = flag; } + public CraftBlockState(Material material) { + world = null; + type = material.getId(); + light = 0; + chunk = null; + x = y = z = 0; + } + public static CraftBlockState getBlockState(net.minecraft.server.World world, int x, int y, int z) { return new CraftBlockState(world.getWorld().getBlockAt(x, y, z)); } @@ -53,6 +62,7 @@ public class CraftBlockState implements BlockState { } public World getWorld() { + requirePlaced(); return world; } @@ -69,6 +79,7 @@ public class CraftBlockState implements BlockState { } public Chunk getChunk() { + requirePlaced(); return chunk; } @@ -125,6 +136,7 @@ public class CraftBlockState implements BlockState { } public Block getBlock() { + requirePlaced(); return world.getBlockAt(x, y, z); } @@ -137,6 +149,7 @@ public class CraftBlockState implements BlockState { } public boolean update(boolean force, boolean applyPhysics) { + requirePlaced(); Block block = getBlock(); if (block.getType() != getType()) { @@ -227,19 +240,38 @@ 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); } public List getMetadata(String metadataKey) { + requirePlaced(); return chunk.getCraftWorld().getBlockMetadata().getMetadata(getBlock(), metadataKey); } public boolean hasMetadata(String metadataKey) { + requirePlaced(); return chunk.getCraftWorld().getBlockMetadata().hasMetadata(getBlock(), metadataKey); } public void removeMetadata(String metadataKey, Plugin owningPlugin) { + requirePlaced(); chunk.getCraftWorld().getBlockMetadata().removeMetadata(getBlock(), metadataKey, owningPlugin); } + + @Override + public boolean isPlaced() { + return world != null; + } + + protected void requirePlaced() { + if (!isPlaced()) { + throw new IllegalStateException("The blockState must be placed to call this method"); + } + } } \ No newline at end of file diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java index d306c3afe1..a910da2be1 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.TileEntityBrewingStand; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BrewingStand; import org.bukkit.craftbukkit.CraftWorld; @@ -16,6 +17,11 @@ public class CraftBrewingStand extends CraftBlockState implements BrewingStand { brewingStand = (TileEntityBrewingStand) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); } + public CraftBrewingStand(final Material material, final TileEntityBrewingStand te) { + super(material); + brewingStand = te; + } + public BrewerInventory getInventory() { return new CraftInventoryBrewer(brewingStand); } @@ -38,4 +44,9 @@ public class CraftBrewingStand extends CraftBlockState implements BrewingStand { public void setBrewingTime(int brewTime) { brewingStand.brewTime = brewTime; } + + @Override + public TileEntityBrewingStand getTileEntity() { + return brewingStand; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java index 0e5c240412..ce36ee4a39 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java @@ -22,6 +22,12 @@ public class CraftChest extends CraftBlockState implements Chest { chest = (TileEntityChest) world.getTileEntityAt(getX(), getY(), getZ()); } + public CraftChest(final Material material, final TileEntityChest te) { + super(material); + chest = te; + world = null; + } + public Inventory getBlockInventory() { return new CraftInventory(chest); } @@ -32,6 +38,9 @@ public class CraftChest extends CraftBlockState implements Chest { int z = getZ(); // The logic here is basically identical to the logic in BlockChest.interact CraftInventory inventory = new CraftInventory(chest); + if (!isPlaced()) { + return inventory; + } int id; if (world.getBlockTypeIdAt(x, y, z) == Material.CHEST.getId()) { id = Material.CHEST.getId(); @@ -70,4 +79,9 @@ public class CraftChest extends CraftBlockState implements Chest { 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 57af2bc505..9bbc790509 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.TileEntityCommand; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.CommandBlock; import org.bukkit.craftbukkit.CraftWorld; @@ -19,6 +20,13 @@ public class CraftCommandBlock extends CraftBlockState implements CommandBlock { name = commandBlock.getCommandBlock().getName(); } + public CraftCommandBlock(final Material material, final TileEntityCommand te) { + super(material); + commandBlock = te; + command = commandBlock.getCommandBlock().getCommand(); + name = commandBlock.getCommandBlock().getName(); + } + public String getCommand() { return command; } @@ -45,4 +53,9 @@ public class CraftCommandBlock extends CraftBlockState implements CommandBlock { return result; } + + @Override + public TileEntityCommand getTileEntity() { + return commandBlock; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java index fa4c0a9646..697cd91c6a 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.TileEntityMobSpawner; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.CreatureSpawner; @@ -17,6 +18,11 @@ public class CraftCreatureSpawner extends CraftBlockState implements CreatureSpa spawner = (TileEntityMobSpawner) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); } + public CraftCreatureSpawner(final Material material, TileEntityMobSpawner te) { + super(material); + spawner = te; + } + @Deprecated public CreatureType getCreatureType() { return CreatureType.fromName(spawner.getSpawner().getMobName()); @@ -70,4 +76,8 @@ public class CraftCreatureSpawner extends CraftBlockState implements CreatureSpa spawner.getSpawner().spawnDelay = delay; } + @Override + public TileEntityMobSpawner getTileEntity() { + return spawner; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java index ab6e55f408..a3ca3a5f2a 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java @@ -25,6 +25,12 @@ public class CraftDispenser extends CraftBlockState implements Dispenser { dispenser = (TileEntityDispenser) world.getTileEntityAt(getX(), getY(), getZ()); } + public CraftDispenser(final Material material, final TileEntityDispenser te) { + super(material); + world = null; + dispenser = te; + } + public Inventory getInventory() { return new CraftInventory(dispenser); } @@ -62,4 +68,9 @@ public class CraftDispenser extends CraftBlockState implements Dispenser { 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 327f47663c..3f7f536a91 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java @@ -23,6 +23,12 @@ public class CraftDropper extends CraftBlockState implements Dropper { dropper = (TileEntityDropper) world.getTileEntityAt(getX(), getY(), getZ()); } + public CraftDropper(final Material material, TileEntityDropper te) { + super(material); + world = null; + dropper = te; + } + public Inventory getInventory() { return new CraftInventory(dropper); } @@ -47,4 +53,9 @@ public class CraftDropper extends CraftBlockState implements Dropper { return result; } + + @Override + public TileEntityDropper getTileEntity() { + return dropper; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java index 8c548f13cd..e58aabcad9 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.TileEntityFurnace; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Furnace; import org.bukkit.craftbukkit.CraftWorld; @@ -16,6 +17,11 @@ public class CraftFurnace extends CraftBlockState implements Furnace { furnace = (TileEntityFurnace) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); } + public CraftFurnace(final Material material, final TileEntityFurnace te) { + super(material); + furnace = te; + } + public FurnaceInventory getInventory() { return new CraftInventoryFurnace(furnace); } @@ -46,4 +52,9 @@ public class CraftFurnace extends CraftBlockState implements Furnace { public void setCookTime(short cookTime) { furnace.cookTime = cookTime; } + + @Override + public TileEntityFurnace getTileEntity() { + return furnace; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java b/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java index a46c472bd7..db844a3ca0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.TileEntityHopper; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Hopper; import org.bukkit.craftbukkit.CraftWorld; @@ -16,6 +17,12 @@ public class CraftHopper extends CraftBlockState implements Hopper { hopper = (TileEntityHopper) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); } + public CraftHopper(final Material material, final TileEntityHopper te) { + super(material); + + hopper = te; + } + public Inventory getInventory() { return new CraftInventory(hopper); } @@ -30,4 +37,9 @@ public class CraftHopper extends CraftBlockState implements Hopper { return result; } + + @Override + public TileEntityHopper getTileEntity() { + return hopper; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java index 37238c47a3..ebe7a6d0f6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java @@ -20,6 +20,12 @@ public class CraftJukebox extends CraftBlockState implements Jukebox { jukebox = (TileEntityRecordPlayer) world.getTileEntityAt(getX(), getY(), getZ()); } + public CraftJukebox(final Material material, TileEntityRecordPlayer te) { + super(material); + world = null; + jukebox = te; + } + @Override public Material getPlaying() { ItemStack record = jukebox.getRecord(); @@ -37,6 +43,9 @@ public class CraftJukebox extends CraftBlockState implements Jukebox { } else { jukebox.setRecord(new ItemStack(CraftMagicNumbers.getItem(record), 1)); } + if (!isPlaced()) { + return; + } jukebox.update(); if (record == Material.AIR) { world.getHandle().setTypeAndData(new BlockPosition(getX(), getY(), getZ()), @@ -55,8 +64,14 @@ public class CraftJukebox extends CraftBlockState implements Jukebox { } public boolean eject() { + requirePlaced(); boolean result = isPlaying(); ((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/CraftNoteBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java index 79d8e6ddc9..0507f3b804 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java @@ -22,6 +22,12 @@ public class CraftNoteBlock extends CraftBlockState implements NoteBlock { note = (TileEntityNote) world.getTileEntityAt(getX(), getY(), getZ()); } + public CraftNoteBlock(final Material material, final TileEntityNote te) { + super(material); + world = null; + note = te; + } + public Note getNote() { return new Note(note.note); } @@ -72,4 +78,9 @@ public class CraftNoteBlock extends CraftBlockState implements NoteBlock { return false; } } + + @Override + public TileEntityNote getTileEntity() { + return note; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java index 724dbd128d..42a6f9a7db 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.ChatComponentText; import net.minecraft.server.IChatBaseComponent; import net.minecraft.server.TileEntitySign; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.craftbukkit.CraftWorld; @@ -21,6 +22,13 @@ public class CraftSign extends CraftBlockState implements Sign { System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length); } + public CraftSign(final Material material, final TileEntitySign te) { + super(material); + sign = te; + lines = new String[sign.lines.length]; + System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length); + } + public String[] getLines() { return lines; } @@ -71,4 +79,9 @@ 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 b3f5709867..ed454f15c2 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.block; import com.mojang.authlib.GameProfile; import net.minecraft.server.MinecraftServer; import net.minecraft.server.TileEntitySkull; +import org.bukkit.Material; import org.bukkit.SkullType; import org.bukkit.block.Block; @@ -27,6 +28,14 @@ public class CraftSkull extends CraftBlockState implements Skull { rotation = (byte) skull.getRotation(); } + public CraftSkull(final Material material, final TileEntitySkull te) { + super(material); + skull = te; + profile = skull.getGameProfile(); + skullType = getSkullType(skull.getSkullType()); + rotation = (byte) skull.getRotation(); + } + static SkullType getSkullType(int id) { switch (id) { case 0: @@ -202,4 +211,9 @@ public class CraftSkull extends CraftBlockState implements Skull { return result; } + + @Override + public TileEntitySkull getTileEntity() { + return skull; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 0f89623db2..5404ee91a1 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -103,7 +103,7 @@ public final class CraftItemFactory implements ItemFactory { case HOPPER: case REDSTONE_COMPARATOR: case FLOWER_POT_ITEM: - return new CraftMetaTileEntity(meta, material); + return new CraftMetaBlockState(meta, material); default: return new CraftMetaItem(meta); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 3d6017ca03..23f05f4db8 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -367,7 +367,7 @@ public final class CraftItemStack extends ItemStack { case HOPPER: case REDSTONE_COMPARATOR: case FLOWER_POT_ITEM: - return new CraftMetaTileEntity(item.getTag(), CraftMagicNumbers.getMaterial(item.getItem())); + return new CraftMetaBlockState(item.getTag(), CraftMagicNumbers.getMaterial(item.getItem())); default: return new CraftMetaItem(item.getTag()); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java new file mode 100644 index 0000000000..dd2f6532d9 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -0,0 +1,318 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import net.minecraft.server.BlockJukeBox; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.TileEntity; +import net.minecraft.server.TileEntityBanner; +import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBrewingStand; +import net.minecraft.server.TileEntityChest; +import net.minecraft.server.TileEntityCommand; +import net.minecraft.server.TileEntityDispenser; +import net.minecraft.server.TileEntityDropper; +import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.TileEntityMobSpawner; +import net.minecraft.server.TileEntityNote; +import net.minecraft.server.TileEntitySign; +import net.minecraft.server.TileEntitySkull; +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +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.CraftBrewingStand; +import org.bukkit.craftbukkit.block.CraftChest; +import org.bukkit.craftbukkit.block.CraftCommandBlock; +import org.bukkit.craftbukkit.block.CraftCreatureSpawner; +import org.bukkit.craftbukkit.block.CraftDispenser; +import org.bukkit.craftbukkit.block.CraftDropper; +import org.bukkit.craftbukkit.block.CraftFurnace; +import org.bukkit.craftbukkit.block.CraftHopper; +import org.bukkit.craftbukkit.block.CraftJukebox; +import org.bukkit.craftbukkit.block.CraftNoteBlock; +import org.bukkit.craftbukkit.block.CraftSign; +import org.bukkit.craftbukkit.block.CraftSkull; +import org.bukkit.inventory.meta.BlockStateMeta; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta { + + @ItemMetaKey.Specific(ItemMetaKey.Specific.To.NBT) + static final ItemMetaKey BLOCK_ENTITY_TAG = new ItemMetaKey("BlockEntityTag"); + + final Material material; + private NBTTagCompound blockEntityTag; + + CraftMetaBlockState(CraftMetaItem meta, Material material) { + super(meta); + this.material = material; + + if (!(meta instanceof CraftMetaBlockState) + || ((CraftMetaBlockState) meta).material != material + || material == Material.SIGN + || material == Material.COMMAND) { + blockEntityTag = null; + return; + } + + CraftMetaBlockState te = (CraftMetaBlockState) meta; + this.blockEntityTag = te.blockEntityTag; + } + + CraftMetaBlockState(NBTTagCompound tag, Material material) { + super(tag); + this.material = material; + + if (tag.hasKeyOfType(BLOCK_ENTITY_TAG.NBT, 10)) { + blockEntityTag = tag.getCompound(BLOCK_ENTITY_TAG.NBT); + } else { + blockEntityTag = null; + } + } + + CraftMetaBlockState(Map map) { + super(map); + material = Material.AIR; // TODO + + blockEntityTag = null; + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + if (blockEntityTag != null) { + tag.set(BLOCK_ENTITY_TAG.NBT, blockEntityTag); + } + } + + @Override + ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + super.serialize(builder); + return builder; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (blockEntityTag != null) { + hash = 61 * hash + this.blockEntityTag.hashCode(); + } + return original != hash ? CraftMetaBlockState.class.hashCode() ^ hash : hash; + } + + @Override + public boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaBlockState) { + CraftMetaBlockState that = (CraftMetaBlockState) meta; + + return Objects.equal(this.blockEntityTag, that.blockEntityTag); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaBlockState || blockEntityTag == null); + } + + @Override + boolean isEmpty() { + return super.isEmpty() && blockEntityTag == null; + } + + @Override + boolean applicableTo(Material type) { + switch(type){ + case FURNACE: + case CHEST: + case TRAPPED_CHEST: + case JUKEBOX: + case DISPENSER: + case DROPPER: + case SIGN: + case MOB_SPAWNER: + case NOTE_BLOCK: + case PISTON_BASE: + case BREWING_STAND_ITEM: + case ENCHANTMENT_TABLE: + case COMMAND: + case BEACON: + case DAYLIGHT_DETECTOR: + case DAYLIGHT_DETECTOR_INVERTED: + case HOPPER: + case REDSTONE_COMPARATOR: + case FLOWER_POT_ITEM: + return true; + } + return false; + } + + @Override + public boolean hasBlockState() { + return blockEntityTag != null; + } + + @Override + public BlockState getBlockState() { + TileEntity te = blockEntityTag == null ? null : TileEntity.c(blockEntityTag); + + switch (material) { + case SIGN: + case SIGN_POST: + case WALL_SIGN: + if (te == null) { + te = new TileEntitySign(); + } + return new CraftSign(material, (TileEntitySign) te); + case CHEST: + case TRAPPED_CHEST: + if (te == null) { + te = new TileEntityChest(); + } + return new CraftChest(material, (TileEntityChest) te); + case BURNING_FURNACE: + case FURNACE: + if (te == null) { + te = new TileEntityFurnace(); + } + return new CraftFurnace(material, (TileEntityFurnace) te); + case DISPENSER: + if (te == null) { + te = new TileEntityDispenser(); + } + return new CraftDispenser(material, (TileEntityDispenser) te); + case DROPPER: + if (te == null) { + te = new TileEntityDispenser(); + } + return new CraftDropper(material, (TileEntityDropper) te); + case HOPPER: + if (te == null) { + te = new TileEntityHopper(); + } + return new CraftHopper(material, (TileEntityHopper) te); + case MOB_SPAWNER: + if (te == null) { + te = new TileEntityMobSpawner(); + } + return new CraftCreatureSpawner(material, (TileEntityMobSpawner) te); + case NOTE_BLOCK: + if (te == null) { + te = new TileEntityNote(); + } + return new CraftNoteBlock(material, (TileEntityNote) te); + case JUKEBOX: + if (te == null) { + te = new BlockJukeBox.TileEntityRecordPlayer(); + } + return new CraftJukebox(material, (BlockJukeBox.TileEntityRecordPlayer) te); + case BREWING_STAND: + if (te == null) { + te = new TileEntityBrewingStand(); + } + return new CraftBrewingStand(material, (TileEntityBrewingStand) te); + case SKULL: + if (te == null) { + te = new TileEntitySkull(); + } + return new CraftSkull(material, (TileEntitySkull) te); + case COMMAND: + if (te == null) { + te = new TileEntityCommand(); + } + return new CraftCommandBlock(material, (TileEntityCommand) te); + case BEACON: + if (te == null) { + te = new TileEntityBeacon(); + } + return new CraftBeacon(material, (TileEntityBeacon) te); + case BANNER: + case WALL_BANNER: + case STANDING_BANNER: + if (te == null) { + te = new TileEntityBanner(); + } + return new CraftBanner(material, (TileEntityBanner) te); + default: + throw new IllegalStateException("Missing blockState for " + material); + } + } + + @Override + public void setBlockState(BlockState blockState) { + Validate.notNull(blockState, "blockState must not be null"); + TileEntity te = ((CraftBlockState) blockState).getTileEntity(); + Validate.notNull(te, "Invalid blockState"); + + boolean valid; + switch (material) { + case SIGN: + case SIGN_POST: + case WALL_SIGN: + valid = te instanceof TileEntitySign; + break; + case CHEST: + case TRAPPED_CHEST: + valid = te instanceof TileEntityChest; + break; + case BURNING_FURNACE: + case FURNACE: + valid = te instanceof TileEntityFurnace; + break; + case DISPENSER: + valid = te instanceof TileEntityDispenser; + break; + case DROPPER: + valid = te instanceof TileEntityDropper; + break; + case HOPPER: + valid = te instanceof TileEntityHopper; + break; + case MOB_SPAWNER: + valid = te instanceof TileEntityMobSpawner; + break; + case NOTE_BLOCK: + valid = te instanceof TileEntityNote; + break; + case JUKEBOX: + valid = te instanceof BlockJukeBox.TileEntityRecordPlayer; + break; + case BREWING_STAND: + valid = te instanceof TileEntityBrewingStand; + break; + case SKULL: + valid = te instanceof TileEntitySkull; + break; + case COMMAND: + valid = te instanceof TileEntityCommand; + break; + case BEACON: + valid = te instanceof TileEntityBeacon; + break; + case BANNER: + case WALL_BANNER: + case STANDING_BANNER: + valid = te instanceof TileEntityBanner; + break; + default: + valid = false; + break; + } + + Validate.isTrue(valid, "Invalid blockState for " + material); + + blockEntityTag = new NBTTagCompound(); + te.b(blockEntityTag); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index 9e426badb1..40d7fca261 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -41,6 +41,7 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.HashSet; import java.util.Set; +import org.bukkit.block.BlockState; /** * Children must include the following: @@ -103,7 +104,7 @@ class CraftMetaItem implements ItemMeta, Repairable { static { classMap = ImmutableMap., String>builder() .put(CraftMetaBanner.class, "BANNER") - .put(CraftMetaTileEntity.class, "TILE_ENTITY") + .put(CraftMetaBlockState.class, "TILE_ENTITY") .put(CraftMetaBook.class, "BOOK") .put(CraftMetaBookSigned.class, "BOOK_SIGNED") .put(CraftMetaSkull.class, "SKULL") @@ -776,7 +777,7 @@ class CraftMetaItem implements ItemMeta, Repairable { CraftMetaMap.MAP_SCALING.NBT, CraftMetaPotion.POTION_EFFECTS.NBT, CraftMetaSkull.SKULL_OWNER.NBT, - CraftMetaTileEntity.BLOCK_ENTITY_TAG.NBT, + CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT, CraftMetaBook.BOOK_TITLE.NBT, CraftMetaBook.BOOK_AUTHOR.NBT, CraftMetaBook.BOOK_PAGES.NBT, diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTileEntity.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTileEntity.java deleted file mode 100644 index 17b913deed..0000000000 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTileEntity.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.bukkit.craftbukkit.inventory; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableMap; -import java.util.Map; -import net.minecraft.server.NBTTagCompound; -import org.bukkit.Material; -import org.bukkit.configuration.serialization.DelegateDeserialization; - -@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) -public class CraftMetaTileEntity extends CraftMetaItem { - - @ItemMetaKey.Specific(ItemMetaKey.Specific.To.NBT) - static final ItemMetaKey BLOCK_ENTITY_TAG = new ItemMetaKey("BlockEntityTag"); - - final Material material; - private final NBTTagCompound blockEntityTag; - - CraftMetaTileEntity(CraftMetaItem meta, Material material) { - super(meta); - this.material = material; - - if (!(meta instanceof CraftMetaTileEntity) - || ((CraftMetaTileEntity) meta).material != material - || material == Material.SIGN - || material == Material.COMMAND) { - blockEntityTag = null; - return; - } - - CraftMetaTileEntity te = (CraftMetaTileEntity) meta; - this.blockEntityTag = te.blockEntityTag; - } - - CraftMetaTileEntity(NBTTagCompound tag, Material material) { - super(tag); - this.material = material; - - if (tag.hasKeyOfType(BLOCK_ENTITY_TAG.NBT, 10)) { - blockEntityTag = tag.getCompound(BLOCK_ENTITY_TAG.NBT); - } else { - blockEntityTag = null; - } - } - - CraftMetaTileEntity(Map map) { - super(map); - material = Material.AIR; // TODO - - blockEntityTag = null; - } - - @Override - void applyToItem(NBTTagCompound tag) { - super.applyToItem(tag); - - if (blockEntityTag != null) { - tag.set(BLOCK_ENTITY_TAG.NBT, blockEntityTag); - } - } - - @Override - ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { - super.serialize(builder); - return builder; - } - - @Override - int applyHash() { - final int original; - int hash = original = super.applyHash(); - if (blockEntityTag != null) { - hash = 61 * hash + this.blockEntityTag.hashCode(); - } - return original != hash ? CraftMetaTileEntity.class.hashCode() ^ hash : hash; - } - - @Override - public boolean equalsCommon(CraftMetaItem meta) { - if (!super.equalsCommon(meta)) { - return false; - } - if (meta instanceof CraftMetaTileEntity) { - CraftMetaTileEntity that = (CraftMetaTileEntity) meta; - - return Objects.equal(this.blockEntityTag, that.blockEntityTag); - } - return true; - } - - @Override - boolean notUncommon(CraftMetaItem meta) { - return super.notUncommon(meta) && (meta instanceof CraftMetaTileEntity || blockEntityTag == null); - } - - @Override - boolean isEmpty() { - return super.isEmpty() && blockEntityTag == null; - } - - @Override - boolean applicableTo(Material type) { - switch(type){ - case FURNACE: - case CHEST: - case TRAPPED_CHEST: - case JUKEBOX: - case DISPENSER: - case DROPPER: - case SIGN: - case MOB_SPAWNER: - case NOTE_BLOCK: - case PISTON_BASE: - case BREWING_STAND_ITEM: - case ENCHANTMENT_TABLE: - case COMMAND: - case BEACON: - case DAYLIGHT_DETECTOR: - case DAYLIGHT_DETECTOR_INVERTED: - case HOPPER: - case REDSTONE_COMPARATOR: - case FLOWER_POT_ITEM: - return true; - } - return false; - } -}