    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    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 getItemSpriteNumber()
    143    {
    144        return this.getItem().getSpriteNumber();
    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.getItem().isItemStackDamaged(this);
    253    }
    254
    255    /**
    256     * gets the damage of an itemstack, for displaying purposes
    257     */
    258    public int getItemDamageForDisplay()
    259    {
    260        return this.getItem().getItemDamageFromStackForDisplay(this);
    261    }
    262
    263    /**
    264     * gets the damage of an itemstack
    265     */
    266    public int getItemDamage()
    267    {
    268        return this.getItem().getItemDamageFromStack(this);
    269    }
    270
    271    /**
    272     * Sets the item damage of the ItemStack.
    273     */
    274    public void setItemDamage(int par1)
    275    {
    276        this.getItem().setItemDamageForStack(this, par1);
    277    }
    278
    279    /**
    280     * Returns the max damage an item in the stack can take.
    281     */
    282    public int getMaxDamage()
    283    {
    284        return this.getItem().getItemMaxDamageFromStack(this);
    285    }
    286
    287    public boolean func_96631_a(int par1, Random par2Random)
    288    {
    289        if (!this.isItemStackDamageable())
    290        {
    291            return false;
    292        }
    293        else
    294        {
    295            if (par1 > 0)
    296            {
    297                int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.unbreaking.effectId, this);
    298                int k = 0;
    299
    300                for (int l = 0; j > 0 && l < par1; ++l)
    301                {
    302                    if (EnchantmentDurability.func_92097_a(this, j, par2Random))
    303                    {
    304                        ++k;
    305                    }
    306                }
    307
    308                par1 -= k;
    309
    310                if (par1 <= 0)
    311                {
    312                    return false;
    313                }
    314            }
    315
    316            this.itemDamage += par1;
    317            return this.itemDamage > this.getMaxDamage();
    318        }
    319    }
    320
    321    /**
    322     * Damages the item in the ItemStack
    323     */
    324    public void damageItem(int par1, EntityLiving par2EntityLiving)
    325    {
    326        if (!(par2EntityLiving instanceof EntityPlayer) || !((EntityPlayer)par2EntityLiving).capabilities.isCreativeMode)
    327        {
    328            if (this.isItemStackDamageable())
    329            {
    330                if (this.func_96631_a(par1, par2EntityLiving.getRNG()))
    331                {
    332                    par2EntityLiving.renderBrokenItemStack(this);
    333
    334                    if (par2EntityLiving instanceof EntityPlayer)
    335                    {
    336                        ((EntityPlayer)par2EntityLiving).addStat(StatList.objectBreakStats[this.itemID], 1);
    337                    }
    338
    339                    --this.stackSize;
    340
    341                    if (this.stackSize < 0)
    342                    {
    343                        this.stackSize = 0;
    344                    }
    345
    346                    this.itemDamage = 0;
    347                }
    348            }
    349        }
    350    }
    351
    352    /**
    353     * Calls the corresponding fct in di
    354     */
    355    public void hitEntity(EntityLiving par1EntityLiving, EntityPlayer par2EntityPlayer)
    356    {
    357        boolean flag = Item.itemsList[this.itemID].hitEntity(this, par1EntityLiving, par2EntityPlayer);
    358
    359        if (flag)
    360        {
    361            par2EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1);
    362        }
    363    }
    364
    365    public void onBlockDestroyed(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer)
    366    {
    367        boolean flag = Item.itemsList[this.itemID].onBlockDestroyed(this, par1World, par2, par3, par4, par5, par6EntityPlayer);
    368
    369        if (flag)
    370        {
    371            par6EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1);
    372        }
    373    }
    374
    375    /**
    376     * Returns the damage against a given entity.
    377     */
    378    public int getDamageVsEntity(Entity par1Entity)
    379    {
    380        return Item.itemsList[this.itemID].getDamageVsEntity(par1Entity, this);
    381    }
    382
    383    /**
    384     * Checks if the itemStack object can harvest a specified block
    385     */
    386    public boolean canHarvestBlock(Block par1Block)
    387    {
    388        return Item.itemsList[this.itemID].canHarvestBlock(par1Block);
    389    }
    390
    391    public boolean interactWith(EntityLiving par1EntityLiving)
    392    {
    393        return Item.itemsList[this.itemID].itemInteractionForEntity(this, par1EntityLiving);
    394    }
    395
    396    /**
    397     * Returns a new stack with the same properties.
    398     */
    399    public ItemStack copy()
    400    {
    401        ItemStack itemstack = new ItemStack(this.itemID, this.stackSize, this.itemDamage);
    402
    403        if (this.stackTagCompound != null)
    404        {
    405            itemstack.stackTagCompound = (NBTTagCompound)this.stackTagCompound.copy();
    406        }
    407
    408        return itemstack;
    409    }
    410
    411    public static boolean areItemStackTagsEqual(ItemStack par0ItemStack, ItemStack par1ItemStack)
    412    {
    413        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);
    414    }
    415
    416    /**
    417     * compares ItemStack argument1 with ItemStack argument2; returns true if both ItemStacks are equal
    418     */
    419    public static boolean areItemStacksEqual(ItemStack par0ItemStack, ItemStack par1ItemStack)
    420    {
    421        return par0ItemStack == null && par1ItemStack == null ? true : (par0ItemStack != null && par1ItemStack != null ? par0ItemStack.isItemStackEqual(par1ItemStack) : false);
    422    }
    423
    424    /**
    425     * compares ItemStack argument to the instance ItemStack; returns true if both ItemStacks are equal
    426     */
    427    private boolean isItemStackEqual(ItemStack par1ItemStack)
    428    {
    429        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))));
    430    }
    431
    432    /**
    433     * compares ItemStack argument to the instance ItemStack; returns true if the Items contained in both ItemStacks are
    434     * equal
    435     */
    436    public boolean isItemEqual(ItemStack par1ItemStack)
    437    {
    438        return this.itemID == par1ItemStack.itemID && this.itemDamage == par1ItemStack.itemDamage;
    439    }
    440
    441    public String getItemName()
    442    {
    443        return Item.itemsList[this.itemID].getUnlocalizedName(this);
    444    }
    445
    446    /**
    447     * Creates a copy of a ItemStack, a null parameters will return a null.
    448     */
    449    public static ItemStack copyItemStack(ItemStack par0ItemStack)
    450    {
    451        return par0ItemStack == null ? null : par0ItemStack.copy();
    452    }
    453
    454    public String toString()
    455    {
    456        return this.stackSize + "x" + Item.itemsList[this.itemID].getUnlocalizedName() + "@" + this.itemDamage;
    457    }
    458
    459    /**
    460     * Called each tick as long the ItemStack in on player inventory. Used to progress the pickup animation and update
    461     * maps.
    462     */
    463    public void updateAnimation(World par1World, Entity par2Entity, int par3, boolean par4)
    464    {
    465        if (this.animationsToGo > 0)
    466        {
    467            --this.animationsToGo;
    468        }
    469
    470        Item.itemsList[this.itemID].onUpdate(this, par1World, par2Entity, par3, par4);
    471    }
    472
    473    public void onCrafting(World par1World, EntityPlayer par2EntityPlayer, int par3)
    474    {
    475        par2EntityPlayer.addStat(StatList.objectCraftStats[this.itemID], par3);
    476        Item.itemsList[this.itemID].onCreated(this, par1World, par2EntityPlayer);
    477    }
    478
    479    public int getMaxItemUseDuration()
    480    {
    481        return this.getItem().getMaxItemUseDuration(this);
    482    }
    483
    484    public EnumAction getItemUseAction()
    485    {
    486        return this.getItem().getItemUseAction(this);
    487    }
    488
    489    /**
    490     * Called when the player releases the use item button. Args: world, entityplayer, itemInUseCount
    491     */
    492    public void onPlayerStoppedUsing(World par1World, EntityPlayer par2EntityPlayer, int par3)
    493    {
    494        this.getItem().onPlayerStoppedUsing(this, par1World, par2EntityPlayer, par3);
    495    }
    496
    497    /**
    498     * Returns true if the ItemStack has an NBTTagCompound. Currently used to store enchantments.
    499     */
    500    public boolean hasTagCompound()
    501    {
    502        return this.stackTagCompound != null;
    503    }
    504
    505    /**
    506     * Returns the NBTTagCompound of the ItemStack.
    507     */
    508    public NBTTagCompound getTagCompound()
    509    {
    510        return this.stackTagCompound;
    511    }
    512
    513    public NBTTagList getEnchantmentTagList()
    514    {
    515        return this.stackTagCompound == null ? null : (NBTTagList)this.stackTagCompound.getTag("ench");
    516    }
    517
    518    /**
    519     * Assigns a NBTTagCompound to the ItemStack, minecraft validates that only non-stackable items can have it.
    520     */
    521    public void setTagCompound(NBTTagCompound par1NBTTagCompound)
    522    {
    523        this.stackTagCompound = par1NBTTagCompound;
    524    }
    525
    526    /**
    527     * returns the display name of the itemstack
    528     */
    529    public String getDisplayName()
    530    {
    531        String s = this.getItem().getItemDisplayName(this);
    532
    533        if (this.stackTagCompound != null && this.stackTagCompound.hasKey("display"))
    534        {
    535            NBTTagCompound nbttagcompound = this.stackTagCompound.getCompoundTag("display");
    536
    537            if (nbttagcompound.hasKey("Name"))
    538            {
    539                s = nbttagcompound.getString("Name");
    540            }
    541        }
    542
    543        return s;
    544    }
    545
    546    /**
    547     * Sets the item's name (used by anvil to rename the items).
    548     */
    549    public void setItemName(String par1Str)
    550    {
    551        if (this.stackTagCompound == null)
    552        {
    553            this.stackTagCompound = new NBTTagCompound("tag");
    554        }
    555
    556        if (!this.stackTagCompound.hasKey("display"))
    557        {
    558            this.stackTagCompound.setCompoundTag("display", new NBTTagCompound());
    559        }
    560
    561        this.stackTagCompound.getCompoundTag("display").setString("Name", par1Str);
    562    }
    563
    564    /**
    565     * Returns true if the itemstack has a display name
    566     */
    567    public boolean hasDisplayName()
    568    {
    569        return this.stackTagCompound == null ? false : (!this.stackTagCompound.hasKey("display") ? false : this.stackTagCompound.getCompoundTag("display").hasKey("Name"));
    570    }
    571
    572    @SideOnly(Side.CLIENT)
    573
    574    /**
    575     * Return a list of strings containing information about the item
    576     */
    577    public List getTooltip(EntityPlayer par1EntityPlayer, boolean par2)
    578    {
    579        ArrayList arraylist = new ArrayList();
    580        Item item = Item.itemsList[this.itemID];
    581        String s = this.getDisplayName();
    582
    583        if (this.hasDisplayName())
    584        {
    585            s = EnumChatFormatting.ITALIC + s + EnumChatFormatting.RESET;
    586        }
    587
    588        if (par2)
    589        {
    590            String s1 = "";
    591
    592            if (s.length() > 0)
    593            {
    594                s = s + " (";
    595                s1 = ")";
    596            }
    597
    598            if (this.getHasSubtypes())
    599            {
    600                s = s + String.format("#%04d/%d%s", new Object[] {Integer.valueOf(this.itemID), Integer.valueOf(this.itemDamage), s1});
    601            }
    602            else
    603            {
    604                s = s + String.format("#%04d%s", new Object[] {Integer.valueOf(this.itemID), s1});
    605            }
    606        }
    607        else if (!this.hasDisplayName() && this.itemID == Item.map.itemID)
    608        {
    609            s = s + " #" + this.itemDamage;
    610        }
    611
    612        arraylist.add(s);
    613        item.addInformation(this, par1EntityPlayer, arraylist, par2);
    614
    615        if (this.hasTagCompound())
    616        {
    617            NBTTagList nbttaglist = this.getEnchantmentTagList();
    618
    619            if (nbttaglist != null)
    620            {
    621                for (int i = 0; i < nbttaglist.tagCount(); ++i)
    622                {
    623                    short short1 = ((NBTTagCompound)nbttaglist.tagAt(i)).getShort("id");
    624                    short short2 = ((NBTTagCompound)nbttaglist.tagAt(i)).getShort("lvl");
    625
    626                    if (Enchantment.enchantmentsList[short1] != null)
    627                    {
    628                        arraylist.add(Enchantment.enchantmentsList[short1].getTranslatedName(short2));
    629                    }
    630                }
    631            }
    632
    633            if (this.stackTagCompound.hasKey("display"))
    634            {
    635                NBTTagCompound nbttagcompound = this.stackTagCompound.getCompoundTag("display");
    636
    637                if (nbttagcompound.hasKey("color"))
    638                {
    639                    if (par2)
    640                    {
    641                        arraylist.add("Color: #" + Integer.toHexString(nbttagcompound.getInteger("color")).toUpperCase());
    642                    }
    643                    else
    644                    {
    645                        arraylist.add(EnumChatFormatting.ITALIC + StatCollector.translateToLocal("item.dyed"));
    646                    }
    647                }
    648
    649                if (nbttagcompound.hasKey("Lore"))
    650                {
    651                    NBTTagList nbttaglist1 = nbttagcompound.getTagList("Lore");
    652
    653                    if (nbttaglist1.tagCount() > 0)
    654                    {
    655                        for (int j = 0; j < nbttaglist1.tagCount(); ++j)
    656                        {
    657                            arraylist.add(EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.ITALIC + ((NBTTagString)nbttaglist1.tagAt(j)).data);
    658                        }
    659                    }
    660                }
    661            }
    662        }
    663
    664        if (par2 && this.isItemDamaged())
    665        {
    666            arraylist.add("Durability: " + (this.getMaxDamage() - this.getItemDamageForDisplay()) + " / " + this.getMaxDamage());
    667        }
    668
    669        return arraylist;
    670    }
    671
    672    @SideOnly(Side.CLIENT)
    673    public boolean hasEffect()
    674    {
    675        return this.getItem().hasEffect(this);
    676    }
    677
    678    @SideOnly(Side.CLIENT)
    679    public EnumRarity getRarity()
    680    {
    681        return this.getItem().getRarity(this);
    682    }
    683
    684    /**
    685     * True if it is a tool and has no enchantments to begin with
    686     */
    687    public boolean isItemEnchantable()
    688    {
    689        return !this.getItem().isItemTool(this) ? false : !this.isItemEnchanted();
    690    }
    691
    692    /**
    693     * Adds an enchantment with a desired level on the ItemStack.
    694     */
    695    public void addEnchantment(Enchantment par1Enchantment, int par2)
    696    {
    697        if (this.stackTagCompound == null)
    698        {
    699            this.setTagCompound(new NBTTagCompound());
    700        }
    701
    702        if (!this.stackTagCompound.hasKey("ench"))
    703        {
    704            this.stackTagCompound.setTag("ench", new NBTTagList("ench"));
    705        }
    706
    707        NBTTagList nbttaglist = (NBTTagList)this.stackTagCompound.getTag("ench");
    708        NBTTagCompound nbttagcompound = new NBTTagCompound();
    709        nbttagcompound.setShort("id", (short)par1Enchantment.effectId);
    710        nbttagcompound.setShort("lvl", (short)((byte)par2));
    711        nbttaglist.appendTag(nbttagcompound);
    712    }
    713
    714    /**
    715     * True if the item has enchantment data
    716     */
    717    public boolean isItemEnchanted()
    718    {
    719        return this.stackTagCompound != null && this.stackTagCompound.hasKey("ench");
    720    }
    721
    722    public void setTagInfo(String par1Str, NBTBase par2NBTBase)
    723    {
    724        if (this.stackTagCompound == null)
    725        {
    726            this.setTagCompound(new NBTTagCompound());
    727        }
    728
    729        this.stackTagCompound.setTag(par1Str, par2NBTBase);
    730    }
    731
    732    public boolean func_82835_x()
    733    {
    734        return this.getItem().func_82788_x();
    735    }
    736
    737    /**
    738     * Return whether this stack is on an item frame.
    739     */
    740    public boolean isOnItemFrame()
    741    {
    742        return this.itemFrame != null;
    743    }
    744
    745    /**
    746     * Set the item frame this stack is on.
    747     */
    748    public void setItemFrame(EntityItemFrame par1EntityItemFrame)
    749    {
    750        this.itemFrame = par1EntityItemFrame;
    751    }
    752
    753    /**
    754     * Return the item frame this stack is on. Returns null if not on an item frame.
    755     */
    756    public EntityItemFrame getItemFrame()
    757    {
    758        return this.itemFrame;
    759    }
    760
    761    /**
    762     * Get this stack's repair cost, or 0 if no repair cost is defined.
    763     */
    764    public int getRepairCost()
    765    {
    766        return this.hasTagCompound() && this.stackTagCompound.hasKey("RepairCost") ? this.stackTagCompound.getInteger("RepairCost") : 0;
    767    }
    768
    769    /**
    770     * Set this stack's repair cost.
    771     */
    772    public void setRepairCost(int par1)
    773    {
    774        if (!this.hasTagCompound())
    775        {
    776            this.stackTagCompound = new NBTTagCompound("tag");
    777        }
    778
    779        this.stackTagCompound.setInteger("RepairCost", par1);
    780    }
    781}