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