Package vazkii.botania.common.core.helper

Source Code of vazkii.botania.common.core.helper.InventoryHelper$GenericInventory

/**
* This class was created by <Mikeemoo/boq/nevercast>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under a
* Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License
* (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB)
*
* File Created @ [? (GMT)]
*/
package vazkii.botania.common.core.helper;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.InventoryLargeChest;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

//From OpenBlocksLib: https://github.com/OpenMods/OpenModsLib
public class InventoryHelper {

  public static void tryInsertStack(IInventory targetInventory, int slot, ItemStack stack, boolean canMerge) {
    if(targetInventory.isItemValidForSlot(slot, stack)) {
      ItemStack targetStack = targetInventory.getStackInSlot(slot);
      if(targetStack == null) {
        int space = targetInventory.getInventoryStackLimit();
        int mergeAmount = Math.min(space, stack.stackSize);

        ItemStack copy = stack.copy();
        copy.stackSize = mergeAmount;
        targetInventory.setInventorySlotContents(slot, copy);
        stack.stackSize -= mergeAmount;
      } else if(canMerge) {
        if(targetInventory.isItemValidForSlot(slot, stack) && areMergeCandidates(stack, targetStack)) {
          int space = Math.min(targetInventory.getInventoryStackLimit(), targetStack.getMaxStackSize()) - targetStack.stackSize;
          int mergeAmount = Math.min(space, stack.stackSize);

          ItemStack copy = targetStack.copy();
          copy.stackSize += mergeAmount;
          targetInventory.setInventorySlotContents(slot, copy);
          stack.stackSize -= mergeAmount;
        }
      }
    }
  }

  protected static boolean areMergeCandidates(ItemStack source, ItemStack target) {
    return source.isItemEqual(target) && ItemStack.areItemStackTagsEqual(source, target) && target.stackSize < target.getMaxStackSize();
  }

  public static void insertItemIntoInventory(IInventory inventory, ItemStack stack) {
    insertItemIntoInventory(inventory, stack, ForgeDirection.UNKNOWN, -1);
  }

  public static void insertItemIntoInventory(IInventory inventory, ItemStack stack, ForgeDirection side, int intoSlot) {
    insertItemIntoInventory(inventory, stack, side, intoSlot, true);
  }

  public static void insertItemIntoInventory(IInventory inventory, ItemStack stack, ForgeDirection side, int intoSlot, boolean doMove) {
    insertItemIntoInventory(inventory, stack, side, intoSlot, doMove, true);
  }

  public static void insertItemIntoInventory(IInventory inventory, ItemStack stack, ForgeDirection side, int intoSlot, boolean doMove, boolean canStack) {
    if(stack == null) return;

    IInventory targetInventory = inventory;

    if(!doMove) {
      targetInventory = new GenericInventory("temporary.inventory", false, targetInventory.getSizeInventory());
      ((GenericInventory)targetInventory).copyFrom(inventory);
    }

    int i = 0;
    int[] attemptSlots = new int[0];

    if(inventory instanceof ISidedInventory && side != ForgeDirection.UNKNOWN) {
      attemptSlots = ((ISidedInventory)inventory).getAccessibleSlotsFromSide(side.ordinal());
      if(attemptSlots == null)
        attemptSlots = new int[0];
    } else {
      attemptSlots = new int[inventory.getSizeInventory()];
      for(int a = 0; a < inventory.getSizeInventory(); a++)
        attemptSlots[a] = a;
    }
    if(intoSlot > -1) {
      Set<Integer> x = new HashSet<Integer>();
      for(int attemptedSlot : attemptSlots)
        x.add(attemptedSlot);

      if(x.contains(intoSlot))
        attemptSlots = new int[] { intoSlot };
      else attemptSlots = new int[0];
    }
    while(stack.stackSize > 0 && i < attemptSlots.length) {
      if(side != ForgeDirection.UNKNOWN && inventory instanceof ISidedInventory)
        if(!((ISidedInventory)inventory).canInsertItem(attemptSlots[i], stack, side.ordinal())) {
          i++;
          continue;
        }

      tryInsertStack(targetInventory, attemptSlots[i], stack, canStack);
      i++;
    }
  }

