Package buildcraft.factory

Source Code of buildcraft.factory.TileAutoWorkbench$LocalInventoryCrafting

/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.factory;

import java.lang.ref.WeakReference;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.InventoryCraftResult;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.WorldServer;

import net.minecraftforge.common.util.ForgeDirection;

import buildcraft.api.core.IInvSlot;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.inventory.InventoryConcatenator;
import buildcraft.core.inventory.InventoryIterator;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.core.utils.CraftingHelper;
import buildcraft.core.utils.Utils;

public class TileAutoWorkbench extends TileBuildCraft implements ISidedInventory {

  public static final int SLOT_RESULT = 0;
  public static final int CRAFT_TIME = 256;
  public static final int UPDATE_TIME = 16;
  private static final int[] SLOTS = Utils.createSlotArray(0, 10);

  public InventoryCrafting craftMatrix = new LocalInventoryCrafting();
  public boolean useLast;
  public int progress;

  private SimpleInventory resultInv = new SimpleInventory(1, "Auto Workbench", 64);

  private IInventory inv = InventoryConcatenator.make().add(resultInv).add(craftMatrix);

  private SlotCrafting craftSlot;
  private InventoryCraftResult craftResult = new InventoryCraftResult();

  private int update = Utils.RANDOM.nextInt();

  private class LocalInventoryCrafting extends InventoryCrafting {

    public LocalInventoryCrafting() {
      super(new Container() {
        @Override
        public boolean canInteractWith(EntityPlayer entityplayer) {
          return false;
        }
      }, 3, 3);
    }
  }

  public WeakReference<EntityPlayer> getInternalPlayer() {
    return CoreProxy.proxy.getBuildCraftPlayer((WorldServer) worldObj, xCoord, yCoord + 1, zCoord);
  }

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

  @Override
  public ItemStack getStackInSlot(int slot) {
    return inv.getStackInSlot(slot);
  }

  @Override
  public ItemStack decrStackSize(int slot, int count) {
    return inv.decrStackSize(slot, count);
  }

  @Override
  public void setInventorySlotContents(int slot, ItemStack stack) {
    inv.setInventorySlotContents(slot, stack);
  }

  @Override
  public ItemStack getStackInSlotOnClosing(int slot) {
    return inv.getStackInSlotOnClosing(slot);
  }

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

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

  @Override
  public boolean isUseableByPlayer(EntityPlayer player) {
    return worldObj.getTileEntity(xCoord, yCoord, zCoord) == this && player.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 64.0D;
  }

  @Override
  public void readFromNBT(NBTTagCompound data) {
    super.readFromNBT(data);
    resultInv.readFromNBT(data);
    InvUtils.readInvFromNBT(craftMatrix, "matrix", data);

    // Legacy Code
    if (data.hasKey("stackList")) {
      ItemStack[] stacks = new ItemStack[9];
      InvUtils.readStacksFromNBT(data, "stackList", stacks);
      for (int i = 0; i < 9; i++) {
        craftMatrix.setInventorySlotContents(i, stacks[i]);
      }
    }
  }

  @Override
  public void writeToNBT(NBTTagCompound data) {
    super.writeToNBT(data);
    resultInv.writeToNBT(data);
    InvUtils.writeInvToNBT(craftMatrix, "matrix", data);
  }

  public ItemStack findRecipeOutput() {
    IRecipe recipe = findRecipe();
    if (recipe == null) {
      return null;
    }
    ItemStack result = recipe.getCraftingResult(craftMatrix);
    if (result != null) {
      result = result.copy();
    }
    return result;
  }

  public IRecipe findRecipe() {
    for (IInvSlot slot : InventoryIterator.getIterable(craftMatrix, ForgeDirection.UP)) {
      ItemStack stack = slot.getStackInSlot();
      if (stack == null) {
        continue;
      }
      if (!stack.isStackable()) {
        return null;
      }
      if (stack.getItem().hasContainerItem(stack)) {
        return null;
      }
    }

    return CraftingHelper.findMatchingRecipe(craftMatrix, worldObj);
  }

  @Override
  public boolean canUpdate() {
    return true;
  }

