package buildcraft.robotics.ai;
import java.util.Iterator;
import java.util.LinkedList;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IZone;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.ResourceIdBlock;
import buildcraft.core.lib.utils.BlockScannerExpanding;
import buildcraft.core.lib.utils.BlockScannerRandom;
import buildcraft.core.lib.utils.BlockScannerZoneRandom;
import buildcraft.core.lib.utils.IBlockFilter;
import buildcraft.core.lib.utils.IterableAlgorithmRunner;
import buildcraft.core.lib.utils.PathFindingSearch;
public class AIRobotSearchBlock extends AIRobot {
public BlockIndex blockFound;
public LinkedList<BlockIndex> path;
private PathFindingSearch blockScanner = null;
private IterableAlgorithmRunner blockScannerJob;
private IBlockFilter pathFound;
private Iterator<BlockIndex> blockIter;
private double maxDistanceToEnd;
private IZone zone;
public AIRobotSearchBlock(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotSearchBlock(EntityRobotBase iRobot, boolean random, IBlockFilter iPathFound,
double iMaxDistanceToEnd) {
super(iRobot);
pathFound = iPathFound;
zone = iRobot.getZoneToWork();
if (!random) {
blockIter = new BlockScannerExpanding().iterator();
} else {
if (zone != null) {
BlockIndex pos = new BlockIndex(iRobot);
blockIter = new BlockScannerZoneRandom(pos.x, pos.y, pos.z, iRobot.worldObj.rand, zone)
.iterator();
} else {
blockIter = new BlockScannerRandom(iRobot.worldObj.rand, 64).iterator();
}
}
blockFound = null;
path = null;
maxDistanceToEnd = iMaxDistanceToEnd;
}
@Override
public void start() {
blockScanner = new PathFindingSearch(robot.worldObj, new BlockIndex(
robot), blockIter, pathFound, maxDistanceToEnd, 96, zone);
blockScannerJob = new IterableAlgorithmRunner(blockScanner);
blockScannerJob.start();
}
@Override
public void update() {
if (blockScannerJob == null) {
// This is probably due to a load from NBT. Abort the ai in
// that case, since there's no filter to analyze either.
abort();
return;
}
if (blockScannerJob.isDone()) {
path = blockScanner.getResult();
if (path != null && path.size() > 0) {
path.removeLast();
blockFound = blockScanner.getResultTarget();
} else {
path = null;
}
terminate();
}
}
@Override
public void end() {
if (blockScannerJob != null) {
blockScannerJob.terminate();
}
}
@Override
public boolean success() {
return blockFound != null;
}
@Override
public boolean canLoadFromNBT() {
return true;
}
@Override
public void writeSelfToNBT(NBTTagCompound nbt) {
super.writeSelfToNBT(nbt);
if (blockFound != null) {
NBTTagCompound sub = new NBTTagCompound();
blockFound.writeTo(sub);
nbt.setTag("blockFound", sub);
}
}
@Override
public void loadSelfFromNBT(NBTTagCompound nbt) {
super.loadSelfFromNBT(nbt);
if (nbt.hasKey("blockFound")) {
blockFound = new BlockIndex(nbt.getCompoundTag("blockFound"));
}
}
public boolean takeResource() {
boolean taken = false;
if (robot.getRegistry().take(new ResourceIdBlock(blockFound), robot)) {
taken = true;
}
unreserve();
return taken;
}
public void unreserve() {
blockScanner.unreserve(blockFound);
}
@Override
public int getEnergyCost() {
return 2;
}
}