From b90c9ef77025041c193cc7d3b517243193133e51 Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Sun, 27 Nov 2011 00:39:25 +0000 Subject: [PATCH] Implemented Enchantment API By: Nathan Adams --- .../org/bukkit/craftbukkit/CraftServer.java | 6 + .../enchantments/CraftEnchantment.java | 109 ++++++++++++++++++ .../craftbukkit/inventory/CraftItemStack.java | 73 ++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 5a730fd948..4dd155a189 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -35,6 +35,7 @@ import jline.ConsoleReader; import net.minecraft.server.ChunkCoordinates; import net.minecraft.server.ConvertProgressUpdater; import net.minecraft.server.Convertable; +import net.minecraft.server.Enchantment; import net.minecraft.server.EntityPlayer; import net.minecraft.server.EntityTracker; import net.minecraft.server.IProgressUpdate; @@ -105,6 +106,11 @@ public final class CraftServer implements Server { Bukkit.setServer(this); + // Register all the Enchantments now so we can stop new registration immediately after + Enchantment.DAMAGE_ALL.getClass(); + org.bukkit.enchantments.Enchantment.stopAcceptingRegistrations(); + // Ugly hack :( + if (!Main.useConsole) { getLogger().info("Console input is disabled due to --noconsole command argument"); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/paper-server/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java new file mode 100644 index 0000000000..4fc391b467 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java @@ -0,0 +1,109 @@ +package org.bukkit.craftbukkit.enchantments; + +import net.minecraft.server.Item; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.inventory.ItemStack; + +public class CraftEnchantment extends Enchantment { + private final net.minecraft.server.Enchantment target; + + public CraftEnchantment(net.minecraft.server.Enchantment target) { + super(target.id); + this.target = target; + } + + @Override + public int getMaxLevel() { + return target.getMaxLevel(); + } + + @Override + public int getStartLevel() { + return target.getStartLevel(); + } + + @Override + public EnchantmentTarget getItemTarget() { + switch (target.slot) { + case ALL: + return EnchantmentTarget.ALL; + case ARMOR: + return EnchantmentTarget.ARMOR; + case ARMOR_FEET: + return EnchantmentTarget.ARMOR_FEET; + case ARMOR_HEAD: + return EnchantmentTarget.ARMOR_HEAD; + case ARMOR_LEGS: + return EnchantmentTarget.ARMOR_LEGS; + case ARMOR_TORSO: + return EnchantmentTarget.ARMOR_TORSO; + case DIGGER: + return EnchantmentTarget.TOOL; + case WEAPON: + return EnchantmentTarget.WEAPON; + default: + return null; + } + } + + @Override + public boolean canEnchantItem(ItemStack item) { + return target.slot.a(Item.byId[item.getTypeId()]); + } + + @Override + public String getName() { + switch (target.id) { + case 0: + return "PROTECTION_ENVIRONMENTAL"; + case 1: + return "PROTECTION_FIRE"; + case 2: + return "PROTECTION_FALL"; + case 3: + return "PROTECTION_EXPLOSIONS"; + case 4: + return "PROTECTION_PROJECTILE"; + case 5: + return "OXYGEN"; + case 6: + return "WATER_WORKER"; + case 16: + return "DAMAGE_ALL"; + case 17: + return "DAMAGE_UNDEAD"; + case 18: + return "DAMAGE_ARTHROPODS"; + case 19: + return "KNOCKBACK"; + case 20: + return "FIRE_ASPECT"; + case 21: + return "LOOT_BONUS_MOBS"; + case 32: + return "DIG_SPEED"; + case 33: + return "SILK_TOUCH"; + case 34: + return "DURABILITY"; + case 35: + return "LOOT_BONUS_BLOCKS"; + default: + return "UNKNOWN_ENCHANT_" + target.id; + } + } + + public static net.minecraft.server.Enchantment getRaw(Enchantment enchantment) { + if (enchantment instanceof EnchantmentWrapper) { + enchantment = ((EnchantmentWrapper)enchantment).getEnchantment(); + } + + if (enchantment instanceof CraftEnchantment) { + return ((CraftEnchantment)enchantment).target; + } + + return null; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 0c3e853882..1f22ea4871 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -1,5 +1,12 @@ package org.bukkit.craftbukkit.inventory; +import java.util.HashMap; +import java.util.Map; +import net.minecraft.server.EnchantmentManager; +import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; +import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; @@ -129,4 +136,70 @@ public class CraftItemStack extends ItemStack { public int getMaxStackSize() { return item.getItem().getMaxStackSize(); } + + @Override + public void addUnsafeEnchantment(Enchantment ench, int level) { + Map enchantments = getEnchantments(); + enchantments.put(ench, level); + rebuildEnchantments(enchantments); + } + + @Override + public boolean containsEnchantment(Enchantment ench) { + return getEnchantmentLevel(ench) > 0; + } + + @Override + public int getEnchantmentLevel(Enchantment ench) { + return EnchantmentManager.b(ench.getId(), item); + } + + @Override + public int removeEnchantment(Enchantment ench) { + Map enchantments = getEnchantments(); + Integer previous = enchantments.remove(ench); + + rebuildEnchantments(enchantments); + + return (previous == null) ? 0 : previous; + } + + @Override + public Map getEnchantments() { + Map result = new HashMap(); + NBTTagList list = item.p(); + + if (list == null) { + return result; + } + + for (int i = 0; i < list.d(); i++) { + short id = ((NBTTagCompound)list.a(i)).e("id"); + short level = ((NBTTagCompound)list.a(i)).e("lvl"); + + result.put(Enchantment.getById(id), (int)level); + } + + return result; + } + + private void rebuildEnchantments(Map enchantments) { + NBTTagCompound tag = item.tag; + NBTTagList list = new NBTTagList("ench"); + + if (tag == null) { + tag = item.tag = new NBTTagCompound(); + } + + for (Map.Entry entry : enchantments.entrySet()) { + NBTTagCompound subtag = new NBTTagCompound(); + + subtag.a("id", (short)entry.getKey().getId()); + subtag.a("lvl", (short)(int)entry.getValue()); + + list.a(subtag); + } + + tag.a("ench", (NBTBase)list); + } }