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.setTagInfo("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 public static int func_90036_a(EntityLiving par0EntityLiving) 209 { 210 return getEnchantmentLevel(Enchantment.fireAspect.effectId, par0EntityLiving.getHeldItem()); 211 } 212 213 /** 214 * Returns the 'Water Breathing' modifier of enchantments on player equipped armors. 215 */ 216 public static int getRespiration(EntityLiving par0EntityLiving) 217 { 218 return getMaxEnchantmentLevel(Enchantment.respiration.effectId, par0EntityLiving.getLastActiveItems()); 219 } 220 221 /** 222 * Return the extra efficiency of tools based on enchantments on equipped player item. 223 */ 224 public static int getEfficiencyModifier(EntityLiving par0EntityLiving) 225 { 226 return getEnchantmentLevel(Enchantment.efficiency.effectId, par0EntityLiving.getHeldItem()); 227 } 228 229 /** 230 * Returns the unbreaking enchantment modifier on current equipped item of player. 231 */ 232 public static int getUnbreakingModifier(EntityLiving par0EntityLiving) 233 { 234 return getEnchantmentLevel(Enchantment.unbreaking.effectId, par0EntityLiving.getHeldItem()); 235 } 236 237 /** 238 * Returns the silk touch status of enchantments on current equipped item of player. 239 */ 240 public static boolean getSilkTouchModifier(EntityLiving par0EntityLiving) 241 { 242 return getEnchantmentLevel(Enchantment.silkTouch.effectId, par0EntityLiving.getHeldItem()) > 0; 243 } 244 245 /** 246 * Returns the fortune enchantment modifier of the current equipped item of player. 247 */ 248 public static int getFortuneModifier(EntityLiving par0EntityLiving) 249 { 250 return getEnchantmentLevel(Enchantment.fortune.effectId, par0EntityLiving.getHeldItem()); 251 } 252 253 /** 254 * Returns the looting enchantment modifier of the current equipped item of player. 255 */ 256 public static int getLootingModifier(EntityLiving par0EntityLiving) 257 { 258 return getEnchantmentLevel(Enchantment.looting.effectId, par0EntityLiving.getHeldItem()); 259 } 260 261 /** 262 * Returns the aqua affinity status of enchantments on current equipped item of player. 263 */ 264 public static boolean getAquaAffinityModifier(EntityLiving par0EntityLiving) 265 { 266 return getMaxEnchantmentLevel(Enchantment.aquaAffinity.effectId, par0EntityLiving.getLastActiveItems()) > 0; 267 } 268 269 /** 270 * Returns the enchantability of itemstack, it's uses a singular formula for each index (2nd parameter: 0, 1 and 2), 271 * cutting to the max enchantability power of the table (3rd parameter) 272 */ 273 public static int calcItemStackEnchantability(Random par0Random, int par1, int par2, ItemStack par3ItemStack) 274 { 275 Item var4 = par3ItemStack.getItem(); 276 int var5 = var4.getItemEnchantability(); 277 278 if (var5 <= 0) 279 { 280 return 0; 281 } 282 else 283 { 284 if (par2 > 15) 285 { 286 par2 = 15; 287 } 288 289 int var6 = par0Random.nextInt(8) + 1 + (par2 >> 1) + par0Random.nextInt(par2 + 1); 290 return par1 == 0 ? Math.max(var6 / 3, 1) : (par1 == 1 ? var6 * 2 / 3 + 1 : Math.max(var6, par2 * 2)); 291 } 292 } 293 294 /** 295 * Adds a random enchantment to the specified item. Args: random, itemStack, enchantabilityLevel 296 */ 297 public static ItemStack addRandomEnchantment(Random par0Random, ItemStack par1ItemStack, int par2) 298 { 299 List var3 = buildEnchantmentList(par0Random, par1ItemStack, par2); 300 301 if (var3 != null) 302 { 303 Iterator var4 = var3.iterator(); 304 305 while (var4.hasNext()) 306 { 307 EnchantmentData var5 = (EnchantmentData)var4.next(); 308 par1ItemStack.addEnchantment(var5.enchantmentobj, var5.enchantmentLevel); 309 } 310 } 311 312 return par1ItemStack; 313 } 314 315 /** 316 * Create a list of random EnchantmentData (enchantments) that can be added together to the ItemStack, the 3rd 317 * parameter is the total enchantability level. 318 */ 319 public static List buildEnchantmentList(Random par0Random, ItemStack par1ItemStack, int par2) 320 { 321 Item var3 = par1ItemStack.getItem(); 322 int var4 = var3.getItemEnchantability(); 323 324 if (var4 <= 0) 325 { 326 return null; 327 } 328 else 329 { 330 var4 /= 2; 331 var4 = 1 + par0Random.nextInt((var4 >> 1) + 1) + par0Random.nextInt((var4 >> 1) + 1); 332 int var5 = var4 + par2; 333 float var6 = (par0Random.nextFloat() + par0Random.nextFloat() - 1.0F) * 0.15F; 334 int var7 = (int)((float)var5 * (1.0F + var6) + 0.5F); 335 336 if (var7 < 1) 337 { 338 var7 = 1; 339 } 340 341 ArrayList var8 = null; 342 Map var9 = mapEnchantmentData(var7, par1ItemStack); 343 344 if (var9 != null && !var9.isEmpty()) 345 { 346 EnchantmentData var10 = (EnchantmentData)WeightedRandom.getRandomItem(par0Random, var9.values()); 347 348 if (var10 != null) 349 { 350 var8 = new ArrayList(); 351 var8.add(var10); 352 353 for (int var11 = var7; par0Random.nextInt(50) <= var11; var11 >>= 1) 354 { 355 Iterator var12 = var9.keySet().iterator(); 356 357 while (var12.hasNext()) 358 { 359 Integer var13 = (Integer)var12.next(); 360 boolean var14 = true; 361 Iterator var15 = var8.iterator(); 362 363 while (true) 364 { 365 if (var15.hasNext()) 366 { 367 EnchantmentData var16 = (EnchantmentData)var15.next(); 368 369 if (var16.enchantmentobj.canApplyTogether(Enchantment.enchantmentsList[var13.intValue()])) 370 { 371 continue; 372 } 373 374 var14 = false; 375 } 376 377 if (!var14) 378 { 379 var12.remove(); 380 } 381 382 break; 383 } 384 } 385 386 if (!var9.isEmpty()) 387 { 388 EnchantmentData var17 = (EnchantmentData)WeightedRandom.getRandomItem(par0Random, var9.values()); 389 var8.add(var17); 390 } 391 } 392 } 393 } 394 395 return var8; 396 } 397 } 398 399 /** 400 * Creates a 'Map' of EnchantmentData (enchantments) possible to add on the ItemStack and the enchantability level 401 * passed. 402 */ 403 public static Map mapEnchantmentData(int par0, ItemStack par1ItemStack) 404 { 405 Item var2 = par1ItemStack.getItem(); 406 HashMap var3 = null; 407 Enchantment[] var4 = Enchantment.enchantmentsList; 408 int var5 = var4.length; 409 410 for (int var6 = 0; var6 < var5; ++var6) 411 { 412 Enchantment var7 = var4[var6]; 413 414 if (var7 != null && var7.canEnchantItem(par1ItemStack)) 415 { 416 for (int var8 = var7.getMinLevel(); var8 <= var7.getMaxLevel(); ++var8) 417 { 418 if (par0 >= var7.getMinEnchantability(var8) && par0 <= var7.getMaxEnchantability(var8)) 419 { 420 if (var3 == null) 421 { 422 var3 = new HashMap(); 423 } 424 425 var3.put(Integer.valueOf(var7.effectId), new EnchantmentData(var7, var8)); 426 } 427 } 428 } 429 } 430 431 return var3; 432 } 433 }