  public static int testInventoryInsertion(IInventory inventory, ItemStack item, ForgeDirection side) {
    if(item == null || item.stackSize == 0)
      return 0;
    item = item.copy();

    if(inventory == null)
      return 0;

    int slotCount = inventory.getSizeInventory();

    int itemSizeCounter = item.stackSize;
    int[] availableSlots = new int[0];

    if(inventory instanceof ISidedInventory)
      availableSlots = ((ISidedInventory) inventory).getAccessibleSlotsFromSide(side.ordinal());
    else {
      availableSlots = new int[slotCount];
      for(int i = 0; i < slotCount; i++)
        availableSlots[i] = i;
    }

    for(int i : availableSlots) {
      if(itemSizeCounter <= 0)
        break;

      if (!inventory.isItemValidForSlot(i, item))
        continue;

      if(side != ForgeDirection.UNKNOWN && inventory instanceof ISidedInventory)
        if(!((ISidedInventory)inventory).canInsertItem(i, item, side.ordinal()))
          continue;

      ItemStack inventorySlot = inventory.getStackInSlot(i);
      if(inventorySlot == null)
        itemSizeCounter -= Math.min(Math.min(itemSizeCounter, inventory.getInventoryStackLimit()), item.getMaxStackSize());
      else if(areMergeCandidates(item, inventorySlot)) {
        int space = Math.min(inventory.getInventoryStackLimit(), inventorySlot.getMaxStackSize()) - inventorySlot.stackSize;
        itemSizeCounter -= Math.min(itemSizeCounter, space);
      }
    }

    if(itemSizeCounter != item.stackSize) {
      itemSizeCounter = Math.max(itemSizeCounter, 0);
      return item.stackSize - itemSizeCounter;
    }

    return 0;
  }

  public static IInventory getInventory(World world, int x, int y, int z) {
    TileEntity tileEntity = world.getTileEntity(x, y, z);
    if(tileEntity instanceof TileEntityChest) {
      Block chestBlock = world.getBlock(x, y, z);
      if(world.getBlock(x - 1, y, z) == chestBlock)
        return new InventoryLargeChest("Large chest", (IInventory)world.getTileEntity(x - 1, y, z), (IInventory)tileEntity);
      if(world.getBlock(x + 1, y, z) == chestBlock)
        return new InventoryLargeChest("Large chest", (IInventory)tileEntity, (IInventory)world.getTileEntity(x + 1, y, z));
      if(world.getBlock(x, y, z - 1) == chestBlock)
        return new InventoryLargeChest("Large chest", (IInventory)world.getTileEntity(x, y, z - 1), (IInventory)tileEntity);
      if(world.getBlock(x, y, z + 1) == chestBlock)
        return new InventoryLargeChest("Large chest", (IInventory)tileEntity, (IInventory)world.getTileEntity(x, y, z + 1));
    }
    return tileEntity instanceof IInventory ? (IInventory)tileEntity : null;
  }

  public static IInventory getInventory(World world, int x, int y, int z, ForgeDirection direction) {
    if(direction != null && direction != ForgeDirection.UNKNOWN) {
      x += direction.offsetX;
      y += direction.offsetY;
      z += direction.offsetZ;
    }
    return getInventory(world, x, y, z);

  }

  public static IInventory getInventory(IInventory inventory) {
    if(inventory instanceof TileEntityChest) {
      TileEntity te = (TileEntity)inventory;
      return getInventory(te.getWorldObj(), te.xCoord, te.yCoord, te.zCoord);
    }
    return inventory;
  }

  public static class GenericInventory implements IInventory {

    protected String inventoryTitle;
    protected int slotsCount;
    protected ItemStack[] inventoryContents;
    protected boolean isInvNameLocalized;

