    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    }