Package cofh.lib.util.helpers

Source Code of cofh.lib.util.helpers.InventoryHelper

package cofh.lib.util.helpers;

import cofh.api.transport.IItemDuct;

import java.util.List;

import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;

/**
* This class contains helper functions related to Inventories and Inventory manipulation.
*
* @author King Lemming
*
*/
public class InventoryHelper {

  private InventoryHelper() {

  }

  /**
   * Copy an entire inventory. Best to avoid doing this often.
   */
  public static ItemStack[] cloneInventory(ItemStack[] inventory) {

    ItemStack[] inventoryCopy = new ItemStack[inventory.length];
    for (int i = 0; i < inventory.length; i++) {
      inventoryCopy[i] = inventory[i] == null ? null : inventory[i].copy();
    }
    return inventoryCopy;
  }

  /**
   * Add an ItemStack to an inventory. Return true if the entire stack was added.
   *
   * @param inventory
   *            The inventory.
   * @param stack
   *            ItemStack to add.
   * @param startIndex
   *            First slot to attempt to add into. Does not loop around fully.
   */
  public static boolean addItemStackToInventory(ItemStack[] inventory, ItemStack stack, int startIndex) {

    if (stack == null) {
      return true;
    }
    int openSlot = -1;
    for (int i = startIndex; i < inventory.length; i++) {
      if (ItemHelper.itemsEqualForCrafting(stack, inventory[i]) && inventory[i].getMaxStackSize() > inventory[i].stackSize) {
        int hold = inventory[i].getMaxStackSize() - inventory[i].stackSize;
        if (hold >= stack.stackSize) {
          inventory[i].stackSize += stack.stackSize;
          stack = null;
          return true;
        } else {
          stack.stackSize -= hold;
          inventory[i].stackSize += hold;
        }
      } else if (inventory[i] == null && openSlot == -1) {
        openSlot = i;
      }
    }
    if (openSlot > -1) {
      inventory[openSlot] = stack;
    } else {
      return false;
    }
    return true;
  }

  /**
   * Shortcut method for above, assumes starting slot is 0.
   */
  public static boolean addItemStackToInventory(ItemStack[] inventory, ItemStack stack) {

    return addItemStackToInventory(inventory, stack, 0);
  }

  /* IInventoryHandler Interaction */

  // IInventoryHandler is not currently implemented or used. Possibly in the future.

  /* IInventory Interaction */
  public static ItemStack extractItemStackFromInventory(IInventory inventory, int side) {

    ItemStack retStack = null;

    if (inventory instanceof ISidedInventory) {
      ISidedInventory sidedInv = (ISidedInventory) inventory;
      int slots[] = sidedInv.getAccessibleSlotsFromSide(side);
      for (int i = 0; i < slots.length && retStack == null; i++) {
        if (sidedInv.getStackInSlot(i) != null && sidedInv.canExtractItem(i, sidedInv.getStackInSlot(i), side)) {
          retStack = sidedInv.getStackInSlot(i).copy();
          sidedInv.setInventorySlotContents(i, null);
        }
      }
    } else {
      for (int i = 0; i < inventory.getSizeInventory() && retStack == null; i++) {
        if (inventory.getStackInSlot(i) != null) {
          retStack = inventory.getStackInSlot(i).copy();
          inventory.setInventorySlotContents(i, null);
        }
      }
    }
    if (retStack != null) {
      inventory.markDirty();
    }
    return retStack;
  }

