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