I created an GUI to open with a key bind. This works with out any errors.
I also created a Capability that extends ItemStackHandler, an InventoryProvider, and an InventroyStorage.
The Capability seems to work, but if place an item into my GUI and close it, the item will moved back to the hotbars first slot and the items within the gui will not display. It seems like it never call
deserializeNBT
. I printed out everytime
serializeNBT
or
deserializeNBT
is called and
deserializeNBT
is never printed.
What am i missing?
My Class that extends ItemStackHandler
package de.cyb3r.testmod.capabilities;
;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.ItemStackHandler;
public class CustomInventoryDef extends ItemStackHandler{
private String item;
public CustomInventoryDef(int size) {
this.setSize(size);
}
@Override
public int getSlots() {
return 9 ;
}
@Override
public ItemStack getStackInSlot(int slot ) {
return super.getStackInSlot(slot);
}
@Override
public ItemStack insertItem( int slot , ItemStack stack , boolean simulate ) {
item = stack.toString();
return super.insertItem(slot, stack, simulate);
}
@Override
public ItemStack extractItem( int slot , int amount , boolean simulate ) {
return super.extractItem(slot ,amount,simulate);
}
@Override
public int getSlotLimit(int slot) {
return 1;
}
public String getItem() {
return item;
}
@Override
public NBTTagCompound serializeNBT()
{
NBTTagCompound nbt2 = new NBTTagCompound();
NBTTagCompound nbt = super.serializeNBT();
nbt2.setTag("customInventoryDef",nbt);
System.out.println("CustomInventoryDef.serializeNBT:"+nbt2);
return nbt2;
}
@Override
public void deserializeNBT(NBTTagCompound nbt2)
{
System.out.println(nbt2);
NBTTagCompound nbt = nbt2.getCompoundTag("customInventoryDef");
super.deserializeNBT(nbt);
}
}
My CapabilityProvider
package de.cyb3r.testmod.capabilities;
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.ICapabilitySerializable;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class InventoryProvider implements ICapabilitySerializable<NBTTagCompound> {
private final CustomInventoryDef inv;
public InventoryProvider( CustomInventoryDef inv ) {
this.inv = inv ;
}
@Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
return capability == CustomInventoryCap.CUSTOM_INVENTORY;
}
@Nullable
@Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
return (T)inv;
}
@Override
public NBTTagCompound serializeNBT() {
System.out.println("InventoryProvider.serializeNBT");
return inv.serializeNBT();
}
@Override
public void deserializeNBT(NBTTagCompound nbt) {
System.out.println("InventoryProvider.deserializeNBT");
inv.deserializeNBT(nbt);
}
}
My IStorage class
package de.cyb3r.testmod.capabilities;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.ItemStackHandler;
public class InventoryStorage implements Capability.IStorage<CustomInventoryDef> {
@Override
public NBTBase writeNBT(Capability< CustomInventoryDef > capability ,
CustomInventoryDef instance , EnumFacing side ) {
System.out.println("InventoryStorage.writeNBT");
return instance.serializeNBT();
}
@Override
public void readNBT(Capability< CustomInventoryDef > capability ,
CustomInventoryDef instance , EnumFacing side , NBTBase nbt ) {
System.out.println("InventoryStorage.readNBT");
instance.deserializeNBT((NBTTagCompound) nbt);
}
}
Here it register my Capability (gets called from the @Mod class's preInit)(yes i am aware im using a deprecated method here)
package de.cyb3r.testmod.capabilities;
import net.minecraftforge.common.capabilities.CapabilityManager;
public class TestModCapabilities {
public static void registerAllCapabilities() {
CapabilityManager.INSTANCE.register(CustomInventoryDef.class , new InventoryStorage() , CustomInventoryDef.class );
}
}
My GuiContainer
package de.cyb3r.testmod.client.gui;
import de.cyb3r.testmod.TestMod;
import de.cyb3r.testmod.capabilities.CustomInventoryDef;
import de.cyb3r.testmod.container.ContainerSamusMenu;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextComponentTranslation;
import java.awt.*;
public class GuiSamusMenuInventory extends GuiContainer {
private static final ResourceLocation texture = new ResourceLocation(TestMod.MODID, "textures/gui/container.png");
public GuiSamusMenuInventory(EntityPlayer player) {
super(new ContainerSamusMenu(player,false));
xSize = 176;
ySize = 166;
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
fontRenderer.drawString(new TextComponentTranslation("tile.tutorial_container.name").getFormattedText(), 5, 5, Color.darkGray.getRGB());
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
}
}
My GuiHandler
package de.cyb3r.testmod.client.gui;
import de.cyb3r.testmod.capabilities.CustomInventoryDef;
import de.cyb3r.testmod.container.ContainerSamusMenu;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import javax.annotation.Nullable;
public class GuiHandler implements IGuiHandler {
public static final int GUI_SAMUS_MENU_CONTAINER_ID = 0;
public static final int GUI_SAMUS_MENU_ID = 1;
@Nullable
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
switch (ID) {
case GUI_SAMUS_MENU_ID:
return new ContainerSamusMenu(player,false );
default: return null;
}
}
@Nullable
@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
switch (ID) {
case GUI_SAMUS_MENU_ID:
return new GuiSamusMenuInventory(player);
default: return null;
}
}
}
My SlotItemHandler
package de.cyb3r.testmod.container;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import javax.annotation.Nonnull;
public class SlotSamusMenu extends SlotItemHandler {
private Item acceptedItem;
public SlotSamusMenu(IItemHandler itemHandler, int index, int xPosition, int yPosition, Item acceptedItem) {
super(itemHandler, index, xPosition, yPosition);
this.acceptedItem = acceptedItem;
}
@Override
public int getSlotStackLimit() {
return 1;
}
@Override
public boolean isItemValid(@Nonnull ItemStack stack) {
if (stack.getItem() == acceptedItem) {
return true;
} else {
return false;
}
}
}
My Container
package de.cyb3r.testmod.container;
import de.cyb3r.testmod.capabilities.CustomInventoryCap;
import de.cyb3r.testmod.capabilities.CustomInventoryDef;
import de.cyb3r.testmod.items.ModItems;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
public class ContainerSamusMenu extends Container {
public ContainerSamusMenu(final EntityPlayer player, boolean localWorld) {
if (player.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)) {
IItemHandler inventory = player.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
IItemHandler customInventoryDef = player.getCapability(CustomInventoryCap.CUSTOM_INVENTORY,null);
// CONTAINER INVENTORY
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
addSlotToContainer(new SlotSamusMenu(customInventoryDef, x + (y * 3), 62 + x * 18, 17 + y * 18, ModItems.hiJumpBoots));
}
}
// MAIN PLAYER INVENTORY
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 9; x++) {
addSlotToContainer(new SlotItemHandler(inventory, x + (y * 9) + 9, 8 + x * 18, 84 + y * 18));
}
}
// PLAYER HOTBAR INVENTORY
for (int i = 0; i < 9; i++) {
addSlotToContainer(new SlotItemHandler(inventory, i, 8 + (i * 18), 142));
}
}
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int index) {
ItemStack stack = ItemStack.EMPTY;
Slot slot = inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
ItemStack stackInSlot = slot.getStack();
stack = stackInSlot.copy();
int containerSlots = inventorySlots.size() - player.inventory.mainInventory.size();
if (index < containerSlots) {
if (!this.mergeItemStack(stackInSlot, containerSlots, inventorySlots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(stackInSlot, 0, containerSlots, false)) {
return ItemStack.EMPTY;
}
if (stackInSlot.getCount() == 0) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
slot.onTake(player, stackInSlot);
}
return stack;
}
@Override
public boolean canInteractWith(EntityPlayer playerIn) {
return true;
}
}
CustomInventoryDef.java
InventoryProvider.java
InventoryStorage.java
TestModCapabilities.java
GuiSamusMenuInventory.java
GuiHandler.java
SlotSamusMenu.java
ContainerSamusMenu.java