    001    package net.minecraft.item;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.ArrayList;
    006    import java.util.HashMap;
    007    import java.util.Iterator;
    008    import java.util.LinkedHashMap;
    009    import java.util.List;
    010    import java.util.Map;
    011    import net.minecraft.creativetab.CreativeTabs;
    012    import net.minecraft.entity.player.EntityPlayer;
    013    import net.minecraft.entity.projectile.EntityPotion;
    014    import net.minecraft.nbt.NBTTagCompound;
    015    import net.minecraft.nbt.NBTTagList;
    016    import net.minecraft.potion.Potion;
    017    import net.minecraft.potion.PotionEffect;
    018    import net.minecraft.potion.PotionHelper;
    019    import net.minecraft.util.StatCollector;
    020    import net.minecraft.world.World;
    021
    022    public class ItemPotion extends Item
    023    {
    024        /** maps potion damage values to lists of effect names */
    025        private HashMap effectCache = new HashMap();
    026        private static final Map field_77835_b = new LinkedHashMap();
    027
    028        public ItemPotion(int par1)
    029        {
    030            super(par1);
    031            this.setMaxStackSize(1);
    032            this.setHasSubtypes(true);
    033            this.setMaxDamage(0);
    034            this.setCreativeTab(CreativeTabs.tabBrewing);
    035        }
    036
    037        /**
    038         * Returns a list of potion effects for the specified itemstack.
    039         */
    040        public List getEffects(ItemStack par1ItemStack)
    041        {
    042            if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().hasKey("CustomPotionEffects"))
    043            {
    044                ArrayList var6 = new ArrayList();
    045                NBTTagList var3 = par1ItemStack.getTagCompound().getTagList("CustomPotionEffects");
    046
    047                for (int var4 = 0; var4 < var3.tagCount(); ++var4)
    048                {
    049                    NBTTagCompound var5 = (NBTTagCompound)var3.tagAt(var4);
    050                    var6.add(PotionEffect.readCustomPotionEffectFromNBT(var5));
    051                }
    052
    053                return var6;
    054            }
    055            else
    056            {
    057                List var2 = (List)this.effectCache.get(Integer.valueOf(par1ItemStack.getItemDamage()));
    058
    059                if (var2 == null)
    060                {
    061                    var2 = PotionHelper.getPotionEffects(par1ItemStack.getItemDamage(), false);
    062                    this.effectCache.put(Integer.valueOf(par1ItemStack.getItemDamage()), var2);
    063                }
    064
    065                return var2;
    066            }
    067        }
    068
    069        /**
    070         * Returns a list of effects for the specified potion damage value.
    071         */
    072        public List getEffects(int par1)
    073        {
    074            List var2 = (List)this.effectCache.get(Integer.valueOf(par1));
    075
    076            if (var2 == null)
    077            {
    078                var2 = PotionHelper.getPotionEffects(par1, false);
    079                this.effectCache.put(Integer.valueOf(par1), var2);
    080            }
    081
    082            return var2;
    083        }
    084
    085        public ItemStack onFoodEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
    086        {
    087            if (!par3EntityPlayer.capabilities.isCreativeMode)
    088            {
    089                --par1ItemStack.stackSize;
    090            }
    091
    092            if (!par2World.isRemote)
    093            {
    094                List var4 = this.getEffects(par1ItemStack);
    095
    096                if (var4 != null)
    097                {
    098                    Iterator var5 = var4.iterator();
    099
    100                    while (var5.hasNext())
    101                    {
    102                        PotionEffect var6 = (PotionEffect)var5.next();
    103                        par3EntityPlayer.addPotionEffect(new PotionEffect(var6));
    104                    }
    105                }
    106            }
    107
    108            if (!par3EntityPlayer.capabilities.isCreativeMode)
    109            {
    110                if (par1ItemStack.stackSize <= 0)
    111                {
    112                    return new ItemStack(Item.glassBottle);
    113                }
    114
    115                par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.glassBottle));
    116            }
    117
    118            return par1ItemStack;
    119        }
    120
    121        /**
    122         * How long it takes to use or consume an item
    123         */
    124        public int getMaxItemUseDuration(ItemStack par1ItemStack)
    125        {
    126            return 32;
    127        }
    128
    129        /**
    130         * returns the action that specifies what animation to play when the items is being used
    131         */
    132        public EnumAction getItemUseAction(ItemStack par1ItemStack)
    133        {
    134            return EnumAction.drink;
    135        }
    136
    137        /**
    138         * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
    139         */
    140        public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
    141        {
    142            if (isSplash(par1ItemStack.getItemDamage()))
    143            {
    144                if (!par3EntityPlayer.capabilities.isCreativeMode)
    145                {
    146                    --par1ItemStack.stackSize;
    147                }
    148
    149                par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));
    150
    151                if (!par2World.isRemote)
    152                {
    153                    par2World.spawnEntityInWorld(new EntityPotion(par2World, par3EntityPlayer, par1ItemStack));
    154                }
    155
    156                return par1ItemStack;
    157            }
    158            else
    159            {
    160                par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack));
    161                return par1ItemStack;
    162            }
    163        }
    164
    165        /**
    166         * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return
    167         * True if something happen and false if it don't. This is for ITEMS, not BLOCKS
    168         */
    169        public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
    170        {
    171            return false;
    172        }
    173
    174        @SideOnly(Side.CLIENT)
    175
    176        /**
    177         * Gets an icon index based on an item's damage value
    178         */
    179        public int getIconFromDamage(int par1)
    180        {
    181            return isSplash(par1) ? 154 : 140;
    182        }
    183
    184        @SideOnly(Side.CLIENT)
    185
    186        /**
    187         * Gets an icon index based on an item's damage value and the given render pass
    188         */
    189        public int getIconFromDamageForRenderPass(int par1, int par2)
    190        {
    191            return par2 == 0 ? 141 : super.getIconFromDamageForRenderPass(par1, par2);
    192        }
    193
    194        /**
    195         * returns wether or not a potion is a throwable splash potion based on damage value
    196         */
    197        public static boolean isSplash(int par0)
    198        {
    199            return (par0 & 16384) != 0;
    200        }
    201
    202        @SideOnly(Side.CLIENT)
    203        public int getColorFromDamage(int par1)
    204        {
    205            return PotionHelper.func_77915_a(par1, false);
    206        }
    207
    208        @SideOnly(Side.CLIENT)
    209        public int getColorFromItemStack(ItemStack par1ItemStack, int par2)
    210        {
    211            return par2 > 0 ? 16777215 : this.getColorFromDamage(par1ItemStack.getItemDamage());
    212        }
    213
    214        @SideOnly(Side.CLIENT)
    215        public boolean requiresMultipleRenderPasses()
    216        {
    217            return true;
    218        }
    219
    220        @SideOnly(Side.CLIENT)
    221        public boolean isEffectInstant(int par1)
    222        {
    223            List var2 = this.getEffects(par1);
    224
    225            if (var2 != null && !var2.isEmpty())
    226            {
    227                Iterator var3 = var2.iterator();
    228                PotionEffect var4;
    229
    230                do
    231                {
    232                    if (!var3.hasNext())
    233                    {
    234                        return false;
    235                    }
    236
    237                    var4 = (PotionEffect)var3.next();
    238                }
    239                while (!Potion.potionTypes[var4.getPotionID()].isInstant());
    240
    241                return true;
    242            }
    243            else
    244            {
    245                return false;
    246            }
    247        }
    248
    249        public String getItemDisplayName(ItemStack par1ItemStack)
    250        {
    251            if (par1ItemStack.getItemDamage() == 0)
    252            {
    253                return StatCollector.translateToLocal("item.emptyPotion.name").trim();
    254            }
    255            else
    256            {
    257                String var2 = "";
    258
    259                if (isSplash(par1ItemStack.getItemDamage()))
    260                {
    261                    var2 = StatCollector.translateToLocal("potion.prefix.grenade").trim() + " ";
    262                }
    263
    264                List var3 = Item.potion.getEffects(par1ItemStack);
    265                String var4;
    266
    267                if (var3 != null && !var3.isEmpty())
    268                {
    269                    var4 = ((PotionEffect)var3.get(0)).getEffectName();
    270                    var4 = var4 + ".postfix";
    271                    return var2 + StatCollector.translateToLocal(var4).trim();
    272                }
    273                else
    274                {
    275                    var4 = PotionHelper.func_77905_c(par1ItemStack.getItemDamage());
    276                    return StatCollector.translateToLocal(var4).trim() + " " + super.getItemDisplayName(par1ItemStack);
    277                }
    278            }
    279        }
    280
    281        @SideOnly(Side.CLIENT)
    282
    283        /**
    284         * allows items to add custom lines of information to the mouseover description
    285         */
    286        public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
    287        {
    288            if (par1ItemStack.getItemDamage() != 0)
    289            {
    290                List var5 = Item.potion.getEffects(par1ItemStack);
    291
    292                if (var5 != null && !var5.isEmpty())
    293                {
    294                    Iterator var9 = var5.iterator();
    295
    296                    while (var9.hasNext())
    297                    {
    298                        PotionEffect var7 = (PotionEffect)var9.next();
    299                        String var8 = StatCollector.translateToLocal(var7.getEffectName()).trim();
    300
    301                        if (var7.getAmplifier() > 0)
    302                        {
    303                            var8 = var8 + " " + StatCollector.translateToLocal("potion.potency." + var7.getAmplifier()).trim();
    304                        }
    305
    306                        if (var7.getDuration() > 20)
    307                        {
    308                            var8 = var8 + " (" + Potion.getDurationString(var7) + ")";
    309                        }
    310
    311                        if (Potion.potionTypes[var7.getPotionID()].isBadEffect())
    312                        {
    313                            par3List.add("\u00a7c" + var8);
    314                        }
    315                        else
    316                        {
    317                            par3List.add("\u00a77" + var8);
    318                        }
    319                    }
    320                }
    321                else
    322                {
    323                    String var6 = StatCollector.translateToLocal("potion.empty").trim();
    324                    par3List.add("\u00a77" + var6);
    325                }
    326            }
    327        }
    328
    329        @SideOnly(Side.CLIENT)
    330        public boolean hasEffect(ItemStack par1ItemStack)
    331        {
    332            List var2 = this.getEffects(par1ItemStack);
    333            return var2 != null && !var2.isEmpty();
    334        }
    335
    336        @SideOnly(Side.CLIENT)
    337
    338        /**
    339         * returns a list of items with the same ID, but different meta (eg: dye returns 16 items)
    340         */
    341        public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
    342        {
    343            super.getSubItems(par1, par2CreativeTabs, par3List);
    344
    345            if (field_77835_b.isEmpty())
    346            {
    347                for (int var4 = 0; var4 <= 32767; ++var4)
    348                {
    349                    List var5 = PotionHelper.getPotionEffects(var4, false);
    350
    351                    if (var5 != null && !var5.isEmpty())
    352                    {
    353                        field_77835_b.put(var5, Integer.valueOf(var4));
    354                    }
    355                }
    356            }
    357
    358            Iterator var6 = field_77835_b.values().iterator();
    359
    360            while (var6.hasNext())
    361            {
    362                int var7 = ((Integer)var6.next()).intValue();
    363                par3List.add(new ItemStack(par1, 1, var7));
    364            }
    365        }
    366    }