package gr8pefish.ironbackpacks.container.backpack; import gr8pefish.ironbackpacks.api.items.backpacks.interfaces.IBackpack; import gr8pefish.ironbackpacks.capabilities.player.PlayerWearingBackpackCapabilities; import gr8pefish.ironbackpacks.items.backpacks.ItemBackpack; import gr8pefish.ironbackpacks.util.IronBackpacksConstants; import gr8pefish.ironbackpacks.util.NBTUtils; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraftforge.common.util.Constants; import java.util.UUID; /** * The inventory used when opening the backpack normally. */ public class InventoryBackpack implements IInventory { private ItemStack backpackStack; //the itemstack instance of the backpack private EntityPlayer player; //the player private ItemStack[] inventory; //the stored items private String sortType; //the sort option (id/alphabetical) //Instantiated from GuiHandler public InventoryBackpack(EntityPlayer player, ItemStack backpackStack){ this.backpackStack = backpackStack; this.player = player; this.inventory = new ItemStack[this.getSizeInventory()]; this.sortType = "id"; readFromNBT(backpackStack.getTagCompound()); } //Instantiated for crafting result (no-player specific opening) public InventoryBackpack(ItemStack backpackStack, boolean noPlayer){ this.backpackStack = backpackStack; this.player = null; this.inventory = new ItemStack[this.getSizeInventory()]; this.sortType = "id"; readFromNBT(backpackStack.getTagCompound(), noPlayer); } public ItemStack getBackpackStack(){ return backpackStack; } public EntityPlayer getPlayer(){ return player; } public String getSortType() { return sortType; } public void toggleSortType() { if (sortType.equals("id")) sortType = "alphabetical"; else sortType = "id"; save(); } @Override public int getSizeInventory() { return ((ItemBackpack)backpackStack.getItem()).getSize(backpackStack); } @Override public ItemStack getStackInSlot(int slotIndex) { return slotIndex >= this.getSizeInventory() ? null : this.inventory[slotIndex]; } @Override public ItemStack decrStackSize(int slotIndex, int amount) { if (inventory[slotIndex] != null) { if (inventory[slotIndex].stackSize <= amount) { ItemStack itemstack = inventory[slotIndex]; inventory[slotIndex] = null; return itemstack; } ItemStack itemstack1 = inventory[slotIndex].splitStack(amount); if (inventory[slotIndex].stackSize == 0) { inventory[slotIndex] = null; } return itemstack1; } else { return null; } } @Override public void setInventorySlotContents(int slotIndex, ItemStack itemStack) { inventory[slotIndex] = itemStack; if (itemStack != null && itemStack.stackSize > getInventoryStackLimit()) { itemStack.stackSize = getInventoryStackLimit(); } } @Override public String getName() { return ((ItemBackpack)backpackStack.getItem()).getName(backpackStack); } @Override public boolean hasCustomName() { return false; } @Override public ITextComponent getDisplayName() {return new TextComponentString(getName()); } @Override public ItemStack removeStackFromSlot(int index) { ItemStack stack = null; if (inventory[index] != null){ stack = inventory[index]; inventory[index] = null; } return stack; } @Override public int getInventoryStackLimit() { return 64; } @Override public void markDirty() { //unnecessary, as it saves when closing } @Override public boolean isUseableByPlayer(EntityPlayer player) { return true; } @Override public void openInventory(EntityPlayer player) { //unused } @Override public void closeInventory(EntityPlayer player) { //unused } @Override public boolean isItemValidForSlot(int index, ItemStack itemStack) { return true; //handled by BackpackSlot //TODO: fix this? } @Override public int getField(int id) { return 0; } @Override public void setField(int id, int value) { //nothing } @Override public int getFieldCount() { return 0; } @Override public void clear() { for (int i = 0; i < inventory.length; i++){ inventory[i] = null; } } //Helper methods for Botania's API and IBlockProvider public int hasStackInInv(Block blockToCheck, int meta){ int total = 0; for (int i = 0; i < inventory.length; i++){ if (inventory[i] != null && inventory[i].stackSize > 0){ Block backpackItemAsBlock = Block.getBlockFromItem(inventory[i].getItem()); if (backpackItemAsBlock.equals(blockToCheck) && inventory[i].getItemDamage() == meta){ total += inventory[i].stackSize; } } } return total; } public boolean removeOneItem(Block blockToCheck, int meta){ for (int i = 0; i < inventory.length; i++){ if (inventory[i] != null && inventory[i].stackSize > 0){ Block backpackItemAsBlock = Block.getBlockFromItem(inventory[i].getItem()); if (backpackItemAsBlock.equals(blockToCheck) && inventory[i].getItemDamage() == meta){ inventory[i].stackSize--; if (inventory[i].stackSize == 0) inventory[i] = null; save(); return true; } } } return false; } //=========================================================HELPER METHODS========================================================================= /** * Checks if the backpack contains any items * @return - true if it does, false otherwise */ public boolean isEmpty(){ for (ItemStack stack : inventory) { if (stack != null && stack.stackSize > 0) { return false; } } return true; } /** * Called from the container and saves the backpack. * @param entityPlayer - the player with the backpack */ public void onGuiSaved(EntityPlayer entityPlayer){ if (backpackStack != null){ save(); } } /** * Saves the backpack (on the server side only) * @param player - the player with the backpack */ public void saveWithSideCheck(EntityPlayer player){ if (!player.worldObj.isRemote) { onGuiSaved(player); } } /** * Updates the NBT data of the itemstack to save it */ public void save(){ NBTTagCompound nbtTagCompound = backpackStack.getTagCompound(); if (nbtTagCompound == null) { nbtTagCompound = new NBTTagCompound(); } writeToNBT(nbtTagCompound); backpackStack.setTagCompound(nbtTagCompound); } /** * Writes the data of the backpack to NBT form. * @param nbtTagCompound - the tag compound */ public void writeToNBT(NBTTagCompound nbtTagCompound){ if (!player.worldObj.isRemote) { //server side only ItemStack tempStack = findParentItemStack(player); ItemStack stackToUse = (tempStack == null) ? backpackStack : tempStack; nbtTagCompound = stackToUse.getTagCompound(); // Write the ItemStacks in the inventory to NBT NBTTagList tagList = new NBTTagList(); for (int i = 0; i < inventory.length; i++) { if (inventory[i] != null) { NBTTagCompound tagCompound = new NBTTagCompound(); tagCompound.setByte(IronBackpacksConstants.NBTKeys.SLOT, (byte) i); inventory[i].writeToNBT(tagCompound); tagList.appendTag(tagCompound); } } nbtTagCompound.setTag(IronBackpacksConstants.NBTKeys.ITEMS, tagList); nbtTagCompound.setTag(IronBackpacksConstants.NBTKeys.SORT_TYPE, new NBTTagString(sortType)); } } /** * Loads in the data stored in the NBT of this stack and puts the items in their respective slots. * @param nbtTagCompound - the tag compound */ //ToDo: Really need to remove this nonsense in next refactor public void readFromNBT(NBTTagCompound nbtTagCompound){ if (!player.worldObj.isRemote) { //server side only ItemStack tempStack = findParentItemStack(player); backpackStack = (tempStack == null) ? backpackStack : tempStack; if (backpackStack != null) { nbtTagCompound = backpackStack.getTagCompound(); if (nbtTagCompound != null) { //load in sortType if (nbtTagCompound.hasKey(IronBackpacksConstants.NBTKeys.SORT_TYPE)) { this.sortType = nbtTagCompound.getString(IronBackpacksConstants.NBTKeys.SORT_TYPE); } //load in items if (nbtTagCompound.hasKey(IronBackpacksConstants.NBTKeys.ITEMS)) { NBTTagList tagList = nbtTagCompound.getTagList(IronBackpacksConstants.NBTKeys.ITEMS, Constants.NBT.TAG_COMPOUND); this.inventory = new ItemStack[this.getSizeInventory()]; for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound stackTag = tagList.getCompoundTagAt(i); int j = stackTag.getByte(IronBackpacksConstants.NBTKeys.SLOT); if (i >= 0 && i <= inventory.length) { //ToDo: Remove 2nd equals (so just less than) as per a 1.7.10 PR; test it this.inventory[j] = ItemStack.loadItemStackFromNBT(stackTag); } } } } } } else { //client side: load in the sort-type for updating the sort button's tooltip if (nbtTagCompound.hasKey(IronBackpacksConstants.NBTKeys.SORT_TYPE)) { this.sortType = nbtTagCompound.getString(IronBackpacksConstants.NBTKeys.SORT_TYPE); } } } public void readFromNBT(NBTTagCompound nbtTagCompound, boolean noPlayer){ if (noPlayer && (backpackStack != null)) { nbtTagCompound = backpackStack.getTagCompound(); if (nbtTagCompound != null) { //load in sortType if (nbtTagCompound.hasKey(IronBackpacksConstants.NBTKeys.SORT_TYPE)) { this.sortType = nbtTagCompound.getString(IronBackpacksConstants.NBTKeys.SORT_TYPE); } //load in items if (nbtTagCompound.hasKey(IronBackpacksConstants.NBTKeys.ITEMS)) { NBTTagList tagList = nbtTagCompound.getTagList(IronBackpacksConstants.NBTKeys.ITEMS, Constants.NBT.TAG_COMPOUND); this.inventory = new ItemStack[this.getSizeInventory()]; for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound stackTag = tagList.getCompoundTagAt(i); int j = stackTag.getByte(IronBackpacksConstants.NBTKeys.SLOT); if (i >= 0 && i <= inventory.length) { //ToDo: Remove 2nd equals (so just less than) as per a 1.7.10 PR; test it this.inventory[j] = ItemStack.loadItemStackFromNBT(stackTag); } } } } } } /** * Helper method to get the stack, and make sure it is unique. * @param entityPlayer - the player to check * @return - the itemstack if it is found, null otherwise */ private ItemStack findParentItemStack(EntityPlayer entityPlayer){ if (NBTUtils.hasUUID(backpackStack)){ UUID parentUUID = new UUID(backpackStack.getTagCompound().getLong(IronBackpacksConstants.Miscellaneous.MOST_SIG_UUID), backpackStack.getTagCompound().getLong(IronBackpacksConstants.Miscellaneous.LEAST_SIG_UUID)); for (int i = 0; i < entityPlayer.inventory.getSizeInventory(); i++){ ItemStack itemStack = entityPlayer.inventory.getStackInSlot(i); if (itemStack != null && itemStack.getItem() instanceof IBackpack && NBTUtils.hasUUID(itemStack)){ if (itemStack.getTagCompound().getLong(IronBackpacksConstants.Miscellaneous.MOST_SIG_UUID) == parentUUID.getMostSignificantBits() && itemStack.getTagCompound().getLong(IronBackpacksConstants.Miscellaneous.LEAST_SIG_UUID) == parentUUID.getLeastSignificantBits()){ return itemStack; } } } ItemStack equipped = PlayerWearingBackpackCapabilities.getEquippedBackpack(entityPlayer); if (equipped != null && equipped.getItem() instanceof IBackpack && NBTUtils.hasUUID(equipped)) { if (equipped.getTagCompound().getLong(IronBackpacksConstants.Miscellaneous.MOST_SIG_UUID) == parentUUID.getMostSignificantBits() && equipped.getTagCompound().getLong(IronBackpacksConstants.Miscellaneous.LEAST_SIG_UUID) == parentUUID.getLeastSignificantBits()) { return equipped; } } } return null; } }