Package buildcraft.core.robots

Source Code of buildcraft.core.robots.EntityRobot

/**
* 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.Date;
import java.util.WeakHashMap;

import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftSilicon;
import buildcraft.api.boards.RedstoneBoardNBT;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IZone;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IDockingStation;
import buildcraft.core.DefaultProps;
import buildcraft.core.LaserData;
import buildcraft.core.RFBattery;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.utils.NBTUtils;
import buildcraft.silicon.statements.ActionRobotWorkInArea;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.StatementSlot;

public class EntityRobot extends EntityRobotBase implements
    IEntityAdditionalSpawnData, IInventory, IFluidHandler {

  public static final ResourceLocation ROBOT_BASE = new ResourceLocation("buildcraft",
      DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_base.png");
  public static final ResourceLocation ROBOT_BUILDER = new ResourceLocation("buildcraft",
      DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_builder.png");
  public static final ResourceLocation ROBOT_TRANSPORT = new ResourceLocation("buildcraft",
      DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_picker.png");
  public static final ResourceLocation ROBOT_FACTORY = new ResourceLocation("buildcraft",
      DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_factory.png");

  private static ResourceLocation defaultTexture = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_base.png");

  public SafeTimeTracker scanForTasks = new SafeTimeTracker (40, 10);

  public LaserData laser = new LaserData();
  public IDockingStation linkedDockingStation;
  public BlockIndex linkedDockingStationIndex;
  public ForgeDirection linkedDockingStationSide;

  public BlockIndex currentDockingStationIndex;
  public ForgeDirection currentDockingStationSide;

  public boolean isDocked = false;

  public NBTTagCompound originalBoardNBT;
  public RedstoneBoardRobot board;
  public AIRobotMain mainAI;

  public ItemStack itemInUse;
  public float itemAngle1 = 0;
  public float itemAngle2 = 0;
  public boolean itemActive = false;
  public float itemActiveStage = 0;
  public long lastUpdateTime = 0;

  private DockingStation currentDockingStation;

  private boolean needsUpdate = false;
  private ItemStack[] inv = new ItemStack[4];
  private FluidStack tank;
  private int maxFluid = FluidContainerRegistry.BUCKET_VOLUME * 4;
  private String boardID;
  private ResourceLocation texture;

  private WeakHashMap<Entity, Boolean> unreachableEntities = new WeakHashMap<Entity, Boolean>();

  private NBTTagList stackRequestNBT;

  private RFBattery battery = new RFBattery(MAX_ENERGY, MAX_ENERGY, 0);

  private boolean firstUpdateDone = false;

  private long robotId = EntityRobotBase.NULL_ROBOT_ID;

  private int energySpendPerCycle = 0;
  private float energyFX = 0;
  private int steamDx = 0;
  private int steamDy = -1;
  private int steamDz = 0;

  public EntityRobot(World world, NBTTagCompound boardNBT) {
    this(world);

    originalBoardNBT = boardNBT;
    board = (RedstoneBoardRobot) RedstoneBoardRegistry.instance.getRedstoneBoard(boardNBT).create(boardNBT, this);
    dataWatcher.updateObject(16, board.getNBTHandler().getID());

    if (!world.isRemote) {
      mainAI = new AIRobotMain(this);
      mainAI.start();
    }
  }

  public EntityRobot(World world) {
    super(world);

    motionX = 0;
    motionY = 0;
    motionZ = 0;

    ignoreFrustumCheck = true;
    laser.isVisible = false;
    entityCollisionReduction = 1F;

    width = 0.25F;
    height = 0.25F;
  }

  @Override
  protected void entityInit() {
    super.entityInit();

    setNullBoundingBox();

    preventEntitySpawning = false;
    noClip = true;
    isImmuneToFire = true;

    dataWatcher.addObject(12, Float.valueOf(0));
    dataWatcher.addObject(13, Float.valueOf(0));
    dataWatcher.addObject(14, Float.valueOf(0));
    dataWatcher.addObject(15, Byte.valueOf((byte) 0));
    dataWatcher.addObject(16, "");
    dataWatcher.addObject(17, Float.valueOf(0));
    dataWatcher.addObject(18, Float.valueOf(0));
    dataWatcher.addObject(19, Integer.valueOf(0));
  }

  protected void updateDataClient() {
    laser.tail.x = dataWatcher.getWatchableObjectFloat(12);
    laser.tail.y = dataWatcher.getWatchableObjectFloat(13);
    laser.tail.z = dataWatcher.getWatchableObjectFloat(14);
    laser.isVisible = dataWatcher.getWatchableObjectByte(15) == 1;

    RedstoneBoardNBT<?> boardNBT = RedstoneBoardRegistry.instance.getRedstoneBoard(dataWatcher
        .getWatchableObjectString(16));

    if (boardNBT != null) {
      texture = ((RedstoneBoardRobotNBT) boardNBT).getRobotTexture();
    }

    itemAngle1 = dataWatcher.getWatchableObjectFloat(17);
    itemAngle2 = dataWatcher.getWatchableObjectFloat(18);
    energySpendPerCycle = dataWatcher.getWatchableObjectInt(19);
  }

  protected void updateDataServer() {
    dataWatcher.updateObject(12, Float.valueOf((float) laser.tail.x));
    dataWatcher.updateObject(13, Float.valueOf((float) laser.tail.y));
    dataWatcher.updateObject(14, Float.valueOf((float) laser.tail.z));
    dataWatcher.updateObject(15, Byte.valueOf((byte) (laser.isVisible ? 1 : 0)));
    dataWatcher.updateObject(17, Float.valueOf(itemAngle1));
    dataWatcher.updateObject(18, Float.valueOf(itemAngle2));
    dataWatcher.updateObject(19, energySpendPerCycle);
  }

  protected void init() {
    if (worldObj.isRemote) {
      RPCHandler.rpcServer(this, "requestInitialization");
    }
  }

  public void setLaserDestination (float x, float y, float z) {
    if (x != laser.tail.x || y != laser.tail.y || z != laser.tail.z) {
      laser.tail.x = x;
      laser.tail.y = y;
      laser.tail.z = z;

      needsUpdate = true;
    }
  }

  public void showLaser() {
    if (!laser.isVisible) {
      laser.isVisible = true;
      needsUpdate = true;
    }
  }

  public void hideLaser() {
    if (laser.isVisible) {
      laser.isVisible = false;
      needsUpdate = true;
    }
  }

  protected void firstUpdate() {
    if (stackRequestNBT != null) {

    }

    if (!worldObj.isRemote) {
      getRegistry().registerRobot(this);
    }
  }

  @Override
  public void onEntityUpdate() {
    if (!firstUpdateDone) {
      firstUpdate();
      firstUpdateDone = true;
    }

    if (!worldObj.isRemote && needsUpdate) {
      updateDataServer();
      needsUpdate = false;
    }

    if (worldObj.isRemote) {
      updateDataClient();

      energyFX += energySpendPerCycle;

      if (energyFX >= 100) {
        energyFX = 0;
        spawnEnergyFX();
      }
    }

    if (currentDockingStation != null) {
      motionX = 0;
      motionY = 0;
      motionZ = 0;
      posX = currentDockingStation.x() + 0.5F + currentDockingStation.side().offsetX * 0.5F;
      posY = currentDockingStation.y() + 0.5F + currentDockingStation.side().offsetY * 0.5F;
      posZ = currentDockingStation.z() + 0.5F + currentDockingStation.side().offsetZ * 0.5F;
    }

    if (!worldObj.isRemote) {
      if (linkedDockingStation == null) {
        linkedDockingStation = RobotRegistry.getRegistry(worldObj).getStation(
            linkedDockingStationIndex.x,
            linkedDockingStationIndex.y,
            linkedDockingStationIndex.z,
            linkedDockingStationSide);

        if (linkedDockingStation == null
            || linkedDockingStation.robotTaking() != this) {
          // Error at load time, the expected linked stations is not
          // properly set, kill this robot.

          setDead();
          return;
        }
      }

      if (currentDockingStationIndex != null && currentDockingStation == null) {
        currentDockingStation = (DockingStation)
            RobotRegistry.getRegistry(worldObj).getStation(
            currentDockingStationIndex.x,
            currentDockingStationIndex.y,
            currentDockingStationIndex.z,
            currentDockingStationSide);
      }

      if (linkedDockingStation != null) {
        mainAI.cycle();

        if (energySpendPerCycle != mainAI.getActiveAI().getEnergyCost()) {
          energySpendPerCycle = mainAI.getActiveAI().getEnergyCost();
          needsUpdate = true;
        }

        if (this.battery.getEnergyStored() <= 0) {
          setDead();
        }
      }
    }

    super.onEntityUpdate();
  }
  @SideOnly(Side.CLIENT)
  private void spawnEnergyFX() {
      Minecraft.getMinecraft().effectRenderer.addEffect(new EntityRobotEnergyFX(
                worldObj,
                posX + steamDx * 0.25, posY + steamDy * 0.25, posZ + steamDz * 0.25,
                steamDx * 0.05, steamDy * 0.05, steamDz * 0.05,
                energySpendPerCycle * 0.075F < 1 ? 1 : energySpendPerCycle * 0.075F));       
  }

  public void setRegularBoundingBox() {
    width = 0.5F;
    height = 0.5F;

    if (laser.isVisible) {
      boundingBox.minX = Math.min(posX, laser.tail.x);
      boundingBox.minY = Math.min(posY, laser.tail.y);
      boundingBox.minZ = Math.min(posZ, laser.tail.z);

      boundingBox.maxX = Math.max(posX, laser.tail.x);
      boundingBox.maxY = Math.max(posY, laser.tail.y);
      boundingBox.maxZ = Math.max(posZ, laser.tail.z);

      boundingBox.minX--;
      boundingBox.minY--;
      boundingBox.minZ--;

      boundingBox.maxX++;
      boundingBox.maxY++;
      boundingBox.maxZ++;
    } else {
      boundingBox.minX = posX - 0.25F;
      boundingBox.minY = posY - 0.25F;
      boundingBox.minZ = posZ - 0.25F;

      boundingBox.maxX = posX + 0.25F;
      boundingBox.maxY = posY + 0.25F;
      boundingBox.maxZ = posZ + 0.25F;
    }
  }

  public void setNullBoundingBox() {
    width = 0F;
    height = 0F;

    boundingBox.minX = posX;
    boundingBox.minY = posY;
    boundingBox.minZ = posZ;

    boundingBox.maxX = posX;
    boundingBox.maxY = posY;
    boundingBox.maxZ = posZ;
  }

  private void iterateBehaviorDocked() {
    motionX = 0F;
    motionY = 0F;
    motionZ = 0F;

    setNullBoundingBox ();
  }

  @Override
  public void writeSpawnData(ByteBuf data) {

  }

  @Override
  public void readSpawnData(ByteBuf data) {
    init();
  }

  @Override
  public ItemStack getHeldItem() {
    return itemInUse;
  }

  @Override
  public void setCurrentItemOrArmor(int i, ItemStack itemstack) {
  }

  @Override
  public ItemStack[] getLastActiveItems() {
    return new ItemStack [0];
  }

  @Override
    protected void fall(float par1) {}

  @Override
    protected void updateFallState(double par1, boolean par3) {}

  @Override
  public void moveEntityWithHeading(float par1, float par2) {
    this.setPosition(posX + motionX, posY + motionY, posZ + motionZ);
  }

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

  public ResourceLocation getTexture() {
    return texture;
  }

  @Override
    public void writeEntityToNBT(NBTTagCompound nbt) {
    super.writeEntityToNBT(nbt);

    NBTTagCompound linkedStationNBT = new NBTTagCompound();
    NBTTagCompound linkedStationIndexNBT = new NBTTagCompound();
    linkedDockingStationIndex.writeTo(linkedStationIndexNBT);
    linkedStationNBT.setTag("index", linkedStationIndexNBT);
    linkedStationNBT.setByte("side", (byte) linkedDockingStationSide.ordinal());
    nbt.setTag("linkedStation", linkedStationNBT);

    if (currentDockingStationIndex != null) {
      NBTTagCompound currentStationNBT = new NBTTagCompound();
      NBTTagCompound currentStationIndexNBT = new NBTTagCompound();
      currentDockingStationIndex.writeTo(currentStationIndexNBT);
      currentStationNBT.setTag("index", currentStationIndexNBT);
      currentStationNBT.setByte("side", (byte) currentDockingStationSide.ordinal());
      nbt.setTag("currentStation", currentStationNBT);
    }

    NBTTagCompound nbtLaser = new NBTTagCompound();
    laser.writeToNBT(nbtLaser);
    nbt.setTag("laser", nbtLaser);

    NBTTagCompound batteryNBT = new NBTTagCompound();
    battery.writeToNBT(batteryNBT);
    nbt.setTag("battery", batteryNBT);

    if (itemInUse != null) {
      NBTTagCompound itemNBT = new NBTTagCompound();
      itemInUse.writeToNBT(itemNBT);
      nbt.setTag("itemInUse", itemNBT);
      nbt.setBoolean("itemActive", itemActive);
    }

    for (int i = 0; i < inv.length; ++i) {
      NBTTagCompound stackNbt = new NBTTagCompound();

      if (inv[i] != null) {
        nbt.setTag("inv[" + i + "]", inv[i].writeToNBT(stackNbt));
      }
    }

    nbt.setTag("originalBoardNBT", originalBoardNBT);

    NBTTagCompound ai = new NBTTagCompound();
    mainAI.writeToNBT(ai);
    nbt.setTag("mainAI", ai);

    if (mainAI.getDelegateAI() != board) {
      NBTTagCompound boardNBT = new NBTTagCompound();
      board.writeToNBT(boardNBT);
      nbt.setTag("board", boardNBT);
    }

    nbt.setLong("robotId", robotId);

    if (tank != null) {
      NBTTagCompound tankNBT = new NBTTagCompound();

      tank.writeToNBT(tankNBT);

      nbt.setTag("tank", tankNBT);
    }
    }

  @Override
  public void readEntityFromNBT(NBTTagCompound nbt) {
    super.readEntityFromNBT(nbt);

    NBTTagCompound linkedStationNBT = nbt.getCompoundTag("linkedStation");
    linkedDockingStationIndex = new BlockIndex(linkedStationNBT.getCompoundTag("index"));
    linkedDockingStationSide = ForgeDirection.values()[linkedStationNBT.getByte("side")];

    if (nbt.hasKey("currentStation")) {
      NBTTagCompound currentStationNBT = nbt.getCompoundTag("currentStation");
      currentDockingStationIndex = new BlockIndex(currentStationNBT.getCompoundTag("index"));
      currentDockingStationSide = ForgeDirection.values()[currentStationNBT.getByte("side")];

    }

    laser.readFromNBT(nbt.getCompoundTag("laser"));

    battery.readFromNBT(nbt.getCompoundTag("battery"));

    if (nbt.hasKey("itemInUse")) {
      itemInUse = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("itemInUse"));
      itemActive = nbt.getBoolean("itemActive");
    }

    for (int i = 0; i < inv.length; ++i) {
      inv[i] = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("inv[" + i + "]"));
    }

    originalBoardNBT = nbt.getCompoundTag("originalBoardNBT");

    NBTTagCompound ai = nbt.getCompoundTag("mainAI");
    mainAI = (AIRobotMain) AIRobot.loadAI(ai, this);

    if (nbt.hasKey("board")) {
      board = (RedstoneBoardRobot) AIRobot.loadAI(nbt.getCompoundTag("board"), this);
    } else {
      board = (RedstoneBoardRobot) mainAI.getDelegateAI();
    }

    dataWatcher.updateObject(16, board.getNBTHandler().getID());

    stackRequestNBT = nbt.getTagList("stackRequests", Constants.NBT.TAG_COMPOUND);

    if (nbt.hasKey("robotId")) {
      robotId = nbt.getLong("robotId");
    }

    if (nbt.hasKey("tank")) {
      tank = FluidStack.loadFluidStackFromNBT(nbt.getCompoundTag("tank"));
    } else {
      tank = null;
    }
    }

  @Override
  public void dock(IDockingStation station) {
    currentDockingStation = (DockingStation) station;

    setSteamDirection(
        currentDockingStation.side.offsetX,
        currentDockingStation.side.offsetY,
        currentDockingStation.side.offsetZ);

    currentDockingStationIndex = currentDockingStation.index();
    currentDockingStationSide = currentDockingStation.side();
  }

  @Override
  public void undock() {
    if (currentDockingStation != null) {
      currentDockingStation.release(this);
      currentDockingStation = null;

      setSteamDirection(0, -1, 0);

      currentDockingStationIndex = null;
      currentDockingStationSide = null;
    }
  }

  @Override
  public DockingStation getDockingStation() {
    return currentDockingStation;
  }

  public void setMainStation(IDockingStation iStation) {
    DockingStation station = (DockingStation) iStation;

    if (linkedDockingStation != null && linkedDockingStation != station) {
      ((DockingStation) linkedDockingStation).release(this);
    }

    linkedDockingStation = station;
    linkedDockingStationIndex = linkedDockingStation.index();
    linkedDockingStationSide = linkedDockingStation.side();
  }

  @Override
  public ItemStack getEquipmentInSlot(int var1) {
    return null;
  }

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

  @Override
  public ItemStack getStackInSlot(int var1) {
    return inv[var1];
  }

  @Override
  public ItemStack decrStackSize(int var1, int var2) {
    ItemStack result = inv[var1].splitStack(var2);

    if (inv[var1].stackSize == 0) {
      inv[var1] = null;
    }

    RPCHandler.rpcBroadcastAllPlayers(this, "rpcClientSetInventory", var1, inv[var1]);

    return result;
  }

  @Override
  public ItemStack getStackInSlotOnClosing(int var1) {
    return inv[var1].splitStack(var1);
  }

  @Override
  public void setInventorySlotContents(int var1, ItemStack var2) {
    inv[var1] = var2;

    RPCHandler.rpcBroadcastAllPlayers(this, "rpcClientSetInventory", var1, inv[var1]);
  }

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

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

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

  @Override
  public void markDirty() {
  }

  @Override
  public boolean isUseableByPlayer(EntityPlayer var1) {
    return false;
  }

  @Override
  public void openInventory() {
  }

  @Override
  public void closeInventory() {
  }

  @Override
  public boolean isItemValidForSlot(int var1, ItemStack var2) {
    return inv[var1] == null
        || (inv[var1].isItemEqual(var2) && inv[var1].isStackable() && inv[var1].stackSize
            + var2.stackSize <= inv[var1].getItem().getItemStackLimit());
  }

  @Override
  public boolean isMoving() {
    return motionX != 0 || motionY != 0 || motionZ != 0;
  }

  @Override
  public void setItemInUse(ItemStack stack) {
    itemInUse = stack;
    RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "clientSetItemInUse", stack);
  }

  @RPC(RPCSide.CLIENT)
  private void clientSetItemInUse(ItemStack stack) {
    itemInUse = stack;
  }

  @RPC(RPCSide.CLIENT)
  private void rpcClientSetInventory(int i, ItemStack stack) {
    inv[i] = stack;
  }

  @RPC(RPCSide.SERVER)
  public void requestInitialization(RPCMessageInfo info) {
    RPCHandler.rpcPlayer(info.sender, this, "rpcInitialize", itemInUse, itemActive);

    for (int i = 0; i < inv.length; ++i) {
      RPCHandler.rpcPlayer(info.sender, this, "rpcClientSetInventory", i, inv[i]);
    }

    if (currentDockingStation != null) {
      setSteamDirection(
          currentDockingStation.side.offsetX,
          currentDockingStation.side.offsetY,
          currentDockingStation.side.offsetZ);
    } else {
      setSteamDirection(0, -1, 0);
    }
  }

  @RPC(RPCSide.CLIENT)
  private void rpcInitialize(ItemStack stack, boolean active) {
    itemInUse = stack;
    itemActive = active;
  }

  @Override
  public void setHealth(float par1) {
    // deactivate health management
  }

  @Override
  public boolean attackEntityFrom(DamageSource par1, float par2) {
    // deactivate being hit
    return false;
  }

  @Override
  public void aimItemAt(int x, int y, int z) {
    itemAngle1 = (float) Math.atan2(z - Math.floor(posZ),
        x - Math.floor(posX));

    itemAngle2 = 0;

    if (Math.floor(posY) < y) {
      itemAngle2 = (float) -Math.PI / 4;

      if (Math.floor(posX) == x && Math.floor(posZ) == z) {
        itemAngle2 -= (float) Math.PI / 4;
      }
    } else if (Math.floor(posY) > y) {
      itemAngle2 = (float) Math.PI / 2;

      if (Math.floor(posX) == x && Math.floor(posZ) == z) {
        itemAngle2 += (float) Math.PI / 4;
      }
    }

    int xComp = (int) Math.floor(posX);
    int yComp = (int) Math.floor(posY);
    int zComp = (int) Math.floor(posZ);

    setSteamDirection(xComp - x, yComp - y, zComp - z);

    updateDataServer();
  }

  @Override
  public void setItemActive(boolean isActive) {
    if (isActive != itemActive) {
      itemActive = isActive;
      RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "rpcSetItemActive", isActive);
    }
  }

  @RPC(RPCSide.CLIENT)
  private void rpcSetItemActive(boolean isActive) {
    itemActive = isActive;
    itemActiveStage = 0;
    lastUpdateTime = new Date().getTime();

    if (!isActive) {
      setSteamDirection(0, -1, 0);
    }
  }

  @RPC(RPCSide.CLIENT)
  private void setSteamDirection(int x, int y, int z) {
    if (!worldObj.isRemote) {
      RPCHandler.rpcBroadcastAllPlayers(this, "setSteamDirection", x, y, z);
    } else {
      Vec3 v = Vec3.createVectorHelper(x, y, z);
      v.normalize();

      steamDx = (int) v.xCoord;
      steamDy = (int) v.yCoord;
      steamDz = (int) v.zCoord;
    }
  }

  @Override
  public RedstoneBoardRobot getBoard() {
    return board;
  }

  @Override
  public IDockingStation getLinkedStation() {
    return linkedDockingStation;
  }

  @SideOnly(Side.CLIENT)
  @Override
  public boolean isInRangeToRenderDist(double par1) {
    return true;
    }

  @Override
  public int getEnergy() {
    return battery.getEnergyStored();
  }

  @Override
  public RFBattery getBattery() {
    return battery;
  }

  @Override
  protected boolean canDespawn() {
    return false;
  }

  public AIRobot getOverridingAI() {
    return mainAI.getOverridingAI();
  }

  public void overrideAI(AIRobot ai) {
    mainAI.setOverridingAI(ai);
  }

  public void attackTargetEntityWithCurrentItem(Entity par1Entity) {
    ItemStack stack = itemInUse;

    if (par1Entity.canAttackWithItem()) {
      if (!par1Entity.hitByEntity(this)) {
        this.setLastAttacker(par1Entity);
        boolean flag2 = par1Entity.attackEntityFrom(new EntityDamageSource("robot", this), 2.0F);

        EnchantmentHelper.func_151385_b(this, par1Entity);
        ItemStack itemstack = itemInUse;
        Object object = par1Entity;

        if (itemstack != null && object instanceof EntityLivingBase) {
          itemstack.getItem().hitEntity(itemstack, (EntityLivingBase) object, this);
        }

      }
    }
  }

  @Override
  public IZone getZoneToWork() {
    if (linkedDockingStation instanceof DockingStation) {
      for (StatementSlot s : new ActionIterator(((DockingStation) linkedDockingStation).getPipe().pipe)) {
        if (s.statement instanceof ActionRobotWorkInArea) {
          IZone zone = ActionRobotWorkInArea.getArea(s);

          if (zone != null) {
            return zone;
          }
        }
      }
    }

    return null;
  }

  @Override
  public boolean containsItems() {
    for (ItemStack element : inv) {
      if (element != null) {
        return true;
      }
    }

    return false;
  }

  @Override
  public boolean hasFreeSlot() {
    for (ItemStack element : inv) {
      if (element == null) {
        return true;
      }
    }

    return false;
  }

  @Override
  public void unreachableEntityDetected(Entity entity) {
    unreachableEntities.put(entity, true);
  }

  @Override
  public boolean isKnownUnreachable(Entity entity) {
    return unreachableEntities.containsKey(entity);
  }

  @Override
  public void setDead() {
    if (!worldObj.isRemote && !isDead) {
      // FIXME: placing a robot gives it full energy, so if it's dropped
      // for lack of energy, it's a cheap way to refuel it. Find
      // some other way to cope with that problem - such as a manual
      // charger?

      if (mainAI != null) {
        mainAI.abort();
      }

      ItemStack robotStack = new ItemStack (BuildCraftSilicon.robotItem);
      NBTUtils.getItemData(robotStack).setTag("board", originalBoardNBT);
      entityDropItem(robotStack, 0);

      getRegistry().killRobot(this);
    }

    super.setDead();
  }

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

  @Override
  protected void collideWithEntity(Entity par1Entity) {

  }

  @Override
  public void applyEntityCollision(Entity par1Entity) {

  }

  public void setUniqueRobotId(long iRobotId) {
    robotId = iRobotId;
  }

  @Override
  public long getRobotId() {
    return robotId;
  }

  @Override
  public RobotRegistry getRegistry() {
    return RobotRegistry.getRegistry(worldObj);
  }

  @Override
  public void releaseResources() {
    getRegistry().releaseResources(this);
  }

  /**
   * Tries to receive items in parameters, return items that are left after
   * the operation.
   */
  public ItemStack receiveItem(TileEntity tile, ItemStack stack) {
    if (currentDockingStation != null
        && currentDockingStation.index().nextTo(new BlockIndex(tile))
        && mainAI != null) {

      return mainAI.getActiveAI().receiveItem(stack);
    } else {
      return stack;
    }
  }

  @Override
  public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
    int result = 0;

    if (tank == null) {
      tank = new FluidStack(resource.getFluid(), 0);
    }

    if (tank.amount + resource.amount <= maxFluid) {
      result = resource.amount;

      if (doFill) {
        tank.amount += resource.amount;
      }
    } else {
      result = maxFluid - tank.amount;

      if (doFill) {
        tank.amount = maxFluid;
      }
    }

    if (tank != null && tank.amount == 0) {
      tank = null;
    }

    return result;
  }

  @Override
  public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
    if (tank != null && tank.fluidID == resource.fluidID) {
      return drain(from, resource.amount, doDrain);
    } else {
      return null;
    }
  }

  @Override
  public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
    FluidStack result = null;

    if (tank == null) {
      result = null;
    } else if (tank.amount <= maxDrain) {
      result = tank.copy();

      if (doDrain) {
        tank = null;
      }
    } else {
      result = tank.copy();
      result.amount = maxDrain;

      if (doDrain) {
        tank.amount -= maxDrain;
      }
    }

    if (tank != null && tank.amount == 0) {
      tank = null;
    }

    return result;
  }

  @Override
  public boolean canFill(ForgeDirection from, Fluid fluid) {
    return tank == null
        || tank.amount == 0
        || (tank.amount < maxFluid
        && tank.fluidID == fluid.getID());
  }

  @Override
  public boolean canDrain(ForgeDirection from, Fluid fluid) {
    return tank != null
        && tank.amount != 0
        && tank.fluidID == fluid.getID();
  }

  @Override
  public FluidTankInfo[] getTankInfo(ForgeDirection from) {
    return new FluidTankInfo[] {new FluidTankInfo(tank, maxFluid)};
  }
}
TOP

Related Classes of buildcraft.core.robots.EntityRobot

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.