Package buildcraft.core.robots

Source Code of buildcraft.core.robots.AIRobotCraftAssemblyTable$StationAssemblyTableFilter

/**
* 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.core.robots;

import java.util.ArrayList;

import net.minecraft.block.Block;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;

import net.minecraftforge.common.util.ForgeDirection;

import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IInvSlot;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.inventory.InventoryCopy;
import buildcraft.core.inventory.InventoryIterator;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.core.inventory.filters.IStackFilter;
import buildcraft.silicon.BlockLaserTable;
import buildcraft.silicon.TileAssemblyTable;
import buildcraft.silicon.statements.ActionRobotFilter;
import buildcraft.silicon.statements.ActionStationAllowCraft;

public class AIRobotCraftAssemblyTable extends AIRobotCraftGeneric {

  private CraftingResult<ItemStack> expectedResult;
  private DockingStation stationFound;
  private TileAssemblyTable table;
  private boolean craftStarted = false;
  private ArrayList<ArrayStackFilter> requirements;

  private int waitedTime = 0;

  public AIRobotCraftAssemblyTable(EntityRobotBase iRobot) {
    super(iRobot);
  }

  public AIRobotCraftAssemblyTable(EntityRobotBase iRobot, CraftingResult craftingResult) {
    super(iRobot);

    expectedResult = craftingResult;
  }

  @Override
  public void start() {
    requirements = tryCraft();
    startDelegateAI(new AIRobotSearchStation(robot, new StationAssemblyTableFilter(), robot.getZoneToWork()));
  }

  @Override
  public void update() {
    if (table != null) {
      if (!craftStarted) {
        if (requirements.size() != 0) {
          startDelegateAI(new AIRobotGotoStationAndLoad(robot, new ReqStackFilter(), robot.getZoneToWork()));
          return;
        }

        if (robot.getDockingStation() != stationFound) {
          startDelegateAI(new AIRobotGotoStation(robot, stationFound));

          return;
        }

        ITransactor trans = Transactor.getTransactorFor(table);

        for (IInvSlot s : InventoryIterator.getIterable(robot)) {
          if (s.getStackInSlot() != null) {
            ItemStack added = trans.add(s.getStackInSlot(), ForgeDirection.UNKNOWN, true);

            if (added.stackSize == 0) {
              terminate();
            } else if (added.stackSize == s.getStackInSlot().stackSize) {
              s.setStackInSlot(null);
            } else {
              s.getStackInSlot().stackSize -= added.stackSize;
            }
          }
        }

        RobotRegistry.getRegistry(robot.worldObj).take(new ResourceIdAssemblyTable(table), robot);
        table.planOutput(expectedResult.recipe);
        // TODO: How to make sure this output is not crafted more than
        // once??

        craftStarted = true;
      } else {
        waitedTime++;

        if (InvUtils.getItem(robot, new ArrayStackFilter(expectedResult.crafted)) != null) {
          crafted = true;
          terminate();
        } else if (waitedTime > 120 * 60) {
          terminate();
        }
      }
    } else {
      terminate();
    }
  }

  @Override
  public void delegateAIEnded(AIRobot ai) {
    if (ai instanceof AIRobotSearchStation) {
      if (!ai.success()) {
        crafted = false;
        terminate();
      } else {
        stationFound = ((AIRobotSearchStation) ai).targetStation;
        table = getUsableAssemblyTable(new BlockIndex(stationFound.x(), stationFound.y(), stationFound.z()));

        if (table == null) {
          terminate();
          return;
        }

        BlockIndex index = new BlockIndex(table);

        if (!robot.getRegistry().take(new ResourceIdBlock(index), robot)) {
          terminate();
        }

        if (!stationFound.take(robot)) {
          terminate();
        }
      }
    } else if (ai instanceof AIRobotGotoStationAndLoad) {
      if (!ai.success()) {
        terminate();
      } else {
        requirements = tryCraft();
      }
    }
  }

  @Override
  public ItemStack receiveItem(ItemStack stack) {
    if (StackHelper.isMatchingItem(stack, expectedResult.crafted)) {
      ITransactor robotTransactor = Transactor.getTransactorFor(robot);
      ItemStack added = robotTransactor.add(stack, ForgeDirection.UNKNOWN, true);

      stack.stackSize -= added.stackSize;

      return stack;
    } else {
      return stack;
    }
  }

  protected ArrayList<ArrayStackFilter> tryCraft() {
    Object[] items = expectedResult.usedItems.toArray();

    ArrayList<ArrayStackFilter> result = new ArrayList<ArrayStackFilter>();

    IInventory inv = new InventoryCopy(robot);

    for (Object tmp : items) {
      if (tmp == null) {
        continue;
      }

      int qty = 0;
      ArrayStackFilter filter;

      if (tmp instanceof ItemStack) {
        ItemStack stack = (ItemStack) tmp;
        qty = stack.stackSize;
        filter = new ArrayStackFilter(stack);
      } else {
        ArrayList<ItemStack> stacks = (ArrayList<ItemStack>) tmp;
        qty = stacks.get(0).stackSize;
        filter = new ArrayStackFilter(stacks.toArray(new ItemStack[stacks.size()]));
      }

      for (IInvSlot s : InventoryIterator.getIterable(inv)) {
        if (filter.matches(s.getStackInSlot())) {
          ItemStack removed = s.decreaseStackInSlot(qty);

          qty = qty - removed.stackSize;

          if (removed.stackSize == 0) {
            break;
          }
        }
      }

      if (qty > 0) {
        result.add(filter);
      }
    }

    return result;
  }

  private class StationAssemblyTableFilter implements IStationFilter {

    @Override
    public boolean matches(DockingStation station) {
      if (!ActionRobotFilter.canInteractWithItem(station, new ArrayStackFilter(expectedResult.crafted),
          ActionStationAllowCraft.class)) {
        return false;
      }

      for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
        if (getUsableAssemblyTable(new BlockIndex(station.x(), station.y(), station.z())) != null) {
          return true;
        }
      }

      return false;
    }
  }

  private TileAssemblyTable getUsableAssemblyTable(BlockIndex b) {

    for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
      BlockIndex index = new BlockIndex (b.x + dir.offsetX, b.y
          + dir.offsetY, b.z
          + dir.offsetZ);

      if (robot.getRegistry().isTaken(new ResourceIdBlock(index))) {
        continue;
      }

      Block nearbyBlock = robot.worldObj.getBlock(index.x, index.y, index.z);
      int nearbyMeta = robot.worldObj.getBlockMetadata(index.x, index.y, index.z);

      if (nearbyBlock instanceof BlockLaserTable && nearbyMeta == 0) {
        TileAssemblyTable f = (TileAssemblyTable) robot.worldObj.getTileEntity(index.x, index.y, index.z);

        // TODO: check if assembly table has some empty slots

        return f;
      }
    }

    return null;
  }

  private class ReqStackFilter implements IStackFilter {
    @Override
    public boolean matches(ItemStack stack) {
      for (ArrayStackFilter s : requirements) {
        if (s.matches(stack)) {
          return true;
        }
      }

      return false;
    }
  }
}
TOP

Related Classes of buildcraft.core.robots.AIRobotCraftAssemblyTable$StationAssemblyTableFilter

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.