Jump to content

IItemHandler and Capability attempt [1.10.2]


Alexiy

Recommended Posts

Here is my first attempt at using Capability and IItemHandler. The tile seems to work fine, but I would like someone's review to verify that I did this right or if something can be improved.

 

public class TileStrongChest extends GeneralTileEntity implements IItemHandlerModifiable
{
    final static public String CHESTTYPE="Chest type",ITEMSTACK="Item stack";
    public int type;
    ItemStack[] storage;
    static public Capability<IItemHandler> iItemHandler=CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
    public ItemStackHandler itemStackHandler;
    public TileStrongChest(){super();}
    public TileStrongChest(int metadata)
    {
        super();
        type=metadata;
        storage=new ItemStack[metadata==0 ? 54 : metadata==1 ? 81 : 108];
        itemStackHandler=new ItemStackHandler(storage);
    }

    @Override
    public boolean hasCapability(Capability<?> capability, EnumFacing facing)
    {
        if(capability==iItemHandler) return true;
        return super.hasCapability(capability, facing);
    }

    @Override
    public <T> T getCapability(Capability<T> capability, EnumFacing facing)
    {
        if(capability==iItemHandler) return (T) this;
        return super.getCapability(capability, facing);
    }

    @Nullable
    @Override
    public ITextComponent getDisplayName()
    {
        int stacks=0;
        for (int i = 0; i < getSlots(); i++)
        {
            if(storage[i]!=null)stacks++;
        }
        return new TextComponentString(stacks+"/"+ getSlots());
    }

  
    @Override
    public int getSlots()
    {
        return storage.length;
    }

   
    @Override
    public ItemStack getStackInSlot(int slot)
    {
        return storage[slot];
    }

  
    @Override
    public ItemStack insertItem(int slot, ItemStack stack, boolean simulate)
    {
        return itemStackHandler.insertItem(slot,stack,simulate);
    }

   
    @Override
    public ItemStack extractItem(int slot, int amount, boolean simulate)
    {

        return itemStackHandler.extractItem(slot,amount,simulate);
    }

    
    @Override
    public void setStackInSlot(int slot, ItemStack stack)
    {
        storage[slot]=stack;
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound)
    {
        NBTTagCompound nbtTagCompound=super.writeToNBT(compound);
        int number=0;
        for(ItemStack itemStack: storage)
        {
            if(itemStack!=null)
            {

                NBTTagCompound item=itemStack.writeToNBT(new NBTTagCompound());
                compound.setTag(ITEMSTACK+number,item);
            }
            number++;
        }
        nbtTagCompound.setShort(CHESTTYPE, (short) type);
        return nbtTagCompound;
    }

    @Override
    public void readFromNBT(NBTTagCompound compound)
    {
        super.readFromNBT(compound);
        type=compound.getShort(CHESTTYPE);
        switch (type)
        {
            case 0: storage=new ItemStack[54];break;
            case 1: storage=new ItemStack[81];break;
            case 2: storage=new ItemStack[108];break;
        }
        for (int i = 0; i < storage.length; i++)
        {
            ItemStack itemStack=ItemStack.loadItemStackFromNBT(compound.getCompoundTag(ITEMSTACK+i));
            if(itemStack!=null)storage[i]=itemStack;
        }
        itemStackHandler=new ItemStackHandler(storage);
    }
}

Link to comment
Share on other sites

The whole point of the Capability system is that you don't implement interfaces on your

TileEntity

, instead you store the objects in the

TileEntity

and override the

ICapabilityProvider

methods to return them. Forge's documentation explains this in more detail here. I also have a simple explanation here.

 

  • Don't implement
    IItemHandler

    on your

    TileEntity

    .

  • Either use the
    CapabilityItemHandler.ITEM_HANDLER_CAPABILITY

    field directly or annotate your own field with

    @CapabilityInject

    . Don't use the existing field to initialise your own.

  • Don't store the
    ItemStack

    array, only interact with your inventory through the

    ItemStackHandler


  • ItemStackHandler

    implements

    INBTSerializable

    , use this to write it to and read it from NBT

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

All right, I refactored it, now it looks like this:

public class TileStrongChest extends GeneralTileEntity
{
    final static public String CHESTTYPE = "Chest type", ITEMSTACKS = "Item stacks";
    public int type;

    public ItemStackHandler itemStackHandler;
    public TileStrongChest() {super();}

    public TileStrongChest(int metadata)
    {
        super();
        type = metadata;
        itemStackHandler=new ItemStackHandler(metadata==0 ? 54 : metadata==1 ? 81 : 108);
    }

    @Override
    public boolean hasCapability(Capability<?> capability, EnumFacing facing)
    {
        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true;
        return super.hasCapability(capability, facing);
    }

    @Override
    public <T> T getCapability(Capability<T> capability, EnumFacing facing)
    {
        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T) itemStackHandler;
        return super.getCapability(capability, facing);
    }

    @Nullable
    @Override
    public ITextComponent getDisplayName()
    {
        int stacks=0;
        for (int i = 0; i < itemStackHandler.getSlots(); i++)
        {
            if(itemStackHandler.getStackInSlot(i)!=null)stacks++;
        }
        return new TextComponentString(stacks+"/"+ itemStackHandler.getSlots());
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound)
    {
        NBTTagCompound nbtTagCompound=super.writeToNBT(compound);
        NBTTagCompound handlernbt= itemStackHandler.serializeNBT();
        nbtTagCompound.setTag(ITEMSTACKS,handlernbt);
        nbtTagCompound.setShort(CHESTTYPE, (short) type);
        return nbtTagCompound;
    }

    @Override
    public void readFromNBT(NBTTagCompound compound)
    {
        super.readFromNBT(compound);
        type=compound.getShort(CHESTTYPE);
        itemStackHandler=new ItemStackHandler();
        itemStackHandler.deserializeNBT(compound.getCompoundTag(ITEMSTACKS));
    }

}

 

