package com.thebrokenrail.twine.item; import com.thebrokenrail.twine.Twine; import com.thebrokenrail.twine.util.BackpackScreenHandler; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventories; import net.minecraft.inventory.Inventory; import net.minecraft.item.DyeableItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.screen.ScreenHandler; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; public class BackpackItem extends Item implements DyeableItem { public static class ItemInventory implements Inventory { private final int size; private final ItemStack stack; private final Hand hand; private final DefaultedList inv; public ItemInventory(int size, PlayerEntity player, Hand hand) { this.size = size; this.stack = player.getStackInHand(hand); this.hand = hand; inv = getInv(); } private DefaultedList getInv() { DefaultedList list = DefaultedList.ofSize(size, ItemStack.EMPTY); Inventories.fromTag(stack.getOrCreateTag(), list); return list; } private void setInv(DefaultedList list) { Inventories.toTag(stack.getOrCreateTag(), list); } @Override public int size() { return size; } @Override public boolean isEmpty() { for (ItemStack item : inv) { if (item != ItemStack.EMPTY) { return false; } } return true; } @Override public ItemStack getStack(int slot) { return inv.get(slot); } @Override public ItemStack removeStack(int slot, int amount) { return inv.get(slot).split(amount); } @Override public ItemStack removeStack(int slot) { ItemStack item = inv.get(slot); return item.split(item.getCount()); } @Override public void setStack(int slot, ItemStack stack) { inv.set(slot, stack); } @Override public void markDirty() { setInv(inv); } @Override public boolean canPlayerUse(PlayerEntity player) { return player.getStackInHand(hand) == stack; } @Override public void clear() { for (int i = 0; i < size; i++) { inv.set(i, ItemStack.EMPTY); } } } private final boolean large; public BackpackItem(boolean large) { super(new Settings().maxCount(1).group(Twine.ITEM_GROUP)); this.large = large; } @Override public TypedActionResult use(World world, PlayerEntity user, Hand hand) { ItemStack stack = user.getStackInHand(hand); if (!world.isClient()) { user.openHandledScreen(new ExtendedScreenHandlerFactory() { @Override public void writeScreenOpeningData(ServerPlayerEntity serverPlayerEntity, PacketByteBuf buf) { buf.writeBoolean(large); buf.writeEnumConstant(hand); } @Override public Text getDisplayName() { return stack.getName(); } @Override public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) { return new BackpackScreenHandler(syncId, inv, large, hand); } }); } return new TypedActionResult<>(ActionResult.CONSUME, stack); } }