Package forestry.core.gadgets

Source Code of forestry.core.gadgets.TileAnalyzer

/*******************************************************************************
* Copyright (c) 2011-2014 SirSengir.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Various Contributors including, but not limited to:
* SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges
******************************************************************************/
package forestry.core.gadgets;

import java.util.Stack;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.Packet;

import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;

import forestry.api.core.ForestryAPI;
import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.IIndividual;
import forestry.core.EnumErrorCode;
import forestry.core.fluids.TankManager;
import forestry.core.config.Defaults;
import forestry.core.config.ForestryItem;
import forestry.core.fluids.FluidHelper;
import forestry.core.fluids.Fluids;
import forestry.core.interfaces.ILiquidTankContainer;
import forestry.core.network.EntityNetData;
import forestry.core.network.GuiId;
import forestry.core.network.PacketIds;
import forestry.core.network.PacketInventoryStack;
import forestry.core.proxy.Proxies;
import forestry.core.fluids.tanks.FilteredTank;
import forestry.core.inventory.InvTools;
import forestry.core.inventory.wrappers.IInvSlot;
import forestry.core.inventory.wrappers.InventoryIterator;
import forestry.core.inventory.wrappers.InventoryMapper;
import forestry.core.utils.InventoryAdapter;
import net.minecraft.inventory.IInventory;

public class TileAnalyzer extends TilePowered implements ISidedInventory, ILiquidTankContainer {

  /* CONSTANTS */
  public static final int TIME_TO_ANALYZE = 125;
  public static final int HONEY_REQUIRED = 100;

  public static final short SLOT_ANALYZE = 0;
  public static final short SLOT_CAN = 1;
  public static final short SLOT_INPUT_1 = 2;
  public static final short SLOT_OUTPUT_1 = 8;

  /* MEMBER */
  private final InventoryAdapter inventory = new InventoryAdapter(12, "Items");

  private int analyzeTime;

  @EntityNetData
  public FilteredTank resourceTank;

  private final TankManager tankManager;

  private final Stack<ItemStack> pendingProducts = new Stack<ItemStack>();

  private final IInventory invInput = new InventoryMapper(inventory, SLOT_INPUT_1, 6);

  /* CONSTRUCTOR */
  public TileAnalyzer() {
    super(800, 40, Defaults.MACHINE_MAX_ENERGY);
    resourceTank = new FilteredTank(Defaults.PROCESSOR_TANK_CAPACITY, Fluids.HONEY.get());
    tankManager = new TankManager(resourceTank);
  }

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

  /* GUI */
  @Override
  public void openGui(EntityPlayer player, TileBase tile) {
    player.openGui(ForestryAPI.instance, GuiId.AnalyzerGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord);
  }

  /* SAVING & LOADING */
  @Override
  public void writeToNBT(NBTTagCompound nbttagcompound) {
    super.writeToNBT(nbttagcompound);

    nbttagcompound.setInteger("AnalyzeTime", analyzeTime);

    tankManager.writeTanksToNBT(nbttagcompound);

    // / Pending Products
    NBTTagList nbttaglist = new NBTTagList();
    ItemStack[] pending = pendingProducts.toArray(new ItemStack[pendingProducts.size()]);
    for (int i = 0; i < pending.length; i++)
      if (pending[i] != null) {
        NBTTagCompound nbttagcompound1 = new NBTTagCompound();
        nbttagcompound1.setByte("Slot", (byte) i);
        pending[i].writeToNBT(nbttagcompound1);
        nbttaglist.appendTag(nbttagcompound1);
      }
    nbttagcompound.setTag("PendingProducts", nbttaglist);

    // / Inventory
    inventory.writeToNBT(nbttagcompound);
  }

  @Override
  public void readFromNBT(NBTTagCompound nbttagcompound) {
    super.readFromNBT(nbttagcompound);

    analyzeTime = nbttagcompound.getInteger("AnalyzeTime");

    tankManager.readTanksFromNBT(nbttagcompound);

    // / Pending Products
    NBTTagList nbttaglist = nbttagcompound.getTagList("PendingProducts", 10);
    for (int i = 0; i < nbttaglist.tagCount(); i++) {
      NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
      pendingProducts.add(ItemStack.loadItemStackFromNBT(nbttagcompound1));
    }

    // / Inventory
    inventory.readFromNBT(nbttagcompound);
  }

