001 package org.bukkit.enchantments; 002 003 import java.util.HashMap; 004 import java.util.Map; 005 006 import org.bukkit.command.defaults.EnchantCommand; 007 import org.bukkit.inventory.ItemStack; 008 009 /** 010 * The various type of enchantments that may be added to armour or weapons 011 */ 012 public abstract class Enchantment { 013 /** 014 * Provides protection against environmental damage 015 */ 016 public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper(0); 017 018 /** 019 * Provides protection against fire damage 020 */ 021 public static final Enchantment PROTECTION_FIRE = new EnchantmentWrapper(1); 022 023 /** 024 * Provides protection against fall damage 025 */ 026 public static final Enchantment PROTECTION_FALL = new EnchantmentWrapper(2); 027 028 /** 029 * Provides protection against explosive damage 030 */ 031 public static final Enchantment PROTECTION_EXPLOSIONS = new EnchantmentWrapper(3); 032 033 /** 034 * Provides protection against projectile damage 035 */ 036 public static final Enchantment PROTECTION_PROJECTILE = new EnchantmentWrapper(4); 037 038 /** 039 * Decreases the rate of air loss whilst underwater 040 */ 041 public static final Enchantment OXYGEN = new EnchantmentWrapper(5); 042 043 /** 044 * Increases the speed at which a player may mine underwater 045 */ 046 public static final Enchantment WATER_WORKER = new EnchantmentWrapper(6); 047 048 /** 049 * Damages the attacker 050 */ 051 public static final Enchantment THORNS = new EnchantmentWrapper(7); 052 053 /** 054 * Increases damage against all targets 055 */ 056 public static final Enchantment DAMAGE_ALL = new EnchantmentWrapper(16); 057 058 /** 059 * Increases damage against undead targets 060 */ 061 public static final Enchantment DAMAGE_UNDEAD = new EnchantmentWrapper(17); 062 063 /** 064 * Increases damage against arthropod targets 065 */ 066 public static final Enchantment DAMAGE_ARTHROPODS = new EnchantmentWrapper(18); 067 068 /** 069 * All damage to other targets will knock them back when hit 070 */ 071 public static final Enchantment KNOCKBACK = new EnchantmentWrapper(19); 072 073 /** 074 * When attacking a target, has a chance to set them on fire 075 */ 076 public static final Enchantment FIRE_ASPECT = new EnchantmentWrapper(20); 077 078 /** 079 * Provides a chance of gaining extra loot when killing monsters 080 */ 081 public static final Enchantment LOOT_BONUS_MOBS = new EnchantmentWrapper(21); 082 083 /** 084 * Increases the rate at which you mine/dig 085 */ 086 public static final Enchantment DIG_SPEED = new EnchantmentWrapper(32); 087 088 /** 089 * Allows blocks to drop themselves instead of fragments (for example, 090 * stone instead of cobblestone) 091 */ 092 public static final Enchantment SILK_TOUCH = new EnchantmentWrapper(33); 093 094 /** 095 * Decreases the rate at which a tool looses durability 096 */ 097 public static final Enchantment DURABILITY = new EnchantmentWrapper(34); 098 099 /** 100 * Provides a chance of gaining extra loot when destroying blocks 101 */ 102 public static final Enchantment LOOT_BONUS_BLOCKS = new EnchantmentWrapper(35); 103 104 /** 105 * Provides extra damage when shooting arrows from bows 106 */ 107 public static final Enchantment ARROW_DAMAGE = new EnchantmentWrapper(48); 108 109 /** 110 * Provides a knockback when an entity is hit by an arrow from a bow 111 */ 112 public static final Enchantment ARROW_KNOCKBACK = new EnchantmentWrapper(49); 113 114 /** 115 * Sets entities on fire when hit by arrows shot from a bow 116 */ 117 public static final Enchantment ARROW_FIRE = new EnchantmentWrapper(50); 118 119 /** 120 * Provides infinite arrows when shooting a bow 121 */ 122 public static final Enchantment ARROW_INFINITE = new EnchantmentWrapper(51); 123 124 /** 125 * Decreases odds of catching worthless junk 126 */ 127 public static final Enchantment LUCK = new EnchantmentWrapper(61); 128 129 /** 130 * Increases rate of fish biting your hook 131 */ 132 public static final Enchantment LURE = new EnchantmentWrapper(62); 133 134 private static final Map<Integer, Enchantment> byId = new HashMap<Integer, Enchantment>(); 135 private static final Map<String, Enchantment> byName = new HashMap<String, Enchantment>(); 136 private static boolean acceptingNew = true; 137 private final int id; 138 139 public Enchantment(int id) { 140 this.id = id; 141 } 142 143 /** 144 * Gets the unique ID of this enchantment 145 * 146 * @return Unique ID 147 * @deprecated Magic value 148 */ 149 @Deprecated 150 public int getId() { 151 return id; 152 } 153 154 /** 155 * Gets the unique name of this enchantment 156 * 157 * @return Unique name 158 */ 159 public abstract String getName(); 160 161 /** 162 * Gets the maximum level that this Enchantment may become. 163 * 164 * @return Maximum level of the Enchantment 165 */ 166 public abstract int getMaxLevel(); 167 168 /** 169 * Gets the level that this Enchantment should start at 170 * 171 * @return Starting level of the Enchantment 172 */ 173 public abstract int getStartLevel(); 174 175 /** 176 * Gets the type of {@link ItemStack} that may fit this Enchantment. 177 * 178 * @return Target type of the Enchantment 179 */ 180 public abstract EnchantmentTarget getItemTarget(); 181 182 /** 183 * Check if this enchantment conflicts with another enchantment. 184 * 185 * @param other The enchantment to check against 186 * @return True if there is a conflict. 187 */ 188 public abstract boolean conflictsWith(Enchantment other); 189 190 /** 191 * Checks if this Enchantment may be applied to the given {@link 192 * ItemStack}. 193 * <p> 194 * This does not check if it conflicts with any enchantments already 195 * applied to the item. 196 * 197 * @param item Item to test 198 * @return True if the enchantment may be applied, otherwise False 199 */ 200 public abstract boolean canEnchantItem(ItemStack item); 201 202 @Override 203 public boolean equals(Object obj) { 204 if (obj == null) { 205 return false; 206 } 207 if (!(obj instanceof Enchantment)) { 208 return false; 209 } 210 final Enchantment other = (Enchantment) obj; 211 if (this.id != other.id) { 212 return false; 213 } 214 return true; 215 } 216 217 @Override 218 public int hashCode() { 219 return id; 220 } 221 222 @Override 223 public String toString() { 224 return "Enchantment[" + id + ", " + getName() + "]"; 225 } 226 227 /** 228 * Registers an enchantment with the given ID and object. 229 * <p> 230 * Generally not to be used from within a plugin. 231 * 232 * @param enchantment Enchantment to register 233 */ 234 public static void registerEnchantment(Enchantment enchantment) { 235 if (byId.containsKey(enchantment.id) || byName.containsKey(enchantment.getName())) { 236 throw new IllegalArgumentException("Cannot set already-set enchantment"); 237 } else if (!isAcceptingRegistrations()) { 238 throw new IllegalStateException("No longer accepting new enchantments (can only be done by the server implementation)"); 239 } 240 241 byId.put(enchantment.id, enchantment); 242 byName.put(enchantment.getName(), enchantment); 243 } 244 245 /** 246 * Checks if this is accepting Enchantment registrations. 247 * 248 * @return True if the server Implementation may add enchantments 249 */ 250 public static boolean isAcceptingRegistrations() { 251 return acceptingNew; 252 } 253 254 /** 255 * Stops accepting any enchantment registrations 256 */ 257 public static void stopAcceptingRegistrations() { 258 acceptingNew = false; 259 EnchantCommand.buildEnchantments(); 260 } 261 262 /** 263 * Gets the Enchantment at the specified ID 264 * 265 * @param id ID to fetch 266 * @return Resulting Enchantment, or null if not found 267 * @deprecated Magic value 268 */ 269 @Deprecated 270 public static Enchantment getById(int id) { 271 return byId.get(id); 272 } 273 274 /** 275 * Gets the Enchantment at the specified name 276 * 277 * @param name Name to fetch 278 * @return Resulting Enchantment, or null if not found 279 */ 280 public static Enchantment getByName(String name) { 281 return byName.get(name); 282 } 283 284 /** 285 * Gets an array of all the registered {@link Enchantment}s 286 * 287 * @return Array of enchantments 288 */ 289 public static Enchantment[] values() { 290 return byId.values().toArray(new Enchantment[byId.size()]); 291 } 292 }