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 }