001 package net.minecraft.src; 002 003 import java.util.ArrayList; 004 import java.util.HashMap; 005 import java.util.Iterator; 006 import java.util.List; 007 import java.util.Map; 008 import java.util.Random; 009 010 public class EnchantmentHelper 011 { 012 /** Is the random seed of enchantment effects. */ 013 private static final Random enchantmentRand = new Random(); 014 015 /** 016 * Used to calculate the extra armor of enchantments on armors equipped on player. 017 */ 018 private static final EnchantmentModifierDamage enchantmentModifierDamage = new EnchantmentModifierDamage((Empty3)null); 019 020 /** 021 * Used to calculate the (magic) extra damage done by enchantments on current equipped item of player. 022 */ 023 private static final EnchantmentModifierLiving enchantmentModifierLiving = new EnchantmentModifierLiving((Empty3)null); 024 025 /** 026 * Returns the level of enchantment on the ItemStack passed. 027 */ 028 public static int getEnchantmentLevel(int par0, ItemStack par1ItemStack) 029 { 030 if (par1ItemStack == null) 031 { 032 return 0; 033 } 034 else 035 { 036 NBTTagList var2 = par1ItemStack.getEnchantmentTagList(); 037 038 if (var2 == null) 039 { 040 return 0; 041 } 042 else 043 { 044 for (int var3 = 0; var3 < var2.tagCount(); ++var3) 045 { 046 short var4 = ((NBTTagCompound)var2.tagAt(var3)).getShort("id"); 047 short var5 = ((NBTTagCompound)var2.tagAt(var3)).getShort("lvl"); 048 049 if (var4 == par0) 050 { 051 return var5; 052 } 053 } 054 055 return 0; 056 } 057 } 058 } 059 060 /** 061 * Returns the biggest level of the enchantment on the array of ItemStack passed. 062 */ 063 private static int getMaxEnchantmentLevel(int par0, ItemStack[] par1ArrayOfItemStack) 064 { 065 int var2 = 0; 066 ItemStack[] var3 = par1ArrayOfItemStack; 067 int var4 = par1ArrayOfItemStack.length; 068 069 for (int var5 = 0; var5 < var4; ++var5) 070 { 071 ItemStack var6 = var3[var5]; 072 int var7 = getEnchantmentLevel(par0, var6); 073 074 if (var7 > var2) 075 { 076 var2 = var7; 077 } 078 } 079 080 return var2; 081 } 082 083 /** 084 * Executes the enchantment modifier on the ItemStack passed. 085 */ 086 private static void applyEnchantmentModifier(IEnchantmentModifier par0IEnchantmentModifier, ItemStack par1ItemStack) 087 { 088 if (par1ItemStack != null) 089 { 090 NBTTagList var2 = par1ItemStack.getEnchantmentTagList(); 091 092 if (var2 != null) 093 { 094 for (int var3 = 0; var3 < var2.tagCount(); ++var3) 095 { 096 short var4 = ((NBTTagCompound)var2.tagAt(var3)).getShort("id"); 097 short var5 = ((NBTTagCompound)var2.tagAt(var3)).getShort("lvl"); 098 099 if (Enchantment.enchantmentsList[var4] != null) 100 { 101 par0IEnchantmentModifier.calculateModifier(Enchantment.enchantmentsList[var4], var5); 102 } 103 } 104 } 105 } 106 } 107 108 /** 109 * Executes the enchantment modifier on the array of ItemStack passed. 110 */ 111 private static void applyEnchantmentModifierArray(IEnchantmentModifier par0IEnchantmentModifier, ItemStack[] par1ArrayOfItemStack) 112 { 113 ItemStack[] var2 = par1ArrayOfItemStack; 114 int var3 = par1ArrayOfItemStack.length; 115 116 for (int var4 = 0; var4 < var3; ++var4) 117 { 118 ItemStack var5 = var2[var4]; 119 applyEnchantmentModifier(par0IEnchantmentModifier, var5); 120 } 121 } 122 123 /** 124 * Returns the modifier of protection enchantments on armors equipped on player. 125 */ 126 public static int getEnchantmentModifierDamage(InventoryPlayer par0InventoryPlayer, DamageSource par1DamageSource) 127 { 128 enchantmentModifierDamage.damageModifier = 0; 129 enchantmentModifierDamage.source = par1DamageSource; 130 applyEnchantmentModifierArray(enchantmentModifierDamage, par0InventoryPlayer.armorInventory); 131 132 if (enchantmentModifierDamage.damageModifier > 25) 133 { 134 enchantmentModifierDamage.damageModifier = 25; 135 } 136 137 return (enchantmentModifierDamage.damageModifier + 1 >> 1) + enchantmentRand.nextInt((enchantmentModifierDamage.damageModifier >> 1) + 1); 138 } 139 140 /** 141 * Return the (magic) extra damage of the enchantments on player equipped item. 142 */ 143 public static int getEnchantmentModifierLiving(InventoryPlayer par0InventoryPlayer, EntityLiving par1EntityLiving) 144 { 145 enchantmentModifierLiving.livingModifier = 0; 146 enchantmentModifierLiving.entityLiving = par1EntityLiving; 147 applyEnchantmentModifier(enchantmentModifierLiving, par0InventoryPlayer.getCurrentItem()); 148 return enchantmentModifierLiving.livingModifier > 0 ? 1 + enchantmentRand.nextInt(enchantmentModifierLiving.livingModifier) : 0; 149 } 150 151 /** 152 * Returns the knockback value of enchantments on equipped player item. 153 */ 154 public static int getKnockbackModifier(InventoryPlayer par0InventoryPlayer, EntityLiving par1EntityLiving) 155 { 156 return getEnchantmentLevel(Enchantment.knockback.effectId, par0InventoryPlayer.getCurrentItem()); 157 } 158 159 /** 160 * Return the fire aspect value of enchantments on equipped player item. 161 */ 162 public static int getFireAspectModifier(InventoryPlayer par0InventoryPlayer, EntityLiving par1EntityLiving) 163 { 164 return getEnchantmentLevel(Enchantment.fireAspect.effectId, par0InventoryPlayer.getCurrentItem()); 165 } 166 167 /** 168 * Returns the 'Water Breathing' modifier of enchantments on player equipped armors. 169 */ 170 public static int getRespiration(InventoryPlayer par0InventoryPlayer) 171 { 172 return getMaxEnchantmentLevel(Enchantment.respiration.effectId, par0InventoryPlayer.armorInventory); 173 } 174 175 /** 176 * Return the extra efficiency of tools based on enchantments on equipped player item. 177 */ 178 public static int getEfficiencyModifier(InventoryPlayer par0InventoryPlayer) 179 { 180 return getEnchantmentLevel(Enchantment.efficiency.effectId, par0InventoryPlayer.getCurrentItem()); 181 } 182 183 /** 184 * Returns the unbreaking enchantment modifier on current equipped item of player. 185 */ 186 public static int getUnbreakingModifier(InventoryPlayer par0InventoryPlayer) 187 { 188 return getEnchantmentLevel(Enchantment.unbreaking.effectId, par0InventoryPlayer.getCurrentItem()); 189 } 190 191 /** 192 * Returns the silk touch status of enchantments on current equipped item of player. 193 */ 194 public static boolean getSilkTouchModifier(InventoryPlayer par0InventoryPlayer) 195 { 196 return getEnchantmentLevel(Enchantment.silkTouch.effectId, par0InventoryPlayer.getCurrentItem()) > 0; 197 } 198 199 /** 200 * Returns the fortune enchantment modifier of the current equipped item of player. 201 */ 202 public static int getFortuneModifier(InventoryPlayer par0InventoryPlayer) 203 { 204 return getEnchantmentLevel(Enchantment.fortune.effectId, par0InventoryPlayer.getCurrentItem()); 205 } 206 207 /** 208 * Returns the looting enchantment modifier of the current equipped item of player. 209 */ 210 public static int getLootingModifier(InventoryPlayer par0InventoryPlayer) 211 { 212 return getEnchantmentLevel(Enchantment.looting.effectId, par0InventoryPlayer.getCurrentItem()); 213 } 214 215 /** 216 * Returns the aqua affinity status of enchantments on current equipped item of player. 217 */ 218 public static boolean getAquaAffinityModifier(InventoryPlayer par0InventoryPlayer) 219 { 220 return getMaxEnchantmentLevel(Enchantment.aquaAffinity.effectId, par0InventoryPlayer.armorInventory) > 0; 221 } 222 223 /** 224 * Returns the enchantability of itemstack, it's uses a singular formula for each index (2nd parameter: 0, 1 and 2), 225 * cutting to the max enchantability power of the table (3rd parameter) 226 */ 227 public static int calcItemStackEnchantability(Random par0Random, int par1, int par2, ItemStack par3ItemStack) 228 { 229 Item var4 = par3ItemStack.getItem(); 230 int var5 = var4.getItemEnchantability(); 231 232 if (var5 <= 0) 233 { 234 return 0; 235 } 236 else 237 { 238 if (par2 > 15) 239 { 240 par2 = 15; 241 } 242 243 int var6 = par0Random.nextInt(8) + 1 + (par2 >> 1) + par0Random.nextInt(par2 + 1); 244 return par1 == 0 ? Math.max(var6 / 3, 1) : (par1 == 1 ? var6 * 2 / 3 + 1 : Math.max(var6, par2 * 2)); 245 } 246 } 247 248 /** 249 * Adds a random enchantment to the specified item. Args: random, itemStack, enchantabilityLevel 250 */ 251 public static ItemStack addRandomEnchantment(Random par0Random, ItemStack par1ItemStack, int par2) 252 { 253 List var3 = buildEnchantmentList(par0Random, par1ItemStack, par2); 254 255 if (var3 != null) 256 { 257 Iterator var4 = var3.iterator(); 258 259 while (var4.hasNext()) 260 { 261 EnchantmentData var5 = (EnchantmentData)var4.next(); 262 par1ItemStack.addEnchantment(var5.enchantmentobj, var5.enchantmentLevel); 263 } 264 } 265 266 return par1ItemStack; 267 } 268 269 /** 270 * Create a list of random EnchantmentData (enchantments) that can be added together to the ItemStack, the 3rd 271 * parameter is the total enchantability level. 272 */ 273 public static List buildEnchantmentList(Random par0Random, ItemStack par1ItemStack, int par2) 274 { 275 Item var3 = par1ItemStack.getItem(); 276 int var4 = var3.getItemEnchantability(); 277 278 if (var4 <= 0) 279 { 280 return null; 281 } 282 else 283 { 284 var4 /= 2; 285 var4 = 1 + par0Random.nextInt((var4 >> 1) + 1) + par0Random.nextInt((var4 >> 1) + 1); 286 int var5 = var4 + par2; 287 float var6 = (par0Random.nextFloat() + par0Random.nextFloat() - 1.0F) * 0.15F; 288 int var7 = (int)((float)var5 * (1.0F + var6) + 0.5F); 289 290 if (var7 < 1) 291 { 292 var7 = 1; 293 } 294 295 ArrayList var8 = null; 296 Map var9 = mapEnchantmentData(var7, par1ItemStack); 297 298 if (var9 != null && !var9.isEmpty()) 299 { 300 EnchantmentData var10 = (EnchantmentData)WeightedRandom.getRandomItem(par0Random, var9.values()); 301 302 if (var10 != null) 303 { 304 var8 = new ArrayList(); 305 var8.add(var10); 306 307 for (int var11 = var7; par0Random.nextInt(50) <= var11; var11 >>= 1) 308 { 309 Iterator var12 = var9.keySet().iterator(); 310 311 while (var12.hasNext()) 312 { 313 Integer var13 = (Integer)var12.next(); 314 boolean var14 = true; 315 Iterator var15 = var8.iterator(); 316 317 while (true) 318 { 319 if (var15.hasNext()) 320 { 321 EnchantmentData var16 = (EnchantmentData)var15.next(); 322 323 if (var16.enchantmentobj.canApplyTogether(Enchantment.enchantmentsList[var13.intValue()])) 324 { 325 continue; 326 } 327 328 var14 = false; 329 } 330 331 if (!var14) 332 { 333 var12.remove(); 334 } 335 336 break; 337 } 338 } 339 340 if (!var9.isEmpty()) 341 { 342 EnchantmentData var17 = (EnchantmentData)WeightedRandom.getRandomItem(par0Random, var9.values()); 343 var8.add(var17); 344 } 345 } 346 } 347 } 348 349 return var8; 350 } 351 } 352 353 /** 354 * Creates a 'Map' of EnchantmentData (enchantments) possible to add on the ItemStack and the enchantability level 355 * passed. 356 */ 357 public static Map mapEnchantmentData(int par0, ItemStack par1ItemStack) 358 { 359 Item var2 = par1ItemStack.getItem(); 360 HashMap var3 = null; 361 Enchantment[] var4 = Enchantment.enchantmentsList; 362 int var5 = var4.length; 363 364 for (int var6 = 0; var6 < var5; ++var6) 365 { 366 Enchantment var7 = var4[var6]; 367 368 if (var7 != null && var7.canEnchantItem(par1ItemStack)) 369 { 370 for (int var8 = var7.getMinLevel(); var8 <= var7.getMaxLevel(); ++var8) 371 { 372 if (par0 >= var7.getMinEnchantability(var8) && par0 <= var7.getMaxEnchantability(var8)) 373 { 374 if (var3 == null) 375 { 376 var3 = new HashMap(); 377 } 378 379 var3.put(Integer.valueOf(var7.effectId), new EnchantmentData(var7, var8)); 380 } 381 } 382 } 383 } 384 385 return var3; 386 } 387 }