    public GenericInventory(String name, boolean isInvNameLocalized, int size) {
      this.isInvNameLocalized = isInvNameLocalized;
      slotsCount = size;
      inventoryTitle = name;
      inventoryContents = new ItemStack[size];
    }

    @Override
    public ItemStack decrStackSize(int par1, int par2) {
      if(inventoryContents[par1] != null) {
        ItemStack itemstack;

        if(inventoryContents[par1].stackSize <= par2) {
          itemstack = inventoryContents[par1];
          inventoryContents[par1] = null;
          return itemstack;
        }

        itemstack = inventoryContents[par1].splitStack(par2);
        if(inventoryContents[par1].stackSize == 0)
          inventoryContents[par1] = null;

        return itemstack;
      }
      return null;
    }

    @Override
    public int getInventoryStackLimit() {
      return 64;
    }

    @Override
    public int getSizeInventory() {
      return slotsCount;
    }

    @Override
    public ItemStack getStackInSlot(int i) {
      return inventoryContents[i];
    }

    public ItemStack getStackInSlot(Enum<?> i) {
      return getStackInSlot(i.ordinal());
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int i) {
      if(i >= inventoryContents.length)
        return null;

      if(inventoryContents[i] != null) {
        ItemStack itemstack = inventoryContents[i];
        inventoryContents[i] = null;
        return itemstack;
      }

      return null;
    }

    public boolean isItem(int slot, Item item) {
      return inventoryContents[slot] != null && inventoryContents[slot].getItem() == item;
    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack) {
      return true;
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer entityplayer) {
      return true;
    }

    public void clearAndSetSlotCount(int amount) {
      slotsCount = amount;
      inventoryContents = new ItemStack[amount];
    }

    public void readFromNBT(NBTTagCompound tag) {
      if(tag.hasKey("size"))
        slotsCount = tag.getInteger("size");

      NBTTagList nbttaglist = tag.getTagList("Items", 10);
      inventoryContents = new ItemStack[slotsCount];
      for(int i = 0; i < nbttaglist.tagCount(); i++) {
        NBTTagCompound stacktag = nbttaglist.getCompoundTagAt(i);
        int j = stacktag.getByte("Slot");
        if(j >= 0 && j < inventoryContents.length)
          inventoryContents[j] = ItemStack.loadItemStackFromNBT(stacktag);
      }
    }

    @Override
    public void setInventorySlotContents(int i, ItemStack itemstack) {
      inventoryContents[i] = itemstack;

      if(itemstack != null && itemstack.stackSize > getInventoryStackLimit())
        itemstack.stackSize = getInventoryStackLimit();
    }

    public void writeToNBT(NBTTagCompound tag) {
      tag.setInteger("size", getSizeInventory());
      NBTTagList nbttaglist = new NBTTagList();
      for(int i = 0; i < inventoryContents.length; i++) {
        if(inventoryContents[i] != null) {
          NBTTagCompound stacktag = new NBTTagCompound();
          stacktag.setByte("Slot", (byte)i);
          inventoryContents[i].writeToNBT(stacktag);
          nbttaglist.appendTag(stacktag);
        }
      }
      tag.setTag("Items", nbttaglist);
    }

    public void copyFrom(IInventory inventory) {
      for(int i = 0; i < inventory.getSizeInventory(); i++)
        if(i < getSizeInventory()) {
          ItemStack stack = inventory.getStackInSlot(i);
          if(stack != null)
            setInventorySlotContents(i, stack.copy());
          else setInventorySlotContents(i, null);
        }
    }

    public List<ItemStack> contents() {
      return Arrays.asList(inventoryContents);
    }

    @Override
    public String getInventoryName() {
      return null;
    }

    @Override
    public boolean hasCustomInventoryName() {
      return false;
    }

    @Override
    public void markDirty() { }

    @Override
    public void openInventory() { }

    @Override
    public void closeInventory() { }
  }
}
TOP

Related Classes of vazkii.botania.common.core.helper.InventoryHelper$GenericInventory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.