    001package net.minecraft.item;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.ArrayList;
    006import java.util.HashMap;
    007import java.util.Iterator;
    008import java.util.LinkedHashMap;
    009import java.util.List;
    010import java.util.Map;
    011import net.minecraft.creativetab.CreativeTabs;
    012import net.minecraft.entity.player.EntityPlayer;
    013import net.minecraft.entity.projectile.EntityPotion;
    014import net.minecraft.nbt.NBTTagCompound;
    015import net.minecraft.nbt.NBTTagList;
    016import net.minecraft.potion.Potion;
    017import net.minecraft.potion.PotionEffect;
    018import net.minecraft.potion.PotionHelper;
    019import net.minecraft.util.StatCollector;
    020import net.minecraft.world.World;
    021
    022public 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}