Seems to be working.

Although I have read the docs few times, I didn't understand it right away. I assert that it needs to show an example, or a link to one.

Link to comment
Share on other sites

That looks correct.

 

I believe LexManos is strongly against the Forge documentation containing any "copy-pasta" code, i.e. fully working code blocks with minimal explanation apart from "copy this code into your code to make it work". If you have some well-documented example code, it may be added (though I don't speak for the Forge team).

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • S1288POKER Rasakan sensasi bertaruh Mix Parlay yang tak terlupakan dengan bonus fantastis di situs judi terpercaya kami! Kami menawarkan bonus Mix Parlay terbesar di Asia dengan berbagai pilihan taruhan dan minimal deposit rendah. Dapatkan bonus hingga jutaan rupiah untuk taruhan Mix Parlay Anda dan nikmati keuntungan berlipat ganda.
    • Situs Akun Pro Peru adalah pilihan terbaik bagi Anda yang mencari situs terpercaya untuk bermain slot dan taruhan bola. Berikut adalah beberapa alasan mengapa Anda harus memilih Situs Akun Pro Peru: Slot Populer Kami menyajikan koleksi slot yang populer dan menarik dengan berbagai tema yang beragam. Dari slot klasik hingga slot video modern, setiap pemain dapat menemukan permainan favorit mereka dengan mudah. Taruhan Bola Terpercaya Selain slot, kami juga menyediakan taruhan bola dengan pasaran terlengkap dan odds yang kompetitif. Dengan berbagai pertandingan dan liga yang tersedia, Anda dapat menikmati pengalaman taruhan bola yang seru dan menguntungkan. Transaksi Mudah dengan Bank BTN Kami menyediakan layanan transaksi yang mudah dan aman melalui Bank BTN. Dengan dukungan dari sistem pembayaran yang terpercaya, Anda dapat melakukan deposit dan penarikan dana dengan cepat dan tanpa hambatan.  
    • Ngamenslot adalah pilihan terbaik bagi Anda yang mencari situs terpercaya untuk bermain slot dan taruhan bola. Berikut adalah beberapa alasan mengapa Anda harus memilih Ngamenslot: Kombinasi Slot & Bola Kami menyajikan kombinasi terbaik antara permainan slot yang seru dan taruhan bola yang menegangkan. Dengan pilihan permainan yang beragam, setiap pemain dapat menikmati pengalaman bermain yang unik dan menyenangkan. Transaksi Mudah melalui Bank Ekonomi Kami menyediakan layanan transaksi yang mudah dan aman melalui Bank Ekonomi. Dengan dukungan dari sistem pembayaran yang terpercaya, Anda dapat melakukan deposit dan penarikan dana dengan cepat dan tanpa hambatan. Terpercaya dan Terjamin Ngamenslot telah terbukti sebagai situs terpercaya dengan ribuan pemain yang puas. Kami mengutamakan keamanan dan kenyamanan para pemain, sehingga Anda dapat bermain dengan tenang dan fokus pada permainan.  
    • Tambang88 adalah pilihan terbaik bagi Anda yang mencari pengalaman bermain slot gacor dengan transaksi mudah menggunakan Bank Sinarmas. Berikut adalah beberapa alasan mengapa Anda harus memilih Tambang88: Raja Slot Gacor Kami merupakan raja slot gacor dengan koleksi permainan terbaik yang menawarkan kesenangan bermain dan peluang kemenangan besar. Dengan fitur-fitur unggulan dan tema-tema menarik, setiap putaran permainan akan memberikan Anda pengalaman yang tak terlupakan. Transaksi Mudah dengan Bank Sinarmas Kami menyediakan layanan transaksi mudah melalui Bank Sinarmas untuk kenyamanan dan keamanan Anda. Dengan proses yang cepat dan efisien, Anda dapat melakukan deposit dan penarikan dana dengan lancar dan tanpa hambatan. Profesional dan Menguntungkan Tambang88 mengutamakan profesionalitas dalam memberikan layanan kepada para pemainnya. Kami juga menawarkan kesempatan untuk meraih keuntungan yang besar dengan jackpot dan hadiah-hadiah menarik lainnya.    
    • TRIK POLA SL0T GAC0R MAHJONG WAYS 1 DAN 2 HARI INI Sekarang Anda dapat meningkatkan peluang Bermain dengan langsung menggunakan situs resmi dari permainan Mahjong (PG SOFT). Cukup daftar dan siapkan hanya mulai dari 50K hingga 200K, Anda sudah memiliki peluang untuk memenangkan hadiah besar. Jika tidak memiliki dana sebanyak itu, Anda dapat mencoba dengan dana 50K dan memanfaatkan bonus member baru untuk menambah modal. Berikut adalah Situs Resmi Mahjong yang dapat Anda kunjungi: >> SITUS RESMI MAHJONG YANG TERBUKTI << >> SITUS RESMI MAHJONG YANG TERBUKTI << Setelah mendaftar, Anda dapat menggunakan pola yang sering saya gunakan: 🔥 25 Manual TURBO OFF 🔥 15 Manual TURBO ON 🔥 30 Auto TURBO OFF 🔥 10 Manual TURBO ON Pola ini biasanya memberikan hasil yang konsisten.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.