    001package net.minecraft.item;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.ArrayList;
    006import java.util.List;
    007import java.util.Random;
    008import net.minecraft.block.Block;
    009import net.minecraft.enchantment.Enchantment;
    010import net.minecraft.enchantment.EnchantmentDurability;
    011import net.minecraft.enchantment.EnchantmentHelper;
    012import net.minecraft.entity.Entity;
    013import net.minecraft.entity.EntityLiving;
    014import net.minecraft.entity.item.EntityItemFrame;
    015import net.minecraft.entity.player.EntityPlayer;
    016import net.minecraft.nbt.NBTBase;
    017import net.minecraft.nbt.NBTTagCompound;
    018import net.minecraft.nbt.NBTTagList;
    019import net.minecraft.nbt.NBTTagString;
    020import net.minecraft.stats.StatList;
    021import net.minecraft.util.EnumChatFormatting;
    022import net.minecraft.util.Icon;
    023import net.minecraft.util.StatCollector;
    024import net.minecraft.world.World;
    025
    026public final class ItemStack
    027{
    028    /** Size of the stack. */
    029    public int stackSize;
    030
    031    /**
    032     * Number of animation frames to go when receiving an item (by walking into it, for example).
    033     */
    034    public int animationsToGo;
    035
    036    /** ID of the item. */
    037    public int itemID;
    038
    039    /**
    040     * A NBTTagMap containing data about an ItemStack. Can only be used for non stackable items
    041     */
    042    public NBTTagCompound stackTagCompound;
    043
    044    /** Damage dealt to the item or number of use. Raise when using items. */
    045    private int itemDamage;
    046
    047    /** Item frame this stack is on, or null if not on an item frame. */
    048    private EntityItemFrame itemFrame;
    049
    050    public ItemStack(Block par1Block)
    051    {
    052        this(par1Block, 1);
    053    }
    054
    055    public ItemStack(Block par1Block, int par2)
    056    {
    057        this(par1Block.blockID, par2, 0);
    058    }
    059
    060    public ItemStack(Block par1Block, int par2, int par3)
    061    {
    062        this(par1Block.blockID, par2, par3);
    063    }
    064
    065    public ItemStack(Item par1Item)
    066    {
    067        this(par1Item.itemID, 1, 0);
    068    }
    069
    070    public ItemStack(Item par1Item, int par2)
    071    {
    072        this(par1Item.itemID, par2, 0);
    073    }
    074
    075    public ItemStack(Item par1Item, int par2, int par3)
    076    {
    077        this(par1Item.itemID, par2, par3);
    078    }
    079
    080    public ItemStack(int par1, int par2, int par3)
    081    {
    082        this.stackSize = 0;
    083        this.itemFrame = null;
    084        this.itemID = par1;
    085        this.stackSize = par2;
    086        this.itemDamage = par3;
    087
    088        if (this.itemDamage < 0)
    089        {
    090            this.itemDamage = 0;
    091        }
    092    }
    093
    094    public static ItemStack loadItemStackFromNBT(NBTTagCompound par0NBTTagCompound)
    095    {
    096        ItemStack itemstack = new ItemStack();
    097        itemstack.readFromNBT(par0NBTTagCompound);
    098        return itemstack.getItem() != null ? itemstack : null;
    099    }
    100
    101    private ItemStack()
    102    {
    103        this.stackSize = 0;
    104        this.itemFrame = null;
    105    }
    106
    107    /**
    108     * Remove the argument from the stack size. Return a new stack object with argument size.
    109     */
    110    public ItemStack splitStack(int par1)
    111    {
    112        ItemStack itemstack = new ItemStack(this.itemID, par1, this.itemDamage);
    113
    114        if (this.stackTagCompound != null)
    115        {
    116            itemstack.stackTagCompound = (NBTTagCompound)this.stackTagCompound.copy();
    117        }
    118
    119        this.stackSize -= par1;
    120        return itemstack;
    121    }
    122
    123    /**
    124     * Returns the object corresponding to the stack.
    125     */
    126    public Item getItem()
    127    {
    128        return Item.itemsList[this.itemID];
    129    }
    130
    131    @SideOnly(Side.CLIENT)
    132
    133    /**
    134     * Returns the icon index of the current stack.
    135     */
    136    public Icon getIconIndex()
    137    {
    138        return this.getItem().getIconIndex(this);
    139    }
    140
    141    @SideOnly(Side.CLIENT)
    142    public int func_94608_d()
    143    {
    144        return this.getItem().func_94901_k();
    145    }
    146
    147    public boolean tryPlaceItemIntoWorld(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5, int par6, float par7, float par8, float par9)
    148    {
    149        boolean flag = this.getItem().onItemUse(this, par1EntityPlayer, par2World, par3, par4, par5, par6, par7, par8, par9);
    150
    151        if (flag)
    152        {
    153            par1EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1);
    154        }
    155
    156        return flag;
    157    }
    158
    159    /**
    160     * Returns the strength of the stack against a given block.
    161     */
    162    public float getStrVsBlock(Block par1Block)
    163    {
    164        return this.getItem().getStrVsBlock(this, par1Block);
    165    }
    166
    167    /**
    168     * Called whenever this item stack is equipped and right clicked. Returns the new item stack to put in the position
    169     * where this item is. Args: world, player
    170     */
    171    public ItemStack useItemRightClick(World par1World, EntityPlayer par2EntityPlayer)
    172    {
    173        return this.getItem().onItemRightClick(this, par1World, par2EntityPlayer);
    174    }
    175
    176    public ItemStack onFoodEaten(World par1World, EntityPlayer par2EntityPlayer)
    177    {
    178        return this.getItem().onEaten(this, par1World, par2EntityPlayer);
    179    }
    180
    181    /**
    182     * Write the stack fields to a NBT object. Return the new NBT object.
    183     */
    184    public NBTTagCompound writeToNBT(NBTTagCompound par1NBTTagCompound)
    185    {
    186        par1NBTTagCompound.setShort("id", (short)this.itemID);
    187        par1NBTTagCompound.setByte("Count", (byte)this.stackSize);
    188        par1NBTTagCompound.setShort("Damage", (short)this.itemDamage);
    189
    190        if (this.stackTagCompound != null)
    191        {
    192            par1NBTTagCompound.setTag("tag", this.stackTagCompound);
    193        }
    194
    195        return par1NBTTagCompound;
    196    }
    197
    198    /**
    199     * Read the stack fields from a NBT object.
    200     */
    201    public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    202    {
    203        this.itemID = par1NBTTagCompound.getShort("id");
    204        this.stackSize = par1NBTTagCompound.getByte("Count");
    205        this.itemDamage = par1NBTTagCompound.getShort("Damage");
    206
    207        if (this.itemDamage < 0)
    208        {
    209            this.itemDamage = 0;
    210        }
    211
    212        if (par1NBTTagCompound.hasKey("tag"))
    213        {
    214            this.stackTagCompound = par1NBTTagCompound.getCompoundTag("tag");
    215        }
    216    }
    217
    218    /**
    219     * Returns maximum size of the stack.
    220     */
    221    public int getMaxStackSize()
    222    {
    223        return this.getItem().getItemStackLimit();
    224    }
    225
    226    /**
    227     * Returns true if the ItemStack can hold 2 or more units of the item.
    228     */
    229    public boolean isStackable()
    230    {
    231        return this.getMaxStackSize() > 1 && (!this.isItemStackDamageable() || !this.isItemDamaged());
    232    }
    233
    234    /**
    235     * true if this itemStack is damageable
    236     */
    237    public boolean isItemStackDamageable()
    238    {
    239        return Item.itemsList[this.itemID].getMaxDamage() > 0;
    240    }
    241
    242    public boolean getHasSubtypes()
    243    {
    244        return Item.itemsList[this.itemID].getHasSubtypes();
    245    }
    246
    247    /**
    248     * returns true when a damageable item is damaged
    249     */
    250    public boolean isItemDamaged()
    251    {
    252        return this.isItemStackDamageable() && this.itemDamage > 0;
    253    }
    254
    255    /**
    256     * gets the damage of an itemstack, for displaying purposes
    257     */
    258    public int getItemDamageForDisplay()
    259    {
    260        return this.itemDamage;
    261    }
    262
    263    /**
    264     * gets the damage of an itemstack
    265     */
    266    public int getItemDamage()
    267    {
    268        return this.itemDamage;
    269    }
    270
    271    /**
    272     * Sets the item damage of the ItemStack.
    273     */
    274    public void setItemDamage(int par1)
    275    {
    276        this.itemDamage = par1;
    277
    278        if (this.itemDamage < 0)
    279        {
    280            this.itemDamage = 0;
    281        }
    282    }
    283
    284    /**
    285     * Returns the max damage an item in the stack can take.
    286     */
    287    public int getMaxDamage()
    288    {
    289        return Item.itemsList[this.itemID].getMaxDamage();
    290    }
    291
    292    public boolean func_96631_a(int par1, Random par2Random)
    293    {
    294        if (!this.isItemStackDamageable())
    295        {
    296            return false;
    297        }
    298        else
    299        {
    300            if (par1 > 0)
    301            {
    302                int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.unbreaking.effectId, this);
    303                int k = 0;
    304
    305                for (int l = 0; j > 0 && l < par1; ++l)
    306                {
    307                    if (EnchantmentDurability.func_92097_a(this, j, par2Random))
    308                    {
    309                        ++k;
    310                    }
    311                }
    312
    313                par1 -= k;
    314
    315                if (par1 <= 0)
    316                {
    317                    return false;
    318                }
    319            }
    320
    321            this.itemDamage += par1;
    322            return this.itemDamage > this.getMaxDamage();
    323        }
    324    }
    325
    326    /**
    327     * Damages the item in the ItemStack
    328     */
    329    public void damageItem(int par1, EntityLiving par2EntityLiving)
    330    {
    331        if (!(par2EntityLiving instanceof EntityPlayer) || !((EntityPlayer)par2EntityLiving).capabilities.isCreativeMode)
    332        {
    333            if (this.isItemStackDamageable())
    334            {
    335                if (this.func_96631_a(par1, par2EntityLiving.getRNG()))
    336                {
    337                    par2EntityLiving.renderBrokenItemStack(this);
    338
    339                    if (par2EntityLiving instanceof EntityPlayer)
    340                    {
    341                        ((EntityPlayer)par2EntityLiving).addStat(StatList.objectBreakStats[this.itemID], 1);
    342                    }
    343
    344                    --this.stackSize;
    345
    346                    if (this.stackSize < 0)
    347                    {
    348                        this.stackSize = 0;
    349                    }
    350
    351                    this.itemDamage = 0;
    352                }
    353            }
    354        }
    355    }
    356
    357    /**
    358     * Calls the corresponding fct in di
    359     */
    360    public void hitEntity(EntityLiving par1EntityLiving, EntityPlayer par2EntityPlayer)
    361    {
    362        boolean flag = Item.itemsList[this.itemID].hitEntity(this, par1EntityLiving, par2EntityPlayer);
    363
    364        if (flag)
    365        {
    366            par2EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1);
    367        }
    368    }
    369
    370    public void onBlockDestroyed(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer)
    371    {
    372        boolean flag = Item.itemsList[this.itemID].onBlockDestroyed(this, par1World, par2, par3, par4, par5, par6EntityPlayer);
    373
    374        if (flag)
    375        {
    376            par6EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1);
    377        }
    378    }
    379
    380    /**
    381     * Returns the damage against a given entity.
    382     */
    383    public int getDamageVsEntity(Entity par1Entity)
    384    {
    385        return Item.itemsList[this.itemID].getDamageVsEntity(par1Entity);
    386    }
    387
    388    /**
    389     * Checks if the itemStack object can harvest a specified block
    390     */
    391    public boolean canHarvestBlock(Block par1Block)
    392    {
    393        return Item.itemsList[this.itemID].canHarvestBlock(par1Block);
    394    }
    395
    396    public boolean interactWith(EntityLiving par1EntityLiving)
    397    {
    398        return Item.itemsList[this.itemID].itemInteractionForEntity(this, par1EntityLiving);
    399    }
    400
    401    /**
    402     * Returns a new stack with the same properties.
    403     */
    404    public ItemStack copy()
    405    {
    406        ItemStack itemstack = new ItemStack(this.itemID, this.stackSize, this.itemDamage);
    407
    408        if (this.stackTagCompound != null)
    409        {
    410            itemstack.stackTagCompound = (NBTTagCompound)this.stackTagCompound.copy();
    411        }
    412
    413        return itemstack;
    414    }
    415
    416    public static boolean areItemStackTagsEqual(ItemStack par0ItemStack, ItemStack par1ItemStack)
    417    {
    418        return par0ItemStack == null && par1ItemStack == null ? true : (par0ItemStack != null && par1ItemStack != null ? (par0ItemStack.stackTagCompound == null && par1ItemStack.stackTagCompound != null ? false : par0ItemStack.stackTagCompound == null || par0ItemStack.stackTagCompound.equals(par1ItemStack.stackTagCompound)) : false);
    419    }
    420
    421    /**
    422     * compares ItemStack argument1 with ItemStack argument2; returns true if both ItemStacks are equal
    423     */
    424    public static boolean areItemStacksEqual(ItemStack par0ItemStack, ItemStack par1ItemStack)
    425    {
    426        return par0ItemStack == null && par1ItemStack == null ? true : (par0ItemStack != null && par1ItemStack != null ? par0ItemStack.isItemStackEqual(par1ItemStack) : false);
    427    }
    428
    429    /**
    430     * compares ItemStack argument to the instance ItemStack; returns true if both ItemStacks are equal
    431     */
    432    private boolean isItemStackEqual(ItemStack par1ItemStack)
    433    {
    434        return this.stackSize != par1ItemStack.stackSize ? false : (this.itemID != par1ItemStack.itemID ? false : (this.itemDamage != par1ItemStack.itemDamage ? false : (this.stackTagCompound == null && par1ItemStack.stackTagCompound != null ? false : this.stackTagCompound == null || this.stackTagCompound.equals(par1ItemStack.stackTagCompound))));
    435    }
    436
    437    /**
    438     * compares ItemStack argument to the instance ItemStack; returns true if the Items contained in both ItemStacks are
    439     * equal
    440     */
    441    public boolean isItemEqual(ItemStack par1ItemStack)
    442    {
    443        return this.itemID == par1ItemStack.itemID && this.itemDamage == par1ItemStack.itemDamage;
    444    }
    445
    446    public String getItemName()
    447    {
    448        return Item.itemsList[this.itemID].getUnlocalizedName(this);
    449    }
    450
    451    /**
    452     * Creates a copy of a ItemStack, a null parameters will return a null.
    453     */
    454    public static ItemStack copyItemStack(ItemStack par0ItemStack)
    455    {
    456        return par0ItemStack == null ? null : par0ItemStack.copy();
    457    }
    458
    459    public String toString()
    460    {
    461        return this.stackSize + "x" + Item.itemsList[this.itemID].getUnlocalizedName() + "@" + this.itemDamage;
    462    }
    463
    464    /**
    465     * Called each tick as long the ItemStack in on player inventory. Used to progress the pickup animation and update
    466     * maps.
    467     */
    468    public void updateAnimation(World par1World, Entity par2Entity, int par3, boolean par4)
    469    {
    470        if (this.animationsToGo > 0)
    471        {
    472            --this.animationsToGo;
    473        }
    474
    475        Item.itemsList[this.itemID].onUpdate(this, par1World, par2Entity, par3, par4);
    476    }
    477
    478    public void onCrafting(World par1World, EntityPlayer par2EntityPlayer, int par3)
    479    {
    480        par2EntityPlayer.addStat(StatList.objectCraftStats[this.itemID], par3);
    481        Item.itemsList[this.itemID].onCreated(this, par1World, par2EntityPlayer);
    482    }
    483
    484    public int getMaxItemUseDuration()
    485    {
    486        return this.getItem().getMaxItemUseDuration(this);
    487    }
    488
    489    public EnumAction getItemUseAction()
    490    {
    491        return this.getItem().getItemUseAction(this);
    492    }
    493
    494    /**
    495     * Called when the player releases the use item button. Args: world, entityplayer, itemInUseCount
    496     */
    497    public void onPlayerStoppedUsing(World par1World, EntityPlayer par2EntityPlayer, int par3)
    498    {
    499        this.getItem().onPlayerStoppedUsing(this, par1World, par2EntityPlayer, par3);
    500    }
    501
    502    /**
    503     * Returns true if the ItemStack has an NBTTagCompound. Currently used to store enchantments.
    504     */
    505    public boolean hasTagCompound()
    506    {
    507        return this.stackTagCompound != null;
    508    }
    509
    510    /**
    511     * Returns the NBTTagCompound of the ItemStack.
    512     */
    513    public NBTTagCompound getTagCompound()
    514    {
    515        return this.stackTagCompound;
    516    }
    517
    518    public NBTTagList getEnchantmentTagList()
    519    {
    520        return this.stackTagCompound == null ? null : (NBTTagList)this.stackTagCompound.getTag("ench");
    521    }
    522
    523    /**
    524     * Assigns a NBTTagCompound to the ItemStack, minecraft validates that only non-stackable items can have it.
    525     */
    526    public void setTagCompound(NBTTagCompound par1NBTTagCompound)
    527    {
    528        this.stackTagCompound = par1NBTTagCompound;
    529    }
    530
    531    /**
    532     * returns the display name of the itemstack
    533     */
    534    public String getDisplayName()
    535    {
    536        String s = this.getItem().getItemDisplayName(this);
    537
    538        if (this.stackTagCompound != null && this.stackTagCompound.hasKey("display"))
    539        {
    540            NBTTagCompound nbttagcompound = this.stackTagCompound.getCompoundTag("display");
    541
    542            if (nbttagcompound.hasKey("Name"))
    543            {
    544                s = nbttagcompound.getString("Name");
    545            }
    546        }
    547
    548        return s;
    549    }
    550
    551    /**
    552     * Sets the item's name (used by anvil to rename the items).
    553     */
    554    public void setItemName(String par1Str)
    555    {
    556        if (this.stackTagCompound == null)
    557        {
    558            this.stackTagCompound = new NBTTagCompound("tag");
    559        }
    560
    561        if (!this.stackTagCompound.hasKey("display"))
    562        {
    563            this.stackTagCompound.setCompoundTag("display", new NBTTagCompound());
    564        }
    565
    566        this.stackTagCompound.getCompoundTag("display").setString("Name", par1Str);
    567    }
    568
    569    /**
    570     * Returns true if the itemstack has a display name
    571     */
    572    public boolean hasDisplayName()
    573    {
    574        return this.stackTagCompound == null ? false : (!this.stackTagCompound.hasKey("display") ? false : this.stackTagCompound.getCompoundTag("display").hasKey("Name"));
    575    }
    576
    577    @SideOnly(Side.CLIENT)
    578
    579    /**
    580     * Return a list of strings containing information about the item
    581     */
    582    public List getTooltip(EntityPlayer par1EntityPlayer, boolean par2)
    583    {
    584        ArrayList arraylist = new ArrayList();
    585        Item item = Item.itemsList[this.itemID];
    586        String s = this.getDisplayName();
    587
    588        if (this.hasDisplayName())
    589        {
    590            s = EnumChatFormatting.ITALIC + s + EnumChatFormatting.RESET;
    591        }
    592
    593        if (par2)
    594        {
    595            String s1 = "";
    596
    597            if (s.length() > 0)
    598            {
    599                s = s + " (";
    600                s1 = ")";
    601            }
    602
    603            if (this.getHasSubtypes())
    604            {
    605                s = s + String.format("#%04d/%d%s", new Object[] {Integer.valueOf(this.itemID), Integer.valueOf(this.itemDamage), s1});
    606            }
    607            else
    608            {
    609                s = s + String.format("#%04d%s", new Object[] {Integer.valueOf(this.itemID), s1});
    610            }
    611        }
    612        else if (!this.hasDisplayName() && this.itemID == Item.map.itemID)
    613        {
    614            s = s + " #" + this.itemDamage;
    615        }
    616
    617        arraylist.add(s);
    618        item.addInformation(this, par1EntityPlayer, arraylist, par2);
    619
    620        if (this.hasTagCompound())
    621        {
    622            NBTTagList nbttaglist = this.getEnchantmentTagList();
    623
    624            if (nbttaglist != null)
    625            {
    626                for (int i = 0; i < nbttaglist.tagCount(); ++i)
    627                {
    628                    short short1 = ((NBTTagCompound)nbttaglist.tagAt(i)).getShort("id");
    629                    short short2 = ((NBTTagCompound)nbttaglist.tagAt(i)).getShort("lvl");
    630
    631                    if (Enchantment.enchantmentsList[short1] != null)
    632                    {
    633                        arraylist.add(Enchantment.enchantmentsList[short1].getTranslatedName(short2));
    634                    }
    635                }
    636            }
    637
    638            if (this.stackTagCompound.hasKey("display"))
    639            {
    640                NBTTagCompound nbttagcompound = this.stackTagCompound.getCompoundTag("display");
    641
    642                if (nbttagcompound.hasKey("color"))
    643                {
    644                    if (par2)
    645                    {
    646                        arraylist.add("Color: #" + Integer.toHexString(nbttagcompound.getInteger("color")).toUpperCase());
    647                    }
    648                    else
    649                    {
    650                        arraylist.add(EnumChatFormatting.ITALIC + StatCollector.translateToLocal("item.dyed"));
    651                    }
    652                }
    653
    654                if (nbttagcompound.hasKey("Lore"))
    655                {
    656                    NBTTagList nbttaglist1 = nbttagcompound.getTagList("Lore");
    657
    658                    if (nbttaglist1.tagCount() > 0)
    659                    {
    660                        for (int j = 0; j < nbttaglist1.tagCount(); ++j)
    661                        {
    662                            arraylist.add(EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.ITALIC + ((NBTTagString)nbttaglist1.tagAt(j)).data);
    663                        }
    664                    }
    665                }
    666            }
    667        }
    668
    669        if (par2 && this.isItemDamaged())
    670        {
    671            arraylist.add("Durability: " + (this.getMaxDamage() - this.getItemDamageForDisplay()) + " / " + this.getMaxDamage());
    672        }
    673
    674        return arraylist;
    675    }
    676
    677    @SideOnly(Side.CLIENT)
    678    public boolean hasEffect()
    679    {
    680        return this.getItem().hasEffect(this);
    681    }
    682
    683    @SideOnly(Side.CLIENT)
    684    public EnumRarity getRarity()
    685    {
    686        return this.getItem().getRarity(this);
    687    }
    688
    689    /**
    690     * True if it is a tool and has no enchantments to begin with
    691     */
    692    public boolean isItemEnchantable()
    693    {
    694        return !this.getItem().isItemTool(this) ? false : !this.isItemEnchanted();
    695    }
    696
    697    /**
    698     * Adds an enchantment with a desired level on the ItemStack.
    699     */
    700    public void addEnchantment(Enchantment par1Enchantment, int par2)
    701    {
    702        if (this.stackTagCompound == null)
    703        {
    704            this.setTagCompound(new NBTTagCompound());
    705        }
    706
    707        if (!this.stackTagCompound.hasKey("ench"))
    708        {
    709            this.stackTagCompound.setTag("ench", new NBTTagList("ench"));
    710        }
    711
    712        NBTTagList nbttaglist = (NBTTagList)this.stackTagCompound.getTag("ench");
    713        NBTTagCompound nbttagcompound = new NBTTagCompound();
    714        nbttagcompound.setShort("id", (short)par1Enchantment.effectId);
    715        nbttagcompound.setShort("lvl", (short)((byte)par2));
    716        nbttaglist.appendTag(nbttagcompound);
    717    }
    718
    719    /**
    720     * True if the item has enchantment data
    721     */
    722    public boolean isItemEnchanted()
    723    {
    724        return this.stackTagCompound != null && this.stackTagCompound.hasKey("ench");
    725    }
    726
    727    public void setTagInfo(String par1Str, NBTBase par2NBTBase)
    728    {
    729        if (this.stackTagCompound == null)
    730        {
    731            this.setTagCompound(new NBTTagCompound());
    732        }
    733
    734        this.stackTagCompound.setTag(par1Str, par2NBTBase);
    735    }
    736
    737    public boolean func_82835_x()
    738    {
    739        return this.getItem().func_82788_x();
    740    }
    741
    742    /**
    743     * Return whether this stack is on an item frame.
    744     */
    745    public boolean isOnItemFrame()
    746    {
    747        return this.itemFrame != null;
    748    }
    749
    750    /**
    751     * Set the item frame this stack is on.
    752     */
    753    public void setItemFrame(EntityItemFrame par1EntityItemFrame)
    754    {
    755        this.itemFrame = par1EntityItemFrame;
    756    }
    757
    758    /**
    759     * Return the item frame this stack is on. Returns null if not on an item frame.
    760     */
    761    public EntityItemFrame getItemFrame()
    762    {
    763        return this.itemFrame;
    764    }
    765
    766    /**
    767     * Get this stack's repair cost, or 0 if no repair cost is defined.
    768     */
    769    public int getRepairCost()
    770    {
    771        return this.hasTagCompound() && this.stackTagCompound.hasKey("RepairCost") ? this.stackTagCompound.getInteger("RepairCost") : 0;
    772    }
    773
    774    /**
    775     * Set this stack's repair cost.
    776     */
    777    public void setRepairCost(int par1)
    778    {
    779        if (!this.hasTagCompound())
    780        {
    781            this.stackTagCompound = new NBTTagCompound("tag");
    782        }
    783
    784        this.stackTagCompound.setInteger("RepairCost", par1);
    785    }
    786}