    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}