summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew <stteg@hotmail.com>2016-12-06 21:15:10 +1100
committermd_5 <git@md-5.net>2016-12-06 21:15:34 +1100
commit04202c0ace026b51160ea18dec5434a3263c936d (patch)
treedee96ec01cae992ce2b255fe4a3fbecb07771e7e
parent9dee10873da43e15d870a3d3d621c0e04d205f4c (diff)
downloadcraftbukkit-04202c0ace026b51160ea18dec5434a3263c936d.tar
craftbukkit-04202c0ace026b51160ea18dec5434a3263c936d.tar.gz
craftbukkit-04202c0ace026b51160ea18dec5434a3263c936d.tar.lz
craftbukkit-04202c0ace026b51160ea18dec5434a3263c936d.tar.xz
craftbukkit-04202c0ace026b51160ea18dec5434a3263c936d.zip
SPIGOT-1592: Implement ItemMeta for Spawn Eggs
The Minecraft implementation of spawn eggs is able to construct an entity using all data that is present in the save format, however since the Bukkit API has no such way to construct an entity unattached to a world, and it appears creating such a way is a very challenging task, the decision was instead made to add this API now that 1.11 has entities which may not be represented by data values. In the future it may be possible to implement a more expanded API cognate with this one.
-rw-r--r--src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java2
-rw-r--r--src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java2
-rw-r--r--src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java2
-rw-r--r--src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java148
-rw-r--r--src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java10
5 files changed, 164 insertions, 0 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
index d8078009..a72b179c 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
@@ -91,6 +91,8 @@ public final class CraftItemFactory implements ItemFactory {
return meta instanceof CraftMetaEnchantedBook ? meta : new CraftMetaEnchantedBook(meta);
case BANNER:
return meta instanceof CraftMetaBanner ? meta : new CraftMetaBanner(meta);
+ case MONSTER_EGG:
+ return meta instanceof CraftMetaSpawnEgg ? meta : new CraftMetaSpawnEgg(meta);
case FURNACE:
case CHEST:
case TRAPPED_CHEST:
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
index b6bce942..8ed4b4bd 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
@@ -348,6 +348,8 @@ public final class CraftItemStack extends ItemStack {
return new CraftMetaEnchantedBook(item.getTag());
case BANNER:
return new CraftMetaBanner(item.getTag());
+ case MONSTER_EGG:
+ return new CraftMetaSpawnEgg(item.getTag());
case FURNACE:
case CHEST:
case TRAPPED_CHEST:
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index a169e101..bb764444 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -115,6 +115,7 @@ class CraftMetaItem implements ItemMeta, Repairable {
.put(CraftMetaLeatherArmor.class, "LEATHER_ARMOR")
.put(CraftMetaMap.class, "MAP")
.put(CraftMetaPotion.class, "POTION")
+ .put(CraftMetaSpawnEgg.class, "SPAWN_EGG")
.put(CraftMetaEnchantedBook.class, "ENCHANTED")
.put(CraftMetaFirework.class, "FIREWORK")
.put(CraftMetaCharge.class, "FIREWORK_EFFECT")
@@ -839,6 +840,7 @@ class CraftMetaItem implements ItemMeta, Repairable {
CraftMetaPotion.DEFAULT_POTION.NBT,
CraftMetaSkull.SKULL_OWNER.NBT,
CraftMetaSkull.SKULL_PROFILE.NBT,
+ CraftMetaSpawnEgg.ENTITY_TAG.NBT,
CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT,
CraftMetaBook.BOOK_TITLE.NBT,
CraftMetaBook.BOOK_AUTHOR.NBT,
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
new file mode 100644
index 00000000..fed91832
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
@@ -0,0 +1,148 @@
+package org.bukkit.craftbukkit.inventory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap.Builder;
+import java.util.Map;
+import net.minecraft.server.MinecraftKey;
+import net.minecraft.server.NBTTagCompound;
+import org.bukkit.Material;
+import org.bukkit.configuration.serialization.DelegateDeserialization;
+import org.bukkit.entity.EntityType;
+import org.bukkit.inventory.meta.SpawnEggMeta;
+
+@DelegateDeserialization(CraftMetaItem.SerializableMeta.class)
+public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta {
+
+ static final ItemMetaKey ENTITY_TAG = new ItemMetaKey("EntityTag", "entity-tag");
+ @ItemMetaKey.Specific(ItemMetaKey.Specific.To.NBT)
+ static final ItemMetaKey ENTITY_ID = new ItemMetaKey("id");
+
+ private EntityType spawnedType;
+
+ CraftMetaSpawnEgg(CraftMetaItem meta) {
+ super(meta);
+
+ if (!(meta instanceof CraftMetaSpawnEgg)) {
+ return;
+ }
+
+ CraftMetaSpawnEgg egg = (CraftMetaSpawnEgg) meta;
+ this.spawnedType = egg.spawnedType;
+ }
+
+ CraftMetaSpawnEgg(NBTTagCompound tag) {
+ super(tag);
+
+ if (tag.hasKey(ENTITY_TAG.NBT)) {
+ NBTTagCompound entityTag = tag.getCompound(ENTITY_TAG.NBT);
+
+ if (entityTag.hasKey(ENTITY_ID.NBT)) {
+ this.spawnedType = EntityType.fromName(new MinecraftKey(entityTag.getString(ENTITY_ID.NBT)).a()); // PAIL: rename
+ }
+ }
+ }
+
+ CraftMetaSpawnEgg(Map<String, Object> map) {
+ super(map);
+
+ String entityType = SerializableMeta.getString(map, ENTITY_ID.BUKKIT, true);
+ setSpawnedType(EntityType.fromName(entityType));
+ }
+
+ @Override
+ void applyToItem(NBTTagCompound tag) {
+ super.applyToItem(tag);
+
+ if (hasSpawnedType()) {
+ NBTTagCompound entityTag = new NBTTagCompound();
+ entityTag.setString(ENTITY_ID.NBT, new MinecraftKey(spawnedType.getName()).toString());
+
+ tag.set(ENTITY_TAG.NBT, entityTag);
+ }
+ }
+
+ @Override
+ boolean applicableTo(Material type) {
+ switch (type) {
+ case MONSTER_EGG:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ boolean isEmpty() {
+ return super.isEmpty() && isSpawnEggEmpty();
+ }
+
+ boolean isSpawnEggEmpty() {
+ return !hasSpawnedType();
+ }
+
+ boolean hasSpawnedType() {
+ return spawnedType != null;
+ }
+
+ @Override
+ public EntityType getSpawnedType() {
+ return spawnedType;
+ }
+
+ @Override
+ public void setSpawnedType(EntityType type) {
+ Preconditions.checkArgument(type == null || type.getName() != null, "Spawn egg type must have name (%s)", type);
+
+ this.spawnedType = type;
+ }
+
+ @Override
+ boolean equalsCommon(CraftMetaItem meta) {
+ if (!super.equalsCommon(meta)) {
+ return false;
+ }
+ if (meta instanceof CraftMetaSpawnEgg) {
+ CraftMetaSpawnEgg that = (CraftMetaSpawnEgg) meta;
+
+ return hasSpawnedType() ? that.hasSpawnedType() && this.spawnedType.equals(that.spawnedType) : !that.hasSpawnedType();
+ }
+ return true;
+ }
+
+ @Override
+ boolean notUncommon(CraftMetaItem meta) {
+ return super.notUncommon(meta) && (meta instanceof CraftMetaSpawnEgg || isSpawnEggEmpty());
+ }
+
+ @Override
+ int applyHash() {
+ final int original;
+ int hash = original = super.applyHash();
+
+ if (hasSpawnedType()) {
+ hash = 73 * hash + spawnedType.hashCode();
+ }
+
+ return original != hash ? CraftMetaSpawnEgg.class.hashCode() ^ hash : hash;
+ }
+
+ @Override
+ Builder<String, Object> serialize(Builder<String, Object> builder) {
+ super.serialize(builder);
+
+ if (hasSpawnedType()) {
+ builder.put(ENTITY_ID.BUKKIT, spawnedType.getName());
+ }
+
+ return builder;
+ }
+
+ @Override
+ public CraftMetaSpawnEgg clone() {
+ CraftMetaSpawnEgg clone = (CraftMetaSpawnEgg) super.clone();
+
+ clone.spawnedType = spawnedType;
+
+ return clone;
+ }
+}
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
index 8c479a68..69c21f28 100644
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
@@ -24,6 +24,7 @@ import org.bukkit.craftbukkit.inventory.ItemStackTest.StackWrapper;
import org.bukkit.craftbukkit.inventory.ItemStackTest.BukkitWrapper;
import org.bukkit.craftbukkit.inventory.ItemStackTest.CraftWrapper;
import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta;
import org.bukkit.inventory.meta.BlockStateMeta;
@@ -35,6 +36,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.inventory.meta.PotionMeta;
+import org.bukkit.inventory.meta.SpawnEggMeta;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
@@ -255,6 +257,14 @@ public class ItemMetaTest extends AbstractTestingBase {
cleanStack.setItemMeta(meta);
return cleanStack;
}
+ },
+ new StackProvider(Material.MONSTER_EGG) {
+ @Override ItemStack operate(ItemStack cleanStack) {
+ final SpawnEggMeta meta = (SpawnEggMeta) cleanStack.getItemMeta();
+ meta.setSpawnedType(EntityType.ZOMBIE);
+ cleanStack.setItemMeta(meta);
+ return cleanStack;
+ }
}
);