diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 3fb36c7de..178b7e432 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -256,6 +256,8 @@ public final class CraftItemFactory implements ItemFactory { return new CraftMetaBlockState(meta, material); case TROPICAL_FISH_BUCKET: return meta instanceof CraftMetaTropicalFishBucket ? meta : new CraftMetaTropicalFishBucket(meta); + case AXOLOTL_BUCKET: + return meta instanceof CraftMetaAxolotlBucket ? meta : new CraftMetaAxolotlBucket(meta); case CROSSBOW: return meta instanceof CraftMetaCrossbow ? meta : new CraftMetaCrossbow(meta); case SUSPICIOUS_STEW: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index a7182e39c..80a661c1f 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -525,6 +525,8 @@ public final class CraftItemStack extends ItemStack { return new CraftMetaBlockState(item.getTag(), CraftMagicNumbers.getMaterial(item.getItem())); case TROPICAL_FISH_BUCKET: return new CraftMetaTropicalFishBucket(item.getTag()); + case AXOLOTL_BUCKET: + return new CraftMetaAxolotlBucket(item.getTag()); case CROSSBOW: return new CraftMetaCrossbow(item.getTag()); case SUSPICIOUS_STEW: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java new file mode 100644 index 000000000..eb2445518 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java @@ -0,0 +1,176 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Axolotl; +import org.bukkit.inventory.meta.AxolotlBucketMeta; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaAxolotlBucket extends CraftMetaItem implements AxolotlBucketMeta { + + static final ItemMetaKey VARIANT = new ItemMetaKey("Variant", "axolotl-variant"); + static final ItemMetaKey ENTITY_TAG = new ItemMetaKey("EntityTag", "entity-tag"); + + private Integer variant; + private NBTTagCompound entityTag; + + CraftMetaAxolotlBucket(CraftMetaItem meta) { + super(meta); + + if (!(meta instanceof CraftMetaAxolotlBucket)) { + return; + } + + CraftMetaAxolotlBucket bucket = (CraftMetaAxolotlBucket) meta; + this.variant = bucket.variant; + this.entityTag = bucket.entityTag; + } + + CraftMetaAxolotlBucket(NBTTagCompound tag) { + super(tag); + + if (tag.hasKeyOfType(VARIANT.NBT, CraftMagicNumbers.NBT.TAG_INT)) { + this.variant = tag.getInt(VARIANT.NBT); + } + + if (tag.hasKey(ENTITY_TAG.NBT)) { + entityTag = tag.getCompound(ENTITY_TAG.NBT); + } + } + + CraftMetaAxolotlBucket(Map map) { + super(map); + + Integer variant = SerializableMeta.getObject(Integer.class, map, VARIANT.BUKKIT, true); + if (variant != null) { + this.variant = variant; + } + } + + @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 (hasVariant()) { + tag.setInt(VARIANT.NBT, variant); + } + + if (entityTag != null) { + tag.set(ENTITY_TAG.NBT, entityTag); + } + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case AXOLOTL_BUCKET: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isBucketEmpty(); + } + + boolean isBucketEmpty() { + return !(hasVariant() || entityTag != null); + } + + @Override + public Axolotl.Variant getVariant() { + return Axolotl.Variant.values()[variant]; + } + + @Override + public void setVariant(Axolotl.Variant variant) { + if (variant == null) { + variant = Axolotl.Variant.LUCY; + } + this.variant = variant.ordinal(); + } + + @Override + public boolean hasVariant() { + return variant != null; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaAxolotlBucket) { + CraftMetaAxolotlBucket that = (CraftMetaAxolotlBucket) meta; + + return (hasVariant() ? that.hasVariant() && this.variant.equals(that.variant) : !that.hasVariant()) + && (entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : that.entityTag == null); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaAxolotlBucket || isBucketEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + if (hasVariant()) { + hash = 61 * hash + variant; + } + if (entityTag != null) { + hash = 61 * hash + entityTag.hashCode(); + } + + return original != hash ? CraftMetaAxolotlBucket.class.hashCode() ^ hash : hash; + } + + @Override + public CraftMetaAxolotlBucket clone() { + CraftMetaAxolotlBucket clone = (CraftMetaAxolotlBucket) super.clone(); + + if (entityTag != null) { + clone.entityTag = entityTag.clone(); + } + + return clone; + } + + @Override + ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + super.serialize(builder); + + if (hasVariant()) { + builder.put(VARIANT.BUKKIT, variant); + } + + return builder; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index f5172e113..59973554c 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -152,6 +152,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { .put(CraftMetaCharge.class, "FIREWORK_EFFECT") .put(CraftMetaKnowledgeBook.class, "KNOWLEDGE_BOOK") .put(CraftMetaTropicalFishBucket.class, "TROPICAL_FISH_BUCKET") + .put(CraftMetaAxolotlBucket.class, "AXOLOTL_BUCKET") .put(CraftMetaCrossbow.class, "CROSSBOW") .put(CraftMetaSuspiciousStew.class, "SUSPICIOUS_STEW") .put(CraftMetaEntityTag.class, "ENTITY_TAG") @@ -1402,6 +1403,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT, CraftMetaKnowledgeBook.BOOK_RECIPES.NBT, CraftMetaTropicalFishBucket.VARIANT.NBT, + CraftMetaAxolotlBucket.VARIANT.NBT, CraftMetaCrossbow.CHARGED.NBT, CraftMetaCrossbow.CHARGED_PROJECTILES.NBT, CraftMetaSuspiciousStew.EFFECTS.NBT, diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java index b813d2d7c..e20638196 100644 --- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java +++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java @@ -30,8 +30,10 @@ import org.bukkit.craftbukkit.inventory.ItemStackTest.CraftWrapper; import org.bukkit.craftbukkit.inventory.ItemStackTest.StackProvider; import org.bukkit.craftbukkit.inventory.ItemStackTest.StackWrapper; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Axolotl; import org.bukkit.entity.TropicalFish; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.AxolotlBucketMeta; import org.bukkit.inventory.meta.BannerMeta; import org.bukkit.inventory.meta.BlockDataMeta; import org.bukkit.inventory.meta.BlockStateMeta; @@ -301,6 +303,14 @@ public class ItemMetaTest extends AbstractTestingBase { return cleanStack; } }, + new StackProvider(Material.AXOLOTL_BUCKET) { + @Override ItemStack operate(ItemStack cleanStack) { + final AxolotlBucketMeta meta = (AxolotlBucketMeta) cleanStack.getItemMeta(); + meta.setVariant(Axolotl.Variant.BLUE); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, new StackProvider(Material.CROSSBOW) { @Override ItemStack operate(ItemStack cleanStack) { final CrossbowMeta meta = (CrossbowMeta) cleanStack.getItemMeta();