I've done my best to try and get through this without turning to the forums, but I've hit a really difficult roadblock. I am trying to make a one slot inventory that will open when a keybinding is pressed. I'm having trouble with using capabilities to store the inventory (which I kinda "completed", but I think it looks kinda weird) and opening the GUI. Here are the files:
SparkOn.java
package com.soravoid.sparkon;
import com.soravoid.sparkon.capabilities.CapabilityAlignerInv;
import com.soravoid.sparkon.capabilities.interfaces.IAlignerInv;
import com.soravoid.sparkon.handlers.GuiHandler;
import com.soravoid.sparkon.handlers.SparkPacketHandler;
import com.soravoid.sparkon.proxy.ClientProxy;
import com.soravoid.sparkon.proxy.CommonProxy;
import com.soravoid.sparkon.proxy.IProxy;
import net.minecraft.item.ItemGroup;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ExtensionPoint;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.network.FMLPlayMessages;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.soravoid.sparkon.capabilities.CapabilityEB;
import com.soravoid.sparkon.capabilities.CapabilityEB.EBStorage;
import com.soravoid.sparkon.capabilities.CapabilityEF;
import com.soravoid.sparkon.capabilities.CapabilityEF.EFStorage;
import com.soravoid.sparkon.capabilities.CapabilityPlayerStats;
import com.soravoid.sparkon.capabilities.CapabilityPlayerStats.PlayerStatsStorage;
import com.soravoid.sparkon.capabilities.interfaces.IEffervescence;
import com.soravoid.sparkon.capabilities.interfaces.IEffervescentBody;
import com.soravoid.sparkon.capabilities.interfaces.IPlayerStats;
import com.soravoid.sparkon.render.EffervescenceBar;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@Mod("sparkon")
public class SparkOn
{
public static SparkOn instance;
public static final String MODID = "sparkon";
private static final Logger logger = LogManager.getLogger(MODID);
public static final int ALIGNINV_GUI_ID = 0;
public static final ItemGroup SPARK = new SparkGroup();
public static final IProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> CommonProxy::new);
public SparkOn()
{
instance = this;
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup);
MinecraftForge.EVENT_BUS.register(this);
}
private void setup(FMLCommonSetupEvent e)
{
CapabilityManager.INSTANCE.register(IEffervescence.class, new EFStorage(), () -> new CapabilityEF());
CapabilityManager.INSTANCE.register(IPlayerStats.class, new PlayerStatsStorage(), () -> new CapabilityPlayerStats());
CapabilityManager.INSTANCE.register(IEffervescentBody.class, new EBStorage(), () -> new CapabilityEB(null));
CapabilityManager.INSTANCE.register(IAlignerInv.class, new CapabilityAlignerInv.AlignerInvStorage(), () -> new CapabilityAlignerInv(null));
SparkPacketHandler.register();
logger.info("Setup Complete!");
}
private void clientSetup(FMLClientSetupEvent e)
{
proxy.registerKeyBinds();
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> GuiHandler::openGui);
logger.info("Client Setup Complete");
}
}
IAlignerInv.java
package com.soravoid.sparkon.capabilities.interfaces;
import com.soravoid.sparkon.inventory.AlignerInventory;
import net.minecraft.item.Item;
import net.minecraftforge.items.IItemHandler;
public interface IAlignerInv extends IItemHandler
{
Item getCurrentAligner();
AlignerInventory getInventory();
void setInventory(AlignerInventory inv);
}
CapabilityAlignerInv.java
package com.soravoid.sparkon.capabilities;
import com.soravoid.sparkon.capabilities.interfaces.IAlignerInv;
import com.soravoid.sparkon.inventory.AlignerInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class CapabilityAlignerInv implements IAlignerInv
{
private AlignerInventory inventory;
public CapabilityAlignerInv(AlignerInventory inv)
{
this.inventory = inv;
}
@Override
public AlignerInventory getInventory() { return inventory; }
@Override
public Item getCurrentAligner() { return this.inventory.getStackInSlot(0).getItem(); }
public void setInventory(AlignerInventory inventory) { this.inventory = inventory; }
@Override
public int getSlots() { return this.inventory.getSizeInventory(); }
@Override
public ItemStack getStackInSlot(int slot) { return this.inventory.getStackInSlot(slot); }
@Nonnull
@Override
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate)
{
if(this.inventory.isItemValidForSlot(slot, stack))
{
if(this.inventory.getStackInSlot(slot) == null || this.inventory.getStackInSlot(slot).getCount() <= 0)
{
if(!simulate) this.inventory.setInventorySlotContents(slot, stack);
return ItemStack.EMPTY;
}
else
{
return stack;
}
}
else
{
return stack;
}
}
@Nonnull
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate)
{
if(this.inventory.getStackInSlot(slot) == null)
{
return ItemStack.EMPTY;
}
else
{
if(!simulate) this.inventory.setInventorySlotContents(slot, ItemStack.EMPTY);
return this.inventory.getStackInSlot(slot);
}
}
@Override
public int getSlotLimit(int slot) { return this.inventory.getInventoryStackLimit(); }
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) { return this.inventory.isItemValidForSlot(slot, stack); }
public static class AlignerInvStorage implements Capability.IStorage<IAlignerInv>
{
@Override
public INBT writeNBT(Capability<IAlignerInv> capability, IAlignerInv instance, Direction side)
{
CompoundNBT nbt = new CompoundNBT();
instance.getInventory().writeToNBT(nbt);
return nbt;
}
@Override
public void readNBT(Capability<IAlignerInv> capability, IAlignerInv instance, Direction side, INBT nbt)
{
AlignerInventory inv = new AlignerInventory();
inv.readFromNBT((CompoundNBT) nbt);
instance.setInventory(inv);
}
}
public static class AlignerInvProvider implements ICapabilitySerializable<INBT>
{
@CapabilityInject(IAlignerInv.class)
public static Capability<IAlignerInv> ALIGNERINV = null;
private IAlignerInv instance;
public AlignerInvProvider(AlignerInventory inv)
{
this.instance = new CapabilityAlignerInv(inv);
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side)
{
return ALIGNERINV.orEmpty(cap, LazyOptional.of(() -> this.instance));
}
@Override
public INBT serializeNBT()
{
return ALIGNERINV.getStorage().writeNBT(ALIGNERINV, instance, null);
}
@Override
public void deserializeNBT(INBT nbt)
{
ALIGNERINV.getStorage().readNBT(ALIGNERINV, instance, null, nbt);
}
}
}
AlignerInventory.java
package com.soravoid.sparkon.inventory;
import com.soravoid.sparkon.lists.SparkItems;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
public class AlignerInventory implements IInventory
{
private final String name = "Aligner Slot";
private final String tagName = "alignerTag";
public static final int INV_SIZE = 1;
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public AlignerInventory() {}
@Override
public int getSizeInventory() { return INV_SIZE; }
@Override
public ItemStack getStackInSlot(int index) { return inventory[index]; }
@Override
public ItemStack decrStackSize(int index, int count)
{
ItemStack stack = getStackInSlot(index);
if(stack != null)
{
if(stack.getCount() > count)
{
stack = stack.split(count);
this.markDirty();
}
else
{
setInventorySlotContents(index, null);
}
}
return stack;
}
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{
this.inventory[index] = stack;
if(stack != null && stack.getCount() > this.getInventoryStackLimit())
{
stack.setCount(this.getInventoryStackLimit());
}
this.markDirty();
}
public String getName() { return name; }
@Override
public int getInventoryStackLimit() { return 1; }
@Override
public void markDirty()
{
for(int i = 0; i < getSizeInventory(); ++i)
{
if(getStackInSlot(i) != null && getStackInSlot(i).getCount() <= 0)
{
this.inventory[i] = null;
}
}
}
@Override
public boolean isUsableByPlayer(PlayerEntity player) { return true; }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{
return stack.getItem() == SparkItems.ADAPTIVE_ALIGNER || stack.getItem() == SparkItems.STRONG_WILLED_ALIGNER || stack.getItem() == SparkItems.WAVE_CASTER_ALIGNER || stack.getItem() == SparkItems.WAVE_MANIPULATOR_ALIGNER;
}
public void writeToNBT(CompoundNBT nbt)
{
ListNBT items = new ListNBT();
for(int i = 0; i < this.getSizeInventory(); ++i) {
if (getStackInSlot(i) != null) {
CompoundNBT item = new CompoundNBT();
item.putByte("Slot", (byte) i);
getStackInSlot(i).write(item);
items.add(item);
}
}
nbt.put(tagName, items);
}
public void readFromNBT(CompoundNBT nbt)
{
ListNBT items = (ListNBT) nbt.get(tagName);
for(int i = 0; i < items.size(); ++i)
{
CompoundNBT item = (CompoundNBT) items.get(i);
byte slot = item.getByte("Slot");
if(slot >= 0 && slot < getSizeInventory())
{
inventory[slot] = ItemStack.read(item);
}
}
}
@Override
public boolean isEmpty()
{
for(int i = 0; i < getSizeInventory(); ++i)
{
if(this.inventory[i] != null)
{
return false;
}
}
return true;
}
@Override
public ItemStack removeStackFromSlot(int index)
{
ItemStack stack = getStackInSlot(index);
setInventorySlotContents(index, null);
return stack;
}
@Override
public void clear()
{
for(int i = 0; i < inventory.length; ++i)
{
this.inventory[i] = null;
}
}
}
AlignerContainer.java
package com.soravoid.sparkon.inventory.containers;
import com.soravoid.sparkon.inventory.AlignerInventory;
import com.soravoid.sparkon.inventory.slots.AlignerSlot;
import com.soravoid.sparkon.lists.SparkItems;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
public class AlignerContainer extends Container
{
private static final int ARMOR_START = AlignerInventory.INV_SIZE, ARMOR_END = ARMOR_START+3,
INV_START = ARMOR_END+1, INV_END = INV_START+26, HOTBAR_START = INV_END+1,
HOTBAR_END = HOTBAR_START+8;
public AlignerContainer(PlayerInventory inventory, AlignerInventory customInv)
{
super(null, 0);
int i;
this.addSlot(new AlignerSlot(customInv, 0, 80, 23));
for (i = 0; i < 3; ++i)
{
for (int j = 0; j < 9; ++j)
{
this.addSlot(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (i = 0; i < 9; ++i)
{
this.addSlot(new Slot(inventory, i, 8 + i * 18, 142));
}
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) { return true; }
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index)
{
ItemStack itemstack = null;
Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
// Either armor slot or custom item slot was clicked
if (index < INV_START)
{
// try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true))
{
return null;
}
slot.onSlotChange(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place either in custom or armor slots
else
{
// if item is our custom item
if (itemstack1.getItem() == SparkItems.ADAPTIVE_ALIGNER || itemstack1.getItem() == SparkItems.STRONG_WILLED_ALIGNER || itemstack1.getItem() == SparkItems.WAVE_CASTER_ALIGNER || itemstack1.getItem() == SparkItems.WAVE_MANIPULATOR_ALIGNER)
{
if (!this.mergeItemStack(itemstack1, 0, AlignerInventory.INV_SIZE, false))
{
return null;
}
}
else if (index >= INV_START && index < HOTBAR_START)
{
if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_START + 1, false))
{
return null;
}
}
else if (index >= HOTBAR_START && index < HOTBAR_END + 1)
{
if (!this.mergeItemStack(itemstack1, INV_START, INV_END + 1, false))
{
return null;
}
}
}
if (itemstack1.getCount() == 0)
{
slot.putStack(null);
}
else
{
slot.onSlotChanged();
}
if (itemstack1.getCount() == itemstack.getCount())
{
return null;
}
slot.onTake(playerIn, itemstack1);
}
return itemstack;
}
}
AlignerGui.java
package com.soravoid.sparkon.guis;
import com.soravoid.sparkon.SparkOn;
import com.soravoid.sparkon.inventory.AlignerInventory;
import com.soravoid.sparkon.inventory.containers.AlignerContainer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.StringTextComponent;
import org.lwjgl.opengl.GL11;
public class AlignerGui extends ContainerScreen<AlignerContainer>
{
private static final ResourceLocation location = new ResourceLocation(SparkOn.MODID, "textures/gui/aligner.png");
private final AlignerInventory inventory;
public AlignerGui(PlayerInventory inv, AlignerInventory cusInv)
{
super(new AlignerContainer(inv, cusInv), inv, new StringTextComponent(""));
this.inventory = cusInv;
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getInstance().getTextureManager().bindTexture(location);
this.blit(guiLeft, guiTop, 0, 0, xSize, ySize);
}
}
GuiHandler.java (For this one, I wasn't sure how to get the AlignerInventory from the player bc getting it from the Minecraft.getInstance().player AlignerInv capability would return null I think because I don't have packets for this capability set up, so null is a placeholder)
package com.soravoid.sparkon.handlers;
import com.soravoid.sparkon.SparkOn;
import com.soravoid.sparkon.guis.AlignerGui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraftforge.fml.network.FMLPlayMessages;
public class GuiHandler
{
public static Screen openGui(FMLPlayMessages.OpenContainer openContainer)
{
if(openContainer.getWindowId() == SparkOn.ALIGNINV_GUI_ID) return new AlignerGui(Minecraft.getInstance().player.inventory, null);
return null;
}
}
The capabilities are properly set up in a Capability Handler.