001package net.minecraft.potion; 002 003import java.util.ArrayList; 004import java.util.List; 005 006import cpw.mods.fml.relauncher.Side; 007import cpw.mods.fml.relauncher.SideOnly; 008import net.minecraft.entity.EntityLiving; 009import net.minecraft.item.Item; 010import net.minecraft.item.ItemStack; 011import net.minecraft.nbt.NBTTagCompound; 012 013public class PotionEffect 014{ 015 /** ID value of the potion this effect matches. */ 016 private int potionID; 017 018 /** The duration of the potion effect */ 019 public int duration; 020 021 /** The amplifier of the potion effect */ 022 private int amplifier; 023 024 /** Whether the potion is a splash potion */ 025 private boolean isSplashPotion; 026 027 /** Whether the potion effect came from a beacon */ 028 private boolean isAmbient; 029 @SideOnly(Side.CLIENT) 030 031 /** True if potion effect duration is at maximum, false otherwise. */ 032 private boolean isPotionDurationMax; 033 034 /** List of ItemStack that can cure the potion effect **/ 035 private List<ItemStack> curativeItems; 036 037 public PotionEffect(int par1, int par2) 038 { 039 this(par1, par2, 0); 040 } 041 042 public PotionEffect(int par1, int par2, int par3) 043 { 044 this(par1, par2, par3, false); 045 } 046 047 public PotionEffect(int par1, int par2, int par3, boolean par4) 048 { 049 this.potionID = par1; 050 this.duration = par2; 051 this.amplifier = par3; 052 this.isAmbient = par4; 053 this.curativeItems = new ArrayList<ItemStack>(); 054 this.curativeItems.add(new ItemStack(Item.bucketMilk)); 055 } 056 057 public PotionEffect(PotionEffect par1PotionEffect) 058 { 059 this.potionID = par1PotionEffect.potionID; 060 this.duration = par1PotionEffect.duration; 061 this.amplifier = par1PotionEffect.amplifier; 062 this.curativeItems = par1PotionEffect.getCurativeItems(); 063 } 064 065 /** 066 * merges the input PotionEffect into this one if this.amplifier <= tomerge.amplifier. The duration in the supplied 067 * potion effect is assumed to be greater. 068 */ 069 public void combine(PotionEffect par1PotionEffect) 070 { 071 if (this.potionID != par1PotionEffect.potionID) 072 { 073 System.err.println("This method should only be called for matching effects!"); 074 } 075 076 if (par1PotionEffect.amplifier > this.amplifier) 077 { 078 this.amplifier = par1PotionEffect.amplifier; 079 this.duration = par1PotionEffect.duration; 080 } 081 else if (par1PotionEffect.amplifier == this.amplifier && this.duration < par1PotionEffect.duration) 082 { 083 this.duration = par1PotionEffect.duration; 084 } 085 else if (!par1PotionEffect.isAmbient && this.isAmbient) 086 { 087 this.isAmbient = par1PotionEffect.isAmbient; 088 } 089 } 090 091 /** 092 * Retrieve the ID of the potion this effect matches. 093 */ 094 public int getPotionID() 095 { 096 return this.potionID; 097 } 098 099 public int getDuration() 100 { 101 return this.duration; 102 } 103 104 public int getAmplifier() 105 { 106 return this.amplifier; 107 } 108 109 /*** 110 * Returns a list of curative items for the potion effect 111 * @return The list (ItemStack) of curative items for the potion effect 112 */ 113 public List<ItemStack> getCurativeItems() 114 { 115 return this.curativeItems; 116 } 117 118 /*** 119 * Checks the given ItemStack to see if it is in the list of curative items for the potion effect 120 * @param stack The ItemStack being checked against the list of curative items for the potion effect 121 * @return true if the given ItemStack is in the list of curative items for the potion effect, false otherwise 122 */ 123 public boolean isCurativeItem(ItemStack stack) 124 { 125 boolean found = false; 126 for (ItemStack curativeItem : this.curativeItems) 127 { 128 if (curativeItem.isItemEqual(stack)) 129 { 130 found = true; 131 } 132 } 133 134 return found; 135 } 136 137 /*** 138 * Sets the array of curative items for the potion effect 139 * @param curativeItems The list of ItemStacks being set to the potion effect 140 */ 141 public void setCurativeItems(List<ItemStack> curativeItems) 142 { 143 this.curativeItems = curativeItems; 144 } 145 146 /*** 147 * Adds the given stack to list of curative items for the potion effect 148 * @param stack The ItemStack being added to the curative item list 149 */ 150 public void addCurativeItem(ItemStack stack) 151 { 152 boolean found = false; 153 for (ItemStack curativeItem : this.curativeItems) 154 { 155 if (curativeItem.isItemEqual(stack)) 156 { 157 found = true; 158 } 159 } 160 if (!found) 161 { 162 this.curativeItems.add(stack); 163 } 164 } 165 166 public boolean func_102028_d() 167 { 168 return this.isSplashPotion; 169 } 170 171 /** 172 * Set whether this potion is a splash potion. 173 */ 174 public void setSplashPotion(boolean par1) 175 { 176 this.isSplashPotion = par1; 177 } 178 179 /** 180 * Gets whether this potion effect originated from a beacon 181 */ 182 public boolean getIsAmbient() 183 { 184 return this.isAmbient; 185 } 186 187 public boolean onUpdate(EntityLiving par1EntityLiving) 188 { 189 if (this.duration > 0) 190 { 191 if (Potion.potionTypes[this.potionID].isReady(this.duration, this.amplifier)) 192 { 193 this.performEffect(par1EntityLiving); 194 } 195 196 this.deincrementDuration(); 197 } 198 199 return this.duration > 0; 200 } 201 202 private int deincrementDuration() 203 { 204 return --this.duration; 205 } 206 207 public void performEffect(EntityLiving par1EntityLiving) 208 { 209 if (this.duration > 0) 210 { 211 Potion.potionTypes[this.potionID].performEffect(par1EntityLiving, this.amplifier); 212 } 213 } 214 215 public String getEffectName() 216 { 217 return Potion.potionTypes[this.potionID].getName(); 218 } 219 220 public int hashCode() 221 { 222 return this.potionID; 223 } 224 225 public String toString() 226 { 227 String s = ""; 228 229 if (this.getAmplifier() > 0) 230 { 231 s = this.getEffectName() + " x " + (this.getAmplifier() + 1) + ", Duration: " + this.getDuration(); 232 } 233 else 234 { 235 s = this.getEffectName() + ", Duration: " + this.getDuration(); 236 } 237 238 if (this.isSplashPotion) 239 { 240 s = s + ", Splash: true"; 241 } 242 243 return Potion.potionTypes[this.potionID].isUsable() ? "(" + s + ")" : s; 244 } 245 246 public boolean equals(Object par1Obj) 247 { 248 if (!(par1Obj instanceof PotionEffect)) 249 { 250 return false; 251 } 252 else 253 { 254 PotionEffect potioneffect = (PotionEffect)par1Obj; 255 return this.potionID == potioneffect.potionID && this.amplifier == potioneffect.amplifier && this.duration == potioneffect.duration && this.isSplashPotion == potioneffect.isSplashPotion && this.isAmbient == potioneffect.isAmbient; 256 } 257 } 258 259 /** 260 * Write a custom potion effect to a potion item's NBT data. 261 */ 262 public NBTTagCompound writeCustomPotionEffectToNBT(NBTTagCompound par1NBTTagCompound) 263 { 264 par1NBTTagCompound.setByte("Id", (byte)this.getPotionID()); 265 par1NBTTagCompound.setByte("Amplifier", (byte)this.getAmplifier()); 266 par1NBTTagCompound.setInteger("Duration", this.getDuration()); 267 par1NBTTagCompound.setBoolean("Ambient", this.getIsAmbient()); 268 return par1NBTTagCompound; 269 } 270 271 /** 272 * Read a custom potion effect from a potion item's NBT data. 273 */ 274 public static PotionEffect readCustomPotionEffectFromNBT(NBTTagCompound par0NBTTagCompound) 275 { 276 byte b0 = par0NBTTagCompound.getByte("Id"); 277 byte b1 = par0NBTTagCompound.getByte("Amplifier"); 278 int i = par0NBTTagCompound.getInteger("Duration"); 279 boolean flag = par0NBTTagCompound.getBoolean("Ambient"); 280 return new PotionEffect(b0, i, b1, flag); 281 } 282 283 @SideOnly(Side.CLIENT) 284 285 /** 286 * Toggle the isPotionDurationMax field. 287 */ 288 public void setPotionDurationMax(boolean par1) 289 { 290 this.isPotionDurationMax = par1; 291 } 292 293 @SideOnly(Side.CLIENT) 294 public boolean getIsPotionDurationMax() 295 { 296 return this.isPotionDurationMax; 297 } 298}