  public static ItemStack insertItemStackIntoInventory(IInventory inventory, ItemStack stack, int side) {

    if (stack == null) {
      return null;
    }
    int stackSize = stack.stackSize;

    if (inventory instanceof ISidedInventory) {
      ISidedInventory sidedInv = (ISidedInventory) inventory;
      int slots[] = sidedInv.getAccessibleSlotsFromSide(side);

      if (slots == null) {
        return stack;
      }
      for (int i = 0; i < slots.length && stack != null; i++) {
        if (sidedInv.canInsertItem(slots[i], stack, side) && ItemHelper.itemsEqualWithMetadata(stack, inventory.getStackInSlot(slots[i]), true)) {
          stack = addToOccupiedInventorySlot(sidedInv, slots[i], stack);
        }
      }
      for (int i = 0; i < slots.length && stack != null; i++) {
        if (sidedInv.canInsertItem(slots[i], stack, side) && inventory.getStackInSlot(slots[i]) == null) {
          stack = addToEmptyInventorySlot(sidedInv, slots[i], stack);
        }
      }
    } else {
      int invSize = inventory.getSizeInventory();
      for (int i = 0; i < invSize && stack != null; i++) {
        if (ItemHelper.itemsEqualWithMetadata(stack, inventory.getStackInSlot(i), true)) {
          stack = addToOccupiedInventorySlot(inventory, i, stack);
        }
      }
      for (int i = 0; i < invSize && stack != null; i++) {
        if (inventory.getStackInSlot(i) == null) {
          stack = addToEmptyInventorySlot(inventory, i, stack);
        }
      }
    }
    if (stack == null || stack.stackSize != stackSize) {
      inventory.markDirty();
    }
    return stack;
  }

  public static ItemStack simulateInsertItemStackIntoInventory(IInventory inventory, ItemStack stack, int side) {

    if (stack == null) {
      return null;
    }
    if (inventory instanceof ISidedInventory) {
      ISidedInventory sidedInv = (ISidedInventory) inventory;
      int slots[] = sidedInv.getAccessibleSlotsFromSide(side);

      if (slots == null) {
        return stack;
      }
      for (int i = 0; i < slots.length && stack != null; i++) {
        if (sidedInv.canInsertItem(slots[i], stack, side) && ItemHelper.itemsEqualWithMetadata(stack, inventory.getStackInSlot(slots[i]), true)) {
          stack = simulateAddToOccupiedInventorySlot(sidedInv, slots[i], stack);
        }
      }
      for (int i = 0; i < slots.length && stack != null; i++) {
        if (sidedInv.canInsertItem(slots[i], stack, side) && inventory.getStackInSlot(slots[i]) == null) {
          stack = simulateAddToEmptyInventorySlot(sidedInv, slots[i], stack);
        }
      }
    } else {
      int invSize = inventory.getSizeInventory();
      for (int i = 0; i < invSize && stack != null; i++) {
        if (ItemHelper.itemsEqualWithMetadata(stack, inventory.getStackInSlot(i), true)) {
          stack = simulateAddToOccupiedInventorySlot(inventory, i, stack);
        }
      }
      for (int i = 0; i < invSize && stack != null; i++) {
        if (inventory.getStackInSlot(i) == null) {
          stack = simulateAddToEmptyInventorySlot(inventory, i, stack);
        }
      }
    }
    return stack;
  }

  /* Slot Interaction */
  public static ItemStack addToEmptyInventorySlot(IInventory inventory, int slot, ItemStack stack) {

    if (!inventory.isItemValidForSlot(slot, stack)) {
      return stack;
    }
    int stackLimit = inventory.getInventoryStackLimit();
    inventory.setInventorySlotContents(slot, ItemHelper.cloneStack(stack, Math.min(stack.stackSize, stackLimit)));
    return stackLimit >= stack.stackSize ? null : stack.splitStack(stack.stackSize - stackLimit);
  }

  public static ItemStack addToOccupiedInventorySlot(IInventory inventory, int slot, ItemStack stack) {

    ItemStack stackInSlot = inventory.getStackInSlot(slot);
    int stackLimit = Math.min(inventory.getInventoryStackLimit(), stackInSlot.getMaxStackSize());

    if (stack.stackSize + stackInSlot.stackSize > stackLimit) {
      int stackDiff = stackLimit - stackInSlot.stackSize;
      stackInSlot.stackSize = stackLimit;
      stack.stackSize -= stackDiff;
      inventory.setInventorySlotContents(slot, stackInSlot);
      return stack;
    }
    stackInSlot.stackSize += Math.min(stack.stackSize, stackLimit);
    inventory.setInventorySlotContents(slot, stackInSlot);
    return stackLimit >= stack.stackSize ? null : stack.splitStack(stack.stackSize - stackLimit);
  }

