001    package net.minecraft.item;
002    
003    import cpw.mods.fml.relauncher.Side;
004    import cpw.mods.fml.relauncher.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    }