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