Skip to content

Instantly share code, notes, and snippets.

@hedgehog1029
Created May 18, 2018 17:25
Show Gist options
  • Save hedgehog1029/34d7d8de0b8b074c8db9aa8b7d37935c to your computer and use it in GitHub Desktop.
Save hedgehog1029/34d7d8de0b8b074c8db9aa8b7d37935c to your computer and use it in GitHub Desktop.
Forge Container implementation for IItemHandler
package offbeatwitch.example; // replace with your own package path, obviously
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.play.server.SPacketOpenWindow;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
/**
* Written by @offbeatwitch.
* Licensed under MIT.
*/
public class ContainerItemHandler extends Container {
private IItemHandler handler;
private int inventoryEnd;
public ContainerItemHandler(IItemHandler handler, EntityPlayer player) {
this.handler = handler;
int i = 0;
while (i < handler.getSlots()) {
int j = i % 9;
int c = i / 9;
Slot slot = new SlotItemHandler(handler, i, 8 + j * 18, 18 + c * 18);
this.addSlotToContainer(slot);
i++;
}
inventoryEnd = inventorySlots.size();
for (int l = 0; l < 3; ++l) {
for (int j1 = 0; j1 < 9; ++j1) {
this.addSlotToContainer(new Slot(player.inventory, j1 + l * 9 + 9, 8 + j1 * 18, 103 + l * 18 + i));
}
}
for (int i1 = 0; i1 < 9; ++i1) {
this.addSlotToContainer(new Slot(player.inventory, i1, 8 + i1 * 18, 161 + i));
}
}
@Override
public boolean canInteractWith(EntityPlayer playerIn) {
return true;
}
public SPacketOpenWindow toPacket(String type, String name) {
return new SPacketOpenWindow(this.windowId, type, new TextComponentString(name), this.handler.getSlots());
}
public void open(EntityPlayerMP player, String type, String title) {
player.getNextWindowId();
this.windowId = player.currentWindowId;
player.connection.sendPacket(this.toPacket(type, title));
player.openContainer = this;
this.addListener(player);
}
@Override
public void onContainerClosed(EntityPlayer playerIn) {
super.onContainerClosed(playerIn);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
ItemStack stack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
ItemStack current = slot.getStack();
stack = current.copy();
if (index < inventoryEnd) {
if (!this.mergeItemStack(current, inventoryEnd, this.inventorySlots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(current, 0, inventoryEnd, false)) {
return ItemStack.EMPTY;
}
if (current.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
}
return stack;
}
}
@Verthicca
Copy link

so how do you get around having to have super(ContainerType, windowID)?

@dj-bauer
Copy link

So how do I register it in the container factory then?

@hedgehog1029
Copy link
Author

this is from 2018, and judging by the version history i believe it's for 1.12. i doubt this still applies to 1.13+

@Caellian
Copy link

Caellian commented Aug 5, 2024

Container is a superset of IItemHandler - almost every container (GUI with slots) in both modded and vanilla can "handle items" i.e. has slots which handle items.
And example of a block which is a Container but isn't an IItemHandler would be some kind of liquid tank which has a GUI showing how full it is but doesn't have item slots (e.g. accept buckets).

Here is updated wrapper for 1.20.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment