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}