    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}