    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    private 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    /**
    165     * Set whether this potion is a splash potion.
    166     */
    167    public void setSplashPotion(boolean par1)
    168    {
    169        this.isSplashPotion = par1;
    170    }
    171
    172    /**
    173     * Gets whether this potion effect originated from a beacon
    174     */
    175    public boolean getIsAmbient()
    176    {
    177        return this.isAmbient;
    178    }
    179
    180    public boolean onUpdate(EntityLiving par1EntityLiving)
    181    {
    182        if (this.duration > 0)
    183        {
    184            if (Potion.potionTypes[this.potionID].isReady(this.duration, this.amplifier))
    185            {
    186                this.performEffect(par1EntityLiving);
    187            }
    188
    189            this.deincrementDuration();
    190        }
    191
    192        return this.duration > 0;
    193    }
    194
    195    private int deincrementDuration()
    196    {
    197        return --this.duration;
    198    }
    199
    200    public void performEffect(EntityLiving par1EntityLiving)
    201    {
    202        if (this.duration > 0)
    203        {
    204            Potion.potionTypes[this.potionID].performEffect(par1EntityLiving, this.amplifier);
    205        }
    206    }
    207
    208    public String getEffectName()
    209    {
    210        return Potion.potionTypes[this.potionID].getName();
    211    }
    212
    213    public int hashCode()
    214    {
    215        return this.potionID;
    216    }
    217
    218    public String toString()
    219    {
    220        String s = "";
    221
    222        if (this.getAmplifier() > 0)
    223        {
    224            s = this.getEffectName() + " x " + (this.getAmplifier() + 1) + ", Duration: " + this.getDuration();
    225        }
    226        else
    227        {
    228            s = this.getEffectName() + ", Duration: " + this.getDuration();
    229        }
    230
    231        if (this.isSplashPotion)
    232        {
    233            s = s + ", Splash: true";
    234        }
    235
    236        return Potion.potionTypes[this.potionID].isUsable() ? "(" + s + ")" : s;
    237    }
    238
    239    public boolean equals(Object par1Obj)
    240    {
    241        if (!(par1Obj instanceof PotionEffect))
    242        {
    243            return false;
    244        }
    245        else
    246        {
    247            PotionEffect potioneffect = (PotionEffect)par1Obj;
    248            return this.potionID == potioneffect.potionID && this.amplifier == potioneffect.amplifier && this.duration == potioneffect.duration && this.isSplashPotion == potioneffect.isSplashPotion && this.isAmbient == potioneffect.isAmbient;
    249        }
    250    }
    251
    252    /**
    253     * Write a custom potion effect to a potion item's NBT data.
    254     */
    255    public NBTTagCompound writeCustomPotionEffectToNBT(NBTTagCompound par1NBTTagCompound)
    256    {
    257        par1NBTTagCompound.setByte("Id", (byte)this.getPotionID());
    258        par1NBTTagCompound.setByte("Amplifier", (byte)this.getAmplifier());
    259        par1NBTTagCompound.setInteger("Duration", this.getDuration());
    260        par1NBTTagCompound.setBoolean("Ambient", this.getIsAmbient());
    261        return par1NBTTagCompound;
    262    }
    263
    264    /**
    265     * Read a custom potion effect from a potion item's NBT data.
    266     */
    267    public static PotionEffect readCustomPotionEffectFromNBT(NBTTagCompound par0NBTTagCompound)
    268    {
    269        byte b0 = par0NBTTagCompound.getByte("Id");
    270        byte b1 = par0NBTTagCompound.getByte("Amplifier");
    271        int i = par0NBTTagCompound.getInteger("Duration");
    272        boolean flag = par0NBTTagCompound.getBoolean("Ambient");
    273        return new PotionEffect(b0, i, b1, flag);
    274    }
    275
    276    @SideOnly(Side.CLIENT)
    277    public void func_100012_b(boolean par1)
    278    {
    279        this.field_100013_f = par1;
    280    }
    281
    282    @SideOnly(Side.CLIENT)
    283    public boolean func_100011_g()
    284    {
    285        return this.field_100013_f;
    286    }
    287}