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