  public static ItemStack simulateAddToEmptyInventorySlot(IInventory inventory, int slot, ItemStack stack) {

    if (!inventory.isItemValidForSlot(slot, stack)) {
      return stack;
    }
    int stackLimit = inventory.getInventoryStackLimit();
    return stackLimit >= stack.stackSize ? null : stack.splitStack(stack.stackSize - stackLimit);
  }

  public static ItemStack simulateAddToOccupiedInventorySlot(IInventory inventory, int slot, ItemStack stack) {

    ItemStack stackInSlot = inventory.getStackInSlot(slot);
    int stackLimit = Math.min(inventory.getInventoryStackLimit(), stackInSlot.getMaxStackSize());

    if (stack.stackSize + stackInSlot.stackSize > stackLimit) {
      stack.stackSize -= stackLimit - stackInSlot.stackSize;
      return stack;
    }
    return stackLimit >= stack.stackSize ? null : stack.splitStack(stack.stackSize - stackLimit);
  }

  public static boolean mergeItemStack(List<Slot> slots, ItemStack stack, int start, int length, boolean reverse) {

    return mergeItemStack(slots, stack, start, length, reverse, true);
  }

  public static boolean mergeItemStack(List<Slot> slots, ItemStack stack, int start, int length, boolean r, boolean limit) {

    boolean successful = false;
    int i = !r ? start : length - 1;
    int iterOrder = !r ? 1 : -1;

    Slot slot;
    ItemStack existingStack;

    if (stack.isStackable()) {
      while (stack.stackSize > 0 && (!r && i < length || r && i >= start)) {
        slot = slots.get(i);
        existingStack = slot.getStack();

        if (slot.isItemValid(stack) && existingStack != null && existingStack.getItem().equals(stack.getItem())
            && (!stack.getHasSubtypes() || stack.getItemDamage() == existingStack.getItemDamage())
            && ItemStack.areItemStackTagsEqual(stack, existingStack)) {
          int existingSize = existingStack.stackSize + stack.stackSize;
          int maxStack = Math.min(stack.getMaxStackSize(), slot.getSlotStackLimit());

          if (existingSize <= maxStack) {
            stack.stackSize = 0;
            existingStack.stackSize = existingSize;
            slot.onSlotChanged();
            successful = true;
          } else if (existingStack.stackSize < maxStack) {
            stack.stackSize -= maxStack - existingStack.stackSize;
            existingStack.stackSize = maxStack;
            slot.onSlotChanged();
            successful = true;
          }
        }

        i += iterOrder;
      }
    }

    if (stack.stackSize > 0) {
      i = !r ? start : length - 1;

      while (stack.stackSize > 0 && (!r && i < length || r && i >= start)) {
        slot = slots.get(i);
        existingStack = slot.getStack();

        if (slot.isItemValid(stack) && existingStack == null) {
          int maxStack = limit ? Math.min(stack.getMaxStackSize(), slot.getSlotStackLimit()) : slot.getSlotStackLimit();
          existingStack = stack.splitStack(Math.min(stack.stackSize, maxStack));
          slot.putStack(existingStack);
          slot.onSlotChanged();
          successful = true;
        }

        i += iterOrder;
      }
    }

    return successful;
  }

  /* HELPERS */
  public static ItemStack addToInsertion(Object tile, int side, ItemStack stack) {

    if (stack == null) {
      return null;
    }
    if (tile instanceof IInventory) {
      stack = insertItemStackIntoInventory((IInventory) tile, stack, BlockHelper.SIDE_OPPOSITE[side]);
    } else {
      stack = ((IItemDuct) tile).insertItem(ForgeDirection.VALID_DIRECTIONS[side ^ 1], stack);
    }
    return stack;
  }

  public static boolean isInventory(TileEntity tile) {

    return tile instanceof IInventory;
  }

  public static boolean isInsertion(Object tile) {

    return tile instanceof IInventory || tile instanceof IItemDuct;
  }

}
TOP

Related Classes of cofh.lib.util.helpers.InventoryHelper

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.