diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 97a58900ac..9828f50e1b 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -259,6 +259,8 @@ public final class CraftItemFactory implements ItemFactory { return meta instanceof CraftMetaCrossbow ? meta : new CraftMetaCrossbow(meta); case SUSPICIOUS_STEW: return meta instanceof CraftMetaSuspiciousStew ? meta : new CraftMetaSuspiciousStew(meta); + case ITEM_FRAME: + return meta instanceof CraftMetaEntityTag ? meta : new CraftMetaEntityTag(meta); 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 6a797a0ac8..a3c2f1b589 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -528,6 +528,8 @@ public final class CraftItemStack extends ItemStack { return new CraftMetaCrossbow(item.getTag()); case SUSPICIOUS_STEW: return new CraftMetaSuspiciousStew(item.getTag()); + case ITEM_FRAME: + return new CraftMetaEntityTag(item.getTag()); default: return new CraftMetaItem(item.getTag()); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java new file mode 100644 index 0000000000..9af9dc3470 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java @@ -0,0 +1,123 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.collect.ImmutableMap.Builder; +import java.util.Map; +import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTTagCompound; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaEntityTag extends CraftMetaItem { + + static final ItemMetaKey ENTITY_TAG = new ItemMetaKey("EntityTag", "entity-tag"); + NBTTagCompound entityTag; + + CraftMetaEntityTag(CraftMetaItem meta) { + super(meta); + } + + CraftMetaEntityTag(NBTTagCompound tag) { + super(tag); + + if (tag.hasKey(ENTITY_TAG.NBT)) { + entityTag = tag.getCompound(ENTITY_TAG.NBT); + } + } + + CraftMetaEntityTag(Map map) { + super(map); + } + + @Override + void deserializeInternal(NBTTagCompound tag, Object context) { + super.deserializeInternal(tag, context); + + if (tag.hasKey(ENTITY_TAG.NBT)) { + entityTag = tag.getCompound(ENTITY_TAG.NBT); + } + } + + @Override + void serializeInternal(Map internalTags) { + if (entityTag != null && !entityTag.isEmpty()) { + internalTags.put(ENTITY_TAG.NBT, entityTag); + } + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + if (entityTag != null) { + tag.set(ENTITY_TAG.NBT, entityTag); + } + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case ITEM_FRAME: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isEntityTagEmpty(); + } + + boolean isEntityTagEmpty() { + return !(entityTag != null); + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaEntityTag) { + CraftMetaEntityTag that = (CraftMetaEntityTag) meta; + + return entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : entityTag == null; + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaEntityTag || isEntityTagEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + if (entityTag != null) { + hash = 73 * hash + entityTag.hashCode(); + } + + return original != hash ? CraftMetaEntityTag.class.hashCode() ^ hash : hash; + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + return builder; + } + + @Override + public CraftMetaEntityTag clone() { + CraftMetaEntityTag clone = (CraftMetaEntityTag) super.clone(); + + if (entityTag != null) { + clone.entityTag = entityTag.clone(); + } + + return clone; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index 44a28bed0e..6a74d95cb6 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -155,6 +155,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { .put(CraftMetaTropicalFishBucket.class, "TROPICAL_FISH_BUCKET") .put(CraftMetaCrossbow.class, "CROSSBOW") .put(CraftMetaSuspiciousStew.class, "SUSPICIOUS_STEW") + .put(CraftMetaEntityTag.class, "ENTITY_TAG") .put(CraftMetaItem.class, "UNSPECIFIC") .build(); diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java index e4305ce522..7be77ab45c 100644 --- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java +++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java @@ -324,6 +324,15 @@ public class ItemMetaTest extends AbstractTestingBase { cleanStack.setItemMeta(meta); return cleanStack; } + }, + new StackProvider(Material.ITEM_FRAME) { + @Override ItemStack operate(ItemStack cleanStack) { + final CraftMetaEntityTag meta = ((CraftMetaEntityTag) cleanStack.getItemMeta()); + meta.entityTag = new NBTTagCompound(); + meta.entityTag.setBoolean("Invisible", true); + cleanStack.setItemMeta(meta); + return cleanStack; + } } );