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}