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 }