  @Override
  protected void updateServerSide() {
    // Check if we have suitable items waiting in the can slot
    FluidHelper.drainContainers(tankManager, this, SLOT_CAN);
    ItemStack can = getStackInSlot(SLOT_CAN);
    if (ForestryItem.honeyDrop.isItemEqual(can) && resourceTank.fill(Fluids.HONEY.get(Defaults.FLUID_PER_HONEY_DROP), false) == Defaults.FLUID_PER_HONEY_DROP) {
      setInventorySlotContents(SLOT_CAN, InvTools.depleteItem(can));
      resourceTank.fill(Fluids.HONEY.get(Defaults.FLUID_PER_HONEY_DROP), true);
    }

    for (int i = 0; i < invInput.getSizeInventory(); i++) {
      ItemStack inputStack = invInput.getStackInSlot(i);
      if (inputStack == null || !AlleleManager.alleleRegistry.isIndividual(inputStack))
        continue;
      // Analyzed bees in the input buffer are added to the output queue.
      IIndividual individual = AlleleManager.alleleRegistry.getIndividual(inputStack);
      if (individual.isAnalyzed()) {
        pendingProducts.push(inputStack);
        invInput.decrStackSize(i, inputStack.stackSize);
      }
    }

    tryAddPending();
    if (!pendingProducts.isEmpty()) {
      setErrorState(EnumErrorCode.NOSPACE);
      return;
    }

    if (analyzeTime == 0) {
      // Look for bees in input slots.
      IInvSlot slot = getInputSlot();
      if (slot == null) {
        // Nothing to analyze
        setErrorState(EnumErrorCode.NOTHINGANALYZE);
        return;
      }
    }

    // We need our liquid honey
    if (resourceTank.getFluidAmount() < HONEY_REQUIRED) {
      setErrorState(EnumErrorCode.NORESOURCE);
      return;
    }

    if (energyManager.getTotalEnergyStored() == 0) {
      setErrorState(EnumErrorCode.NOPOWER);
      return;
    }

    setErrorState(EnumErrorCode.OK);
  }

  /* WORKING */
  @Override
  public boolean workCycle() {
    ItemStack stackToAnalyze = getStackInSlot(SLOT_ANALYZE);
    if (analyzeTime > 0 && stackToAnalyze != null && AlleleManager.alleleRegistry.isIndividual(stackToAnalyze)) {

      analyzeTime--;

      // Still not done
      if (analyzeTime > 0) {
        setErrorState(EnumErrorCode.OK);
        return true;
      }

      // Analyzation is done.
      IIndividual individual = AlleleManager.alleleRegistry.getIndividual(stackToAnalyze);
      // No bee, abort
      if (individual == null)
        return false;

      individual.analyze();
      NBTTagCompound nbttagcompound = new NBTTagCompound();
      individual.writeToNBT(nbttagcompound);
      stackToAnalyze.setTagCompound(nbttagcompound);

      pendingProducts.push(stackToAnalyze);
      setInventorySlotContents(SLOT_ANALYZE, null);
      sendNetworkUpdate();
      return true;
    }

    analyzeTime = 0;

    // Don't start if analyze slot already occupied
    if (stackToAnalyze != null)
      return false;

    if (getErrorState() != EnumErrorCode.OK)
      return false;

    // Look for bees in input slots.
    IInvSlot slot = getInputSlot();
    ItemStack inputStack = slot.getStackInSlot();
    setInventorySlotContents(SLOT_ANALYZE, inputStack);
    slot.setStackInSlot(null);
    resourceTank.drain(HONEY_REQUIRED, true);
    analyzeTime = TIME_TO_ANALYZE;
    sendNetworkUpdate();
    return true;
  }

  private IInvSlot getInputSlot() {
    for (IInvSlot slot : InventoryIterator.getIterable(invInput)) {
      ItemStack inputStack = slot.getStackInSlot();
      if (inputStack != null && AlleleManager.alleleRegistry.isIndividual(inputStack))
        return slot;
    }
    return null;
  }

  private boolean tryAddPending() {
    if (pendingProducts.isEmpty())
      return false;

    ItemStack next = pendingProducts.peek();
    if (inventory.tryAddStack(next, SLOT_OUTPUT_1, inventory.getSizeInventory() - SLOT_OUTPUT_1, true)) {
      pendingProducts.pop();
      return true;
    }
    return false;
  }

  /* STATE INFORMATION */
  // @Override
  @Override
  public boolean isWorking() {
    return analyzeTime > 0;
  }

