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