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    
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    }