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