  @Override
  public void updateEntity() {
    super.updateEntity();

    if (worldObj.isRemote) {
      return;
    }

    balanceSlots();

    if (craftSlot == null) {
      craftSlot = new SlotCrafting(getInternalPlayer().get(), craftMatrix, craftResult, 0, 0, 0);
    }
    if (resultInv.getStackInSlot(SLOT_RESULT) != null) {
      return;
    }
    update++;
    if (update % UPDATE_TIME == 0) {
      updateCrafting();
    }
  }

  public int getProgressScaled(int i) {
    return (progress * i) / CRAFT_TIME;
  }

  /**
   * Evenly redistributes items between all the slots.
   */
  private void balanceSlots() {
    for (IInvSlot slotA : InventoryIterator.getIterable(craftMatrix, ForgeDirection.UP)) {
      ItemStack stackA = slotA.getStackInSlot();
      if (stackA == null) {
        continue;
      }
      for (IInvSlot slotB : InventoryIterator.getIterable(craftMatrix, ForgeDirection.UP)) {
        if (slotA.getIndex() == slotB.getIndex()) {
          continue;
        }
        ItemStack stackB = slotB.getStackInSlot();
        if (stackB == null) {
          continue;
        }
        if (StackHelper.canStacksMerge(stackA, stackB)) {
          if (stackA.stackSize > stackB.stackSize + 1) {
            stackA.stackSize--;
            stackB.stackSize++;
            return;
          }
        }
      }
    }
  }

  /**
   * Increment craft job, find recipes, produce output
   */
  private void updateCrafting() {
    IRecipe recipe = findRecipe();
    if (recipe == null) {
      progress = 0;
      return;
    }
    if (!useLast && isLast()) {
      progress = 0;
      return;
    }
    progress += UPDATE_TIME;
    if (progress < CRAFT_TIME) {
      return;
    }
    progress = 0;
    useLast = false;
    ItemStack result = recipe.getCraftingResult(craftMatrix);
    if (result == null) {
      return;
    }
    result = result.copy();
    craftSlot.onPickupFromSlot(getInternalPlayer().get(), result);
    resultInv.setInventorySlotContents(SLOT_RESULT, result);

    // clean fake player inventory (crafting handler support)
    for (IInvSlot slot : InventoryIterator.getIterable(getInternalPlayer().get().inventory, ForgeDirection.UP)) {
      ItemStack stack = slot.getStackInSlot();
      if (stack != null) {
        slot.setStackInSlot(null);
        InvUtils.dropItems(worldObj, stack, xCoord, yCoord + 1, zCoord);
      }
    }
  }

  @Override
  public void openInventory() {
  }

  @Override
  public void closeInventory() {
  }

  @Override
  public boolean isItemValidForSlot(int slot, ItemStack stack) {
    if (slot == SLOT_RESULT) {
      return false;
    }
    if (stack == null) {
      return false;
    }
    if (!stack.isStackable()) {
      return false;
    }
    if (stack.getItem().hasContainerItem(stack)) {
      return false;
    }
    if (getStackInSlot(slot) == null) {
      return false;
    }
    return true;
  }

  @Override
  public int[] getAccessibleSlotsFromSide(int var1) {
    return SLOTS;
  }

  @Override
  public boolean canInsertItem(int slot, ItemStack stack, int side) {
    return isItemValidForSlot(slot, stack);
  }

  @Override
  public boolean canExtractItem(int slot, ItemStack stack, int side) {
    return slot == SLOT_RESULT;
  }

  /**
   * Returns true if there are only enough inputs for a single craft job.
   *
   * @return true or false
   */
  public boolean isLast() {
    int minStackSize = 64;
    for (IInvSlot slot : InventoryIterator.getIterable(craftMatrix, ForgeDirection.UP)) {
      ItemStack stack = slot.getStackInSlot();
      if (stack != null && stack.stackSize < minStackSize) {
        minStackSize = stack.stackSize;
      }
    }
    return minStackSize <= 1;
  }

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

Related Classes of buildcraft.factory.TileAutoWorkbench$LocalInventoryCrafting

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.