Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions src/main/java/vazkii/botania/common/item/ItemBackedInventory.java
Original file line number Diff line number Diff line change
@@ -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<? extends ItemBackedInventory> inventorySupplier;

public ItemHandler(Supplier<? extends ItemBackedInventory> inventorySupplier) {
super(EMPTY_INVENTORY);
this.inventorySupplier = inventorySupplier;
}

@Override
public ItemBackedInventory getInv() {
return inventorySupplier.get();
}
}

}
54 changes: 26 additions & 28 deletions src/main/java/vazkii/botania/common/item/ItemBaubleBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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<NBTBase> {

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) {
Expand All @@ -80,23 +71,30 @@ public <T> T getCapability(@Nonnull Capability<T> 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
Expand Down
48 changes: 22 additions & 26 deletions src/main/java/vazkii/botania/common/item/ItemFlowerBag.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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<NBTBase> {

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) {
Expand All @@ -95,23 +87,27 @@ public <T> T getCapability(@Nonnull Capability<T> 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
Expand Down