  @Override
  public boolean hasWork() {
    if (!pendingProducts.isEmpty())
      return true;
    if (analyzeTime > 0)
      return true;

    return getErrorState() == EnumErrorCode.OK ||getErrorState() == EnumErrorCode.NOPOWER;
  }

  public int getProgressScaled(int i) {
    return (analyzeTime * i) / TIME_TO_ANALYZE;
  }

  public int getResourceScaled(int i) {
    return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY;
  }

  public ItemStack getIndividualOnDisplay() {
    return getStackInSlot(SLOT_ANALYZE);
  }

  /* SMP */
  @Override
  public void getGUINetworkData(int i, int j) {
    i -= tankManager.maxMessageId() + 1;
    switch (i) {
    case 0:
      analyzeTime = j;
      break;
    }
  }

  @Override
  public void sendGUINetworkData(Container container, ICrafting iCrafting) {
    int i = tankManager.maxMessageId() + 1;
    iCrafting.sendProgressBarUpdate(container, i, analyzeTime);

  }

  /* ISIDEDINVENTORY */
  @Override
  public InventoryAdapter getInternalInventory() {
    return inventory;
  }

  @Override
  protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) {
    if (!super.canTakeStackFromSide(slotIndex, itemstack, side))
      return false;

    return slotIndex >= SLOT_OUTPUT_1 && slotIndex < SLOT_OUTPUT_1 + 4;
  }

  @Override
  protected boolean canPutStackFromSide(int slotIndex, ItemStack stack, int side) {

    if (!super.canPutStackFromSide(slotIndex, stack, side))
      return false;

    if (slotIndex >= SLOT_INPUT_1 && slotIndex < SLOT_INPUT_1 + 6)
      return AlleleManager.alleleRegistry.isIndividual(stack);

    if (slotIndex == SLOT_CAN)
      return Fluids.HONEY.isContained(stack);

    return false;
  }

  @Override
  public int getSizeInventory() {
    return inventory.getSizeInventory();
  }

  @Override
  public ItemStack getStackInSlot(int i) {
    return inventory.getStackInSlot(i);
  }

  @Override
  public ItemStack decrStackSize(int i, int j) {
    return inventory.decrStackSize(i, j);
  }

  @Override
  public void setInventorySlotContents(int i, ItemStack itemstack) {
    inventory.setInventorySlotContents(i, itemstack);
  }

  @Override
  public int getInventoryStackLimit() {
    return inventory.getInventoryStackLimit();
  }

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

  @Override
  public void openInventory() {
  }

  @Override
  public void closeInventory() {
  }

  /**
   * TODO: just a specialsource workaround
   */
  @Override
  public boolean isUseableByPlayer(EntityPlayer player) {
    return super.isUseableByPlayer(player);
  }

  /**
   * TODO: just a specialsource workaround
   */
  @Override
  public boolean hasCustomInventoryName() {
    return super.hasCustomInventoryName();
  }

  /**
   * TODO: just a specialsource workaround
   */
  @Override
  public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) {
    return super.isItemValidForSlot(slotIndex, itemstack);
  }

  /**
   * TODO: just a specialsource workaround
   */
  @Override
  public boolean canInsertItem(int i, ItemStack itemstack, int j) {
    return super.canInsertItem(i, itemstack, j);
  }

  /**
   * TODO: just a specialsource workaround
   */
  @Override
  public boolean canExtractItem(int i, ItemStack itemstack, int j) {
    return super.canExtractItem(i, itemstack, j);
  }

  /**
   * TODO: just a specialsource workaround
   */
  @Override
  public int[] getAccessibleSlotsFromSide(int side) {
    return super.getAccessibleSlotsFromSide(side);
  }

  /* ILIQUIDCONTAINER */
  @Override
  public TankManager getTankManager() {
    return tankManager;
  }

  @Override
  public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
    return tankManager.fill(from, resource, doFill);
  }

  @Override
  public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
    return tankManager.drain(from, resource, doDrain);
  }

  @Override
  public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
    return tankManager.drain(from, maxDrain, doDrain);
  }

  @Override
  public boolean canFill(ForgeDirection from, Fluid fluid) {
    return tankManager.canFill(from, fluid);
  }

  @Override
  public boolean canDrain(ForgeDirection from, Fluid fluid) {
    return tankManager.canDrain(from, fluid);
  }

  @Override
  public FluidTankInfo[] getTankInfo(ForgeDirection from) {
    return tankManager.getTankInfo(from);
  }

}
TOP

Related Classes of forestry.core.gadgets.TileAnalyzer

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.