From 645483f3b9bc78322c9bd98235dccad4788a7cea Mon Sep 17 00:00:00 2001 From: Aedial Date: Mon, 7 Sep 2026 19:30:41 +0200 Subject: [PATCH] Fix Bauble Case and Flower Bag voiding --- .../common/item/ItemBackedInventory.java | 109 ++++++++++++++++++ .../botania/common/item/ItemBaubleBox.java | 54 +++++---- .../botania/common/item/ItemFlowerBag.java | 48 ++++---- 3 files changed, 157 insertions(+), 54 deletions(-) create mode 100644 src/main/java/vazkii/botania/common/item/ItemBackedInventory.java diff --git a/src/main/java/vazkii/botania/common/item/ItemBackedInventory.java b/src/main/java/vazkii/botania/common/item/ItemBackedInventory.java new file mode 100644 index 0000000000..199209030b --- /dev/null +++ b/src/main/java/vazkii/botania/common/item/ItemBackedInventory.java @@ -0,0 +1,109 @@ +package vazkii.botania.common.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryBasic; +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.wrapper.InvWrapper; +import vazkii.botania.common.core.helper.ItemNBTHelper; + +import javax.annotation.Nonnull; +import java.util.function.Supplier; + +public class ItemBackedInventory extends InventoryBasic { + + private static final String TAG_SLOT = "Slot"; + private final ItemStack stack; + private final String tag; + + public ItemBackedInventory(ItemStack stack, int size, String tag) { + super("", false, size); + this.stack = stack; + this.tag = tag; + + NBTTagList list = ItemNBTHelper.getList(stack, tag, Constants.NBT.TAG_COMPOUND, false); + for(int i = 0; i < list.tagCount(); i++) { + NBTTagCompound cmp = list.getCompoundTagAt(i); + int slot = cmp.getByte(TAG_SLOT); + if(slot >= 0 && slot < size) + super.setInventorySlotContents(slot, new ItemStack(cmp)); + } + } + + public static boolean hasItems(ItemStack stack, String tag) { + return stack.hasTagCompound() && stack.getTagCompound().hasKey(tag, Constants.NBT.TAG_LIST); + } + + @Override + public boolean isUsableByPlayer(@Nonnull EntityPlayer player) { + return !stack.isEmpty(); + } + + @Override + public ItemStack decrStackSize(int index, int count) { + ItemStack result = super.decrStackSize(index, count); + if(!result.isEmpty()) + markDirty(); + + return result; + } + + @Override + public ItemStack removeStackFromSlot(int index) { + ItemStack result = super.removeStackFromSlot(index); + if(!result.isEmpty()) + markDirty(); + + return result; + } + + @Override + public void setInventorySlotContents(int index, @Nonnull ItemStack stack) { + super.setInventorySlotContents(index, stack); + markDirty(); + } + + @Override + public void clear() { + super.clear(); + markDirty(); + } + + @Override + public void markDirty() { + super.markDirty(); + + NBTTagList list = new NBTTagList(); + for(int i = 0; i < getSizeInventory(); i++) { + ItemStack slotStack = getStackInSlot(i); + if(!slotStack.isEmpty()) { + NBTTagCompound cmp = new NBTTagCompound(); + cmp.setByte(TAG_SLOT, (byte) i); + slotStack.writeToNBT(cmp); + list.appendTag(cmp); + } + } + + ItemNBTHelper.setList(stack, tag, list); + } + + public static class ItemHandler extends InvWrapper { + + private static final InventoryBasic EMPTY_INVENTORY = new InventoryBasic("", false, 0); + + private final Supplier inventorySupplier; + + public ItemHandler(Supplier inventorySupplier) { + super(EMPTY_INVENTORY); + this.inventorySupplier = inventorySupplier; + } + + @Override + public ItemBackedInventory getInv() { + return inventorySupplier.get(); + } + } + +} diff --git a/src/main/java/vazkii/botania/common/item/ItemBaubleBox.java b/src/main/java/vazkii/botania/common/item/ItemBaubleBox.java index bf4b29b965..b12e246890 100644 --- a/src/main/java/vazkii/botania/common/item/ItemBaubleBox.java +++ b/src/main/java/vazkii/botania/common/item/ItemBaubleBox.java @@ -11,7 +11,6 @@ package vazkii.botania.common.item; import baubles.api.cap.BaublesCapabilities; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTBase; @@ -22,14 +21,11 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilitySerializable; -import net.minecraftforge.common.util.Constants; import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.IItemHandlerModifiable; import vazkii.botania.api.mana.IManaItem; import vazkii.botania.client.gui.box.ContainerBaubleBox; import vazkii.botania.common.Botania; -import vazkii.botania.common.core.helper.ItemNBTHelper; import vazkii.botania.common.lib.LibGuiIDs; import vazkii.botania.common.lib.LibItemNames; @@ -48,23 +44,18 @@ public ItemBaubleBox() { @Nonnull @Override public ICapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound oldCapNbt) { - return new InvProvider(); + return new InvProvider(stack); } private static class InvProvider implements ICapabilitySerializable { - private final IItemHandler inv = new ItemStackHandler(24) { - @Nonnull - @Override - public ItemStack insertItem(int slot, @Nonnull ItemStack toInsert, boolean simulate) { - if(!toInsert.isEmpty()) { - boolean isBauble = toInsert.hasCapability(BaublesCapabilities.CAPABILITY_ITEM_BAUBLE, null); - if (toInsert.getItem() instanceof IManaItem || isBauble || ContainerBaubleBox.RODS.contains(toInsert.getItem().getRegistryName())) - return super.insertItem(slot, toInsert, simulate); - } - return toInsert; - } - }; + private final ItemStack stack; + private final IItemHandlerModifiable inv; + + private InvProvider(ItemStack stack) { + this.stack = stack; + inv = new ItemBackedInventory.ItemHandler(() -> getInventory(stack)); + } @Override public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { @@ -80,23 +71,30 @@ public T getCapability(@Nonnull Capability capability, @Nullable EnumFaci @Override public NBTBase serializeNBT() { - return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.writeNBT(inv, null); + // Clear legacy capability data after moving it into the item tag + return new NBTTagList(); } @Override public void deserializeNBT(NBTBase nbt) { - CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.readNBT(inv, null, nbt); + if(!ItemBackedInventory.hasItems(stack, TAG_ITEMS)) { + CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.readNBT(inv, null, nbt); + } } } - @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected) { - NBTTagList oldData = ItemNBTHelper.getList(stack, TAG_ITEMS, Constants.NBT.TAG_COMPOUND, true); - if (oldData != null) { - IItemHandler newInv = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); - CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.readNBT(newInv, null, oldData); - ItemNBTHelper.removeEntry(stack, TAG_ITEMS); - } + public static ItemBackedInventory getInventory(ItemStack stack) { + return new ItemBackedInventory(stack, 24, TAG_ITEMS) { + @Override + public boolean isItemValidForSlot(int slot, @Nonnull ItemStack toInsert) { + if(toInsert.isEmpty()) + return false; + + boolean isBauble = toInsert.hasCapability(BaublesCapabilities.CAPABILITY_ITEM_BAUBLE, null); + return toInsert.getItem() instanceof IManaItem || isBauble + || ContainerBaubleBox.RODS.contains(toInsert.getItem().getRegistryName()); + } + }; } @Nonnull diff --git a/src/main/java/vazkii/botania/common/item/ItemFlowerBag.java b/src/main/java/vazkii/botania/common/item/ItemFlowerBag.java index c102ce81be..d492e0386f 100644 --- a/src/main/java/vazkii/botania/common/item/ItemFlowerBag.java +++ b/src/main/java/vazkii/botania/common/item/ItemFlowerBag.java @@ -10,7 +10,6 @@ */ package vazkii.botania.common.item; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.SoundEvents; @@ -33,18 +32,15 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilitySerializable; -import net.minecraftforge.common.util.Constants; import net.minecraftforge.event.entity.player.EntityItemPickupEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.InvWrapper; import vazkii.botania.common.Botania; import vazkii.botania.common.block.ModBlocks; -import vazkii.botania.common.core.helper.ItemNBTHelper; import vazkii.botania.common.lib.LibGuiIDs; import vazkii.botania.common.lib.LibItemNames; @@ -64,22 +60,18 @@ public ItemFlowerBag() { @Nonnull @Override public ICapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound oldCapNbt) { - return new InvProvider(); + return new InvProvider(stack); } private static class InvProvider implements ICapabilitySerializable { - private final IItemHandler inv = new ItemStackHandler(16) { - @Nonnull - @Override - public ItemStack insertItem(int slot, @Nonnull ItemStack toInsert, boolean simulate) { - if(!toInsert.isEmpty() - && toInsert.getItem() == Item.getItemFromBlock(ModBlocks.flower) - && toInsert.getItemDamage() == slot) - return super.insertItem(slot, toInsert, simulate); - else return toInsert; - } - }; + private final ItemStack stack; + private final IItemHandlerModifiable inv; + + private InvProvider(ItemStack stack) { + this.stack = stack; + inv = new ItemBackedInventory.ItemHandler(() -> getInventory(stack)); + } @Override public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { @@ -95,23 +87,27 @@ public T getCapability(@Nonnull Capability capability, @Nullable EnumFaci @Override public NBTBase serializeNBT() { - return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.writeNBT(inv, null); + // Clear legacy capability data after moving it into the item tag + return new NBTTagList(); } @Override public void deserializeNBT(NBTBase nbt) { - CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.readNBT(inv, null, nbt); + if(!ItemBackedInventory.hasItems(stack, TAG_ITEMS)) { + CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.readNBT(inv, null, nbt); + } } } - @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected) { - NBTTagList oldData = ItemNBTHelper.getList(stack, TAG_ITEMS, Constants.NBT.TAG_COMPOUND, true); - if (oldData != null) { - IItemHandler newInv = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); - CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.readNBT(newInv, null, oldData); - ItemNBTHelper.removeEntry(stack, TAG_ITEMS); - } + public static ItemBackedInventory getInventory(ItemStack stack) { + return new ItemBackedInventory(stack, 16, TAG_ITEMS) { + @Override + public boolean isItemValidForSlot(int slot, @Nonnull ItemStack toInsert) { + return !toInsert.isEmpty() + && toInsert.getItem() == Item.getItemFromBlock(ModBlocks.flower) + && toInsert.getItemDamage() == slot; + } + }; } @SubscribeEvent