Résolu Inventaire multi fonction ( IItemHandler vs IInventory )
-
ENFIN … ! Bon je poste l’intégralité de mon “kitbag” au cas ou que cela puisse aider quelqu’un !
KitbagCapability.java
package com.kporal.mcplus.items.kitbag; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; public class KitbagCapability { @CapabilityInject(KitbagHandler.class) public static Capability<KitbagHandler> VOIDSTORAGE_CAPABILITY = null; public static void register() { CapabilityManager.INSTANCE.register(KitbagHandler.class, new Capability.IStorage<KitbagHandler>() { @Override public NBTBase writeNBT(Capability<KitbagHandler> capability, KitbagHandler instance, EnumFacing side) { NBTTagList nbtTagList = new NBTTagList(); int size = instance.getSlots(); for (int i = 0; i < size; i++) { ItemStack stack = instance.getStackInSlot(i); if (!stack.isEmpty()) { NBTTagCompound itemTag = new NBTTagCompound(); itemTag.setInteger("Slot", i); stack.writeToNBT(itemTag); nbtTagList.appendTag(itemTag); } } return nbtTagList; } @Override public void readNBT(Capability<KitbagHandler> capability, KitbagHandler instance, EnumFacing side, NBTBase base) { if (!(instance instanceof IItemHandlerModifiable)) throw new RuntimeException("IItemHandler instance does not implement IItemHandlerModifiable"); IItemHandlerModifiable itemHandlerModifiable = (IItemHandlerModifiable) instance; NBTTagList tagList = (NBTTagList) base; for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound itemTags = tagList.getCompoundTagAt(i); int j = itemTags.getInteger("Slot"); if (j >= 0 && j < instance.getSlots()) { itemHandlerModifiable.setStackInSlot(j, new ItemStack(itemTags)); } } } }, KitbagStackHandler::new); } }
KitbagContainer.java
package com.kporal.mcplus.items.kitbag; import com.kporal.mcplus.container.FuelFurnaceSlot; import com.kporal.mcplus.container.OutputFurnaceSlot; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IContainerListener; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemStack; import net.minecraft.util.NonNullList; import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; public class KitbagContainer extends Container { private int xPos = 5, yPos = 5, iid = 0, iRows = 8, iLines = 13, nSlots = iRows * iLines; public KitbagContainer( IItemHandler i, EntityPlayer p ) { // Container inventory :: 0 > 103 for( int y = 0; y < iRows; ++y ) { for( int x = 0; x < iLines; ++x ) { addSlotToContainer( new SlotItemHandler( i, iid, xPos + x * 18, yPos + y * 18 )); iid++; } } // Workbench slots :: 104 > 113 addSlotToContainer( new SlotItemHandler( i, iid, 167, 170 )); iid++; for (int y = 0; y < 3; ++y) { for (int x = 0; x < 3; ++x) { addSlotToContainer( new SlotItemHandler( i, iid, 185 + x * 18, 152 + y * 18 )); iid++; } } // Furnace slots :: 114 > 116 addSlotToContainer( new SlotItemHandler( i, iid, 221, 209 )); iid++; addSlotToContainer( new FuelFurnaceSlot( i, iid, 185, 209 )); iid++; addSlotToContainer( new OutputFurnaceSlot( p, i, iid, 167, 209 )); yPos = 152; // Player inventory for( int y = 0; y < 3; ++y ) { for( int x = 0; x < 9; ++x ) { addSlotToContainer( new Slot( p.inventory, x + y * 9 + 9, xPos + x * 18, yPos + y * 18 )); } } // Player hotbar for( int x = 0; x < 9; ++x ) { addSlotToContainer( new Slot( p.inventory, x, xPos + x * 18, 209 )); } } @Override public ItemStack transferStackInSlot( EntityPlayer playerIn, int index ) { ItemStack itemstack = ItemStack.EMPTY; Slot slot = inventorySlots.get(index); if( slot != null && slot.getHasStack() ) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if( index == 104 ) { itemstack1.getItem().onCreated(itemstack1, playerIn.world, playerIn); if( !this.mergeItemStack(itemstack1, 0, nSlots, false )) { return ItemStack.EMPTY; } slot.onSlotChange( itemstack1, itemstack ); } else if( index < nSlots ) { if( !mergeItemStack( itemstack1, nSlots, inventorySlots.size(), true )) { return ItemStack.EMPTY; } } else if( !mergeItemStack( itemstack1, 0, nSlots, false )) { return ItemStack.EMPTY; } if ( itemstack1.isEmpty() ) { slot.putStack( ItemStack.EMPTY ); } else { slot.onSlotChanged(); } if( itemstack1.getCount() == itemstack.getCount() ) { return ItemStack.EMPTY; } ItemStack itemstack2 = slot.onTake( playerIn, itemstack1 ); if( index == 104 ) { playerIn.dropItem( itemstack2, false ); } } return itemstack; } @Override public boolean canInteractWith( EntityPlayer p ) { return true; } }
KitbagGui.java
package com.kporal.mcplus.items.kitbag; import com.kporal.mcplus.Main; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.tileentity.TileEntityFurnace; import net.minecraft.util.ResourceLocation; import net.minecraftforge.items.IItemHandler; public class KitbagGui extends GuiContainer { private IItemHandler i; public KitbagGui( IItemHandler i, EntityPlayer p ) { super( new KitbagContainer( i, p )); this.xSize = 243; this.ySize = 230; this.i = i; } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F ); this.mc.getTextureManager().bindTexture( new ResourceLocation( Main.MODID, "textures/gui/container/bookmysteries.png" ) ); this.drawTexturedModalRect( this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize ); // GuiFurnace.class int w = (this.width - this.xSize) / 2; int h = (this.height - this.ySize) / 2; int k = 5; // this.getBurnLeftScaled(13); this.drawTexturedModalRect( w + 204, h + 221 - k, 0, 243 - k, 14, k + 1 ); int l = 12; // this.getCookProgressScaled( 15 ); this.drawTexturedModalRect( w + 203, h + 224 - 1, 14, 230, l + 1, 2 ); } }
KitbagGuiHandler
package com.kporal.mcplus.items.kitbag; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.IInventory; import net.minecraft.world.World; import net.minecraftforge.fml.common.network.IGuiHandler; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; public class KitbagGuiHandler implements IGuiHandler { @Override public Object getServerGuiElement( int ID, EntityPlayer p, World w, int x, int y, int z ) { return new KitbagContainer(( IItemHandler ) p.getCapability( KitbagCapability.VOIDSTORAGE_CAPABILITY, null ), p ); } @Override public Object getClientGuiElement( int ID, EntityPlayer p, World w, int x, int y, int z ) { return new KitbagGui(( IItemHandler ) p.getCapability( KitbagCapability.VOIDSTORAGE_CAPABILITY, null ), p ); } }
KitbagHandler.java
package com.kporal.mcplus.items.kitbag; import javax.annotation.Nonnull; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; public interface KitbagHandler { int getSlots(); @Nonnull ItemStack getStackInSlot(int slot); @Nonnull ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate); @Nonnull ItemStack extractItem(int slot, int amount, boolean simulate); int getSlotLimit(int slot); default boolean isItemValid(int slot, @Nonnull ItemStack stack) { return true; } }
KitbagProvider.java
package com.kporal.mcplus.items.kitbag; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class KitbagProvider implements ICapabilityProvider, ICapabilitySerializable<NBTTagCompound> { private final KitbagStackHandler inventory; public KitbagProvider() { inventory = new KitbagStackHandler( 117 ); } @Override public NBTTagCompound serializeNBT() { return inventory.serializeNBT(); } @Override public void deserializeNBT( NBTTagCompound nbt ) { inventory.deserializeNBT( nbt ); } @Override public boolean hasCapability( Capability<?> capability, EnumFacing facing ) { if( capability == KitbagCapability.VOIDSTORAGE_CAPABILITY ) { return true; } return false; } @Override public <T> T getCapability( Capability<T> capability, EnumFacing facing ) { if( capability == KitbagCapability.VOIDSTORAGE_CAPABILITY ) { return (T) inventory; } return null; } }
KitbagStackHandler.java
package com.kporal.mcplus.items.kitbag; import javax.annotation.Nonnull; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.NonNullList; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; public class KitbagStackHandler implements KitbagHandler, IItemHandlerModifiable, INBTSerializable<NBTTagCompound> { protected NonNullList<ItemStack> stacks; public KitbagStackHandler() { this(1); } public KitbagStackHandler(int size) { stacks = NonNullList.withSize(size, ItemStack.EMPTY); } public KitbagStackHandler(NonNullList<ItemStack> stacks) { this.stacks = stacks; } public void setSize(int size) { stacks = NonNullList.withSize(size, ItemStack.EMPTY); } @Override public void setStackInSlot(int slot, @Nonnull ItemStack stack) { validateSlotIndex(slot); this.stacks.set(slot, stack); onContentsChanged(slot); } @Override public int getSlots() { return stacks.size(); } @Override @Nonnull public ItemStack getStackInSlot(int slot) { validateSlotIndex(slot); return this.stacks.get(slot); } @Override @Nonnull public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { if (stack.isEmpty()) return ItemStack.EMPTY; validateSlotIndex(slot); ItemStack existing = this.stacks.get(slot); int limit = getStackLimit(slot, stack); if (!existing.isEmpty()) { if (!ItemHandlerHelper.canItemStacksStack(stack, existing)) return stack; limit -= existing.getCount(); } if (limit <= 0) return stack; boolean reachedLimit = stack.getCount() > limit; if (!simulate) { if (existing.isEmpty()) { this.stacks.set(slot, reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, limit) : stack); } else { existing.grow(reachedLimit ? limit : stack.getCount()); } onContentsChanged(slot); } return reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount()- limit) : ItemStack.EMPTY; } @Override @Nonnull public ItemStack extractItem(int slot, int amount, boolean simulate) { if (amount == 0) return ItemStack.EMPTY; validateSlotIndex(slot); ItemStack existing = this.stacks.get(slot); if (existing.isEmpty()) return ItemStack.EMPTY; int toExtract = Math.min(amount, existing.getMaxStackSize()); if (existing.getCount() <= toExtract) { if (!simulate) { this.stacks.set(slot, ItemStack.EMPTY); onContentsChanged(slot); } return existing; } else { if (!simulate) { this.stacks.set(slot, ItemHandlerHelper.copyStackWithSize(existing, existing.getCount() - toExtract)); onContentsChanged(slot); } return ItemHandlerHelper.copyStackWithSize(existing, toExtract); } } @Override public int getSlotLimit(int slot) { return 64; } protected int getStackLimit(int slot, @Nonnull ItemStack stack) { return Math.min(getSlotLimit(slot), stack.getMaxStackSize()); } @Override public boolean isItemValid(int slot, @Nonnull ItemStack stack) { return true; } @Override public NBTTagCompound serializeNBT() { NBTTagList nbtTagList = new NBTTagList(); for (int i = 0; i < stacks.size(); i++) { if (!stacks.get(i).isEmpty()) { NBTTagCompound itemTag = new NBTTagCompound(); itemTag.setInteger("Slot", i); stacks.get(i).writeToNBT(itemTag); nbtTagList.appendTag(itemTag); } } NBTTagCompound nbt = new NBTTagCompound(); nbt.setTag("Items", nbtTagList); nbt.setInteger("Size", stacks.size()); return nbt; } @Override public void deserializeNBT(NBTTagCompound nbt) { setSize(nbt.hasKey("Size", Constants.NBT.TAG_INT) ? nbt.getInteger("Size") : stacks.size()); NBTTagList tagList = nbt.getTagList("Items", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound itemTags = tagList.getCompoundTagAt(i); int slot = itemTags.getInteger("Slot"); if (slot >= 0 && slot < stacks.size()) { stacks.set(slot, new ItemStack(itemTags)); } } onLoad(); } protected void validateSlotIndex(int slot) { if (slot < 0 || slot >= stacks.size()) throw new RuntimeException("Slot " + slot + " not in valid range - [0," + stacks.size() + ")"); } protected void onLoad() { } protected void onContentsChanged(int slot) { } }
PS: J’ai simplement fais un gros copier coller de toute la capability CapabilityItemHandler.ITEM_HANDLER_CAPABILITY sans instancier celle-ci via l’item évidement.
Mais bref, le code est néanmoins incomplet mais il est fonctionnel. -
Fin du code : ( pour rendre le contenu permanent )
@SubscribeEvent public void cloneEvent( PlayerEvent.Clone e ) { if( e.isWasDeath() ) { KitbagHandler o = e.getOriginal().getCapability( KitbagCapability.VOIDSTORAGE_CAPABILITY, null ); KitbagHandler i = e.getEntityPlayer().getCapability( KitbagCapability.VOIDSTORAGE_CAPABILITY, null ); for( int k = 0; k < o.getSlots(); k++ ) { i.insertItem( k, o.getStackInSlot( k ), false ); } } } @SubscribeEvent public void addCapability( AttachCapabilitiesEvent<Entity> event ) { if( event.getObject() instanceof EntityPlayer ) { event.addCapability( new ResourceLocation( Main.MODID, "voidStorage" ), new KitbagProvider() ); } }