Refactored Robot AI system into smaller units.

This commit is contained in:
SpaceToad 2014-06-10 00:22:22 +02:00
parent b83f2ae6dc
commit bdda0fb476
29 changed files with 882 additions and 816 deletions

View file

@ -1,16 +0,0 @@
/**
* 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.api.boards;
public interface IRedstoneBoardRobot<T> extends IRedstoneBoard<T> {
@Override
RedstoneBoardRobotNBT getNBTHandler();
}

View file

@ -23,7 +23,7 @@ import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.common.util.Constants;
public abstract class RedstoneBoardNBT {
public abstract class RedstoneBoardNBT<T> {
private static Random rand = new Random();
@ -31,7 +31,7 @@ public abstract class RedstoneBoardNBT {
public abstract void addInformation(ItemStack stack, EntityPlayer player, List list, boolean advanced);
public abstract IRedstoneBoard create(NBTTagCompound nbt);
public abstract IRedstoneBoard<T> create(NBTTagCompound nbt, T object);
@SideOnly(Side.CLIENT)
public abstract void registerIcons(IIconRegister iconRegister);

View file

@ -0,0 +1,29 @@
/**
* 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.api.boards;
import buildcraft.robots.AIRobot;
import buildcraft.robots.EntityRobotBase;
public abstract class RedstoneBoardRobot extends AIRobot implements IRedstoneBoard<EntityRobotBase> {
public RedstoneBoardRobot(EntityRobotBase iRobot) {
super(iRobot);
}
@Override
public abstract RedstoneBoardRobotNBT getNBTHandler();
@Override
public final void updateBoard(EntityRobotBase container) {
// TODO Auto-generated method stub
}
}

View file

@ -11,10 +11,12 @@ package buildcraft.api.boards;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
public abstract class RedstoneBoardRobotNBT extends RedstoneBoardNBT {
import buildcraft.robots.EntityRobotBase;
public abstract class RedstoneBoardRobotNBT extends RedstoneBoardNBT<EntityRobotBase> {
@Override
public abstract IRedstoneBoardRobot create(NBTTagCompound nbt);
public abstract RedstoneBoardRobot create(NBTTagCompound nbt, EntityRobotBase object);
public abstract ResourceLocation getRobotTexture();

View file

@ -0,0 +1,65 @@
package buildcraft.robots;
public class AIRobot {
public EntityRobotBase robot;
private AIRobot delegateAI;
private AIRobot parentAI;
public AIRobot(EntityRobotBase iRobot) {
robot = iRobot;
}
public void start() {
}
public void preempt() {
}
public void update() {
}
public void end() {
}
public void delegateAIEnded(AIRobot ai) {
}
public final void terminate() {
abortDelegateAI();
end();
if (parentAI != null) {
parentAI.delegateAI = null;
parentAI.delegateAIEnded(this);
}
}
public final void cycle() {
preempt();
if (delegateAI != null) {
delegateAI.cycle();
} else {
update();
}
}
public final void startDelegateAI(AIRobot ai) {
delegateAI = ai;
ai.parentAI = this;
delegateAI.start();
}
public final void abortDelegateAI() {
if (delegateAI != null) {
delegateAI.terminate();
}
}
}

View file

@ -0,0 +1,42 @@
/**
* 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.robots;
import net.minecraft.entity.EntityLiving;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import buildcraft.api.boards.RedstoneBoardRobot;
public abstract class EntityRobotBase extends EntityLiving implements IInventory {
public EntityRobotBase(World par1World) {
super(par1World);
}
public abstract void setItemInUse(ItemStack stack);
public abstract ItemStack getItemInUse();
public abstract void setItemActive(boolean b);
public abstract boolean isMoving();
public abstract void setCurrentDockingStation(DockingStation station);
public abstract DockingStation getCurrentDockingStation();
public abstract DockingStation getMainDockingStation();
public abstract RedstoneBoardRobot getBoard();
public abstract void setItemAngles(float a1, float a2);
}

View file

@ -12,7 +12,6 @@ import buildcraft.builders.urbanism.TileUrbanist.FrameTask;
import buildcraft.core.blueprints.BuildingSlotBlock;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.robots.IRobotTask;
import buildcraft.core.robots.RobotAIMoveAround;
public class TaskBuildSchematic implements IRobotTask {
@ -27,7 +26,8 @@ public class TaskBuildSchematic implements IRobotTask {
@Override
public void setup(EntityRobot robot) {
robot.setMainAI(new RobotAIMoveAround(robot, builder.x, builder.y, builder.z));
// robot.setMainAI(new RobotAIMoveAround(robot, builder.x, builder.y,
// builder.z));
}
@Override

View file

@ -17,9 +17,9 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import buildcraft.api.boards.IRedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardNBT;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.utils.NBTUtils;
@ -32,19 +32,11 @@ public class ItemRobot extends ItemBuildCraft {
public EntityRobot createRobot(ItemStack stack, World world) {
try {
IRedstoneBoardRobot board = null;
RedstoneBoardRobot board = null;
NBTTagCompound nbt = NBTUtils.getItemData(stack);
if (nbt.hasKey("board")) {
NBTTagCompound boardCpt = nbt.getCompoundTag("board");
RedstoneBoardNBT boardNBT = RedstoneBoardRegistry.instance.getRedstoneBoard(boardCpt);
if (boardNBT instanceof RedstoneBoardRobotNBT) {
board = ((RedstoneBoardRobotNBT) boardNBT).create(boardCpt);
}
}
EntityRobot robot = new EntityRobot(world, board);
EntityRobot robot = new EntityRobot(world, boardCpt);
return robot;
} catch (Throwable e) {

View file

@ -0,0 +1,49 @@
/**
* 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 buildcraft.robots.AIRobot;
import buildcraft.robots.DockingStation;
import buildcraft.robots.EntityRobotBase;
public class AIRobotGoToDock extends AIRobot {
private DockingStation station;
public AIRobotGoToDock(EntityRobotBase iRobot, DockingStation iStation) {
super(iRobot);
station = iStation;
}
@Override
public void start() {
if (station == robot.getCurrentDockingStation()) {
terminate();
} else {
startDelegateAI(new AIRobotMoveToBlock(robot,
station.pipe.xCoord + station.side.offsetX * 2,
station.pipe.yCoord + station.side.offsetY * 2,
station.pipe.zCoord + station.side.offsetZ * 2));
}
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotMoveToBlock) {
startDelegateAI(new AIRobotStraightMoveTo(robot,
station.pipe.xCoord + 0.5F + station.side.offsetX * 0.5F,
station.pipe.yCoord + 0.5F + station.side.offsetY * 0.5F,
station.pipe.zCoord + 0.5F + station.side.offsetZ * 0.5F));
} else {
robot.setCurrentDockingStation(station);
terminate();
}
}
}

View file

@ -8,9 +8,18 @@
*/
package buildcraft.core.robots;
public class RobotAIReturnToDock extends RobotAIGoToDock {
import buildcraft.robots.AIRobot;
import buildcraft.robots.EntityRobotBase;
public RobotAIReturnToDock(EntityRobot iRobot) {
super(iRobot, iRobot.mainDockingStation);
public class AIRobotMain extends AIRobot {
public AIRobotMain(EntityRobotBase iRobot) {
super(iRobot);
}
@Override
public void start() {
startDelegateAI(robot.getBoard());
}
}

View file

@ -0,0 +1,49 @@
/**
* 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 buildcraft.robots.AIRobot;
import buildcraft.robots.EntityRobotBase;
public abstract class AIRobotMove extends AIRobot {
protected float nextX, nextY, nextZ;
protected double dirX, dirY, dirZ;
public AIRobotMove(EntityRobotBase iRobot) {
super(iRobot);
}
protected void setDestination(EntityRobotBase robot, float x, float y, float z) {
nextX = x;
nextY = y;
nextZ = z;
dirX = nextX - robot.posX;
dirY = nextY - robot.posY;
dirZ = nextZ - robot.posZ;
double magnitude = Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
if (magnitude != 0) {
dirX /= magnitude;
dirY /= magnitude;
dirZ /= magnitude;
} else {
dirX = 0;
dirY = 0;
dirZ = 0;
}
robot.motionX = dirX / 10F;
robot.motionY = dirY / 10F;
robot.motionZ = dirZ / 10F;
}
}

View file

@ -0,0 +1,97 @@
/**
* 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.LinkedList;
import buildcraft.core.BlockIndex;
import buildcraft.core.utils.PathFinding;
import buildcraft.robots.EntityRobotBase;
public class AIRobotMoveToBlock extends AIRobotMove {
private PathFinding pathSearch;
private LinkedList<BlockIndex> path;
private double prevDistance = Double.MAX_VALUE;
private float finalX, finalY, finalZ;
public AIRobotMoveToBlock(EntityRobotBase robot, int x, int y, int z) {
super(robot);
finalX = x;
finalY = y;
finalZ = z;
}
public AIRobotMoveToBlock(EntityRobotBase robot, LinkedList<BlockIndex> iPath) {
super(robot);
path = iPath;
finalX = path.getLast().x;
finalY = path.getLast().y;
finalZ = path.getLast().z;
setNextInPath();
}
@Override
public void start() {
robot.setCurrentDockingStation(null);
if (path == null) {
pathSearch = new PathFinding(robot.worldObj, new BlockIndex((int) Math.floor(robot.posX),
(int) Math.floor(robot.posY), (int) Math.floor(robot.posZ)), new BlockIndex(
(int) Math.floor(finalX), (int) Math.floor(finalY), (int) Math.floor(finalZ)));
}
}
@Override
public void update() {
if (path != null) {
double distance = robot.getDistance(nextX, nextY, nextZ);
if (!robot.isMoving() || distance > prevDistance) {
if (path.size() > 0) {
path.removeFirst();
}
setNextInPath();
} else {
prevDistance = robot.getDistance(nextX, nextY, nextZ);
}
} else {
pathSearch.iterate(PathFinding.PATH_ITERATIONS);
if (pathSearch.isDone()) {
path = pathSearch.getResult();
setNextInPath();
}
}
if (path != null && path.size() == 0) {
terminate();
}
}
private void setNextInPath() {
if (path.size() > 0) {
BlockIndex next = path.getFirst();
setDestination(robot, next.x + 0.5F, next.y + 0.5F, next.z + 0.5F);
prevDistance = Double.MAX_VALUE;
}
}
@Override
public void end() {
robot.motionX = 0;
robot.motionY = 0;
robot.motionZ = 0;
robot.posX = finalX + 0.5F;
robot.posY = finalY + 0.5F;
robot.posZ = finalZ + 0.5F;
}
}

View file

@ -8,15 +8,15 @@
*/
package buildcraft.core.robots;
import buildcraft.robots.EntityRobotBase;
public class RobotAIDirectMoveTo extends RobotAIBase {
public class AIRobotStraightMoveTo extends AIRobotMove {
private double prevDistance = Double.MAX_VALUE;
private boolean done = false;
private float x, y, z;
public RobotAIDirectMoveTo(EntityRobot iRobot, float ix, float iy, float iz) {
public AIRobotStraightMoveTo(EntityRobotBase iRobot, float ix, float iy, float iz) {
super(iRobot);
robot = iRobot;
x = ix;
@ -26,18 +26,23 @@ public class RobotAIDirectMoveTo extends RobotAIBase {
@Override
public void start() {
robot.setCurrentDockingStation(null);
setDestination(robot, x, y, z);
}
@Override
public void updateTask() {
super.updateTask();
double distance = robot.getDistance(destX, destY, destZ);
public void update() {
double distance = robot.getDistance(nextX, nextY, nextZ);
if (distance < prevDistance) {
prevDistance = distance;
} else {
terminate();
}
}
@Override
public void end() {
robot.motionX = 0;
robot.motionY = 0;
robot.motionZ = 0;
@ -45,13 +50,5 @@ public class RobotAIDirectMoveTo extends RobotAIBase {
robot.posX = x;
robot.posY = y;
robot.posZ = z;
done = true;
}
}
@Override
public boolean isDone() {
return done;
}
}

View file

@ -12,7 +12,6 @@ import java.util.Date;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@ -21,12 +20,14 @@ import net.minecraft.util.ResourceLocation;
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.ForgeDirection;
import buildcraft.api.boards.IRedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardNBT;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.core.DefaultProps;
@ -37,8 +38,9 @@ import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.robots.DockingStation;
import buildcraft.robots.DockingStationRegistry;
import buildcraft.robots.EntityRobotBase;
public class EntityRobot extends EntityLiving implements
public class EntityRobot extends EntityRobotBase implements
IEntityAdditionalSpawnData, IInventory {
public static final ResourceLocation ROBOT_BASE = new ResourceLocation("buildcraft",
@ -60,9 +62,9 @@ public class EntityRobot extends EntityLiving implements
public DockingStation mainDockingStation;
public boolean isDocked = false;
public IRedstoneBoardRobot board;
public RedstoneBoardRobot board;
public AIRobotMain mainAI;
public RobotAIBase currentAI;
public ItemStack itemInUse;
public float itemAngle1 = 0;
public float itemAngle2 = 0;
@ -70,21 +72,22 @@ public class EntityRobot extends EntityLiving implements
public float itemActiveStage = 0;
public long lastUpdateTime = 0;
protected RobotAIBase nextAI;
private boolean needsUpdate = false;
private ItemStack[] inv = new ItemStack[6];
private String boardID;
private ResourceLocation texture;
public EntityRobot(World world, IRedstoneBoardRobot iBoard) {
public EntityRobot(World world, NBTTagCompound boardNBT) {
this(world);
board = iBoard;
board = (RedstoneBoardRobot) RedstoneBoardRegistry.instance.getRedstoneBoard(boardNBT).create(boardNBT, this);
dataWatcher.updateObject(16, board.getNBTHandler().getID());
if (world.isRemote) {
RPCHandler.rpcServer(this, "requestInitialization", itemInUse);
} else {
mainAI = new AIRobotMain(this);
mainAI.start();
}
}
@ -187,18 +190,17 @@ public class EntityRobot extends EntityLiving implements
updateDataClient();
}
if (nextAI != null) {
if (currentAI != null) {
tasks.removeTask(currentAI);
}
currentAI = nextAI;
nextAI = null;
tasks.addTask(0, currentAI);
if (currentDockingStation != null) {
motionX = 0;
motionY = 0;
motionZ = 0;
posX = currentDockingStation.pipe.xCoord + 0.5F + currentDockingStation.side.offsetX * 0.5F;
posY = currentDockingStation.pipe.yCoord + 0.5F + currentDockingStation.side.offsetY * 0.5F;
posZ = currentDockingStation.pipe.zCoord + 0.5F + currentDockingStation.side.offsetZ * 0.5F;
}
if (!worldObj.isRemote) {
board.updateBoard(this);
mainAI.cycle();
if (currentTask == null) {
if (scanForTasks.markTimeIfDelay(worldObj)) {
@ -330,10 +332,6 @@ public class EntityRobot extends EntityLiving implements
nbt.setInteger("dockSide", mainDockingStation.side.ordinal());
}
if (currentAI != null) {
nbt.setString("ai", currentAI.getClass().getCanonicalName());
}
NBTTagCompound nbtLaser = new NBTTagCompound();
laser.writeToNBT(nbtLaser);
nbt.setTag("laser", nbtLaser);
@ -390,10 +388,6 @@ public class EntityRobot extends EntityLiving implements
return true;
}
public void setMainAI (RobotAIBase ai) {
nextAI = ai;
}
@Override
public int getSizeInventory() {
return inv.length;
@ -465,10 +459,12 @@ public class EntityRobot extends EntityLiving implements
.getItemStackLimit());
}
@Override
public boolean isMoving() {
return motionX != 0 || motionY != 0 || motionZ != 0;
}
@Override
public void setItemInUse(ItemStack stack) {
itemInUse = stack;
RPCHandler.rpcBroadcastPlayers(worldObj, this, "clientSetItemInUse", stack);
@ -489,12 +485,14 @@ public class EntityRobot extends EntityLiving implements
// deactivate healh management
}
public void setItemAngle(float a1, float a2) {
@Override
public void setItemAngles(float a1, float a2) {
itemAngle1 = a1;
itemAngle2 = a2;
updateDataServer();
}
@Override
public void setItemActive(boolean isActive) {
RPCHandler.rpcBroadcastPlayers(worldObj, this, "rpcSetItemActive", isActive);
}
@ -505,4 +503,36 @@ public class EntityRobot extends EntityLiving implements
itemActiveStage = 0;
lastUpdateTime = new Date().getTime();
}
@Override
public void setCurrentDockingStation(DockingStation station) {
currentDockingStation = station;
}
@Override
public ItemStack getItemInUse() {
return itemInUse;
}
@Override
public RedstoneBoardRobot getBoard() {
return board;
}
@Override
public DockingStation getCurrentDockingStation() {
return currentDockingStation;
}
@Override
public DockingStation getMainDockingStation() {
return mainDockingStation;
}
@SideOnly(Side.CLIENT)
@Override
public boolean isInRangeToRenderDist(double par1) {
return true;
}
}

View file

@ -1,91 +0,0 @@
/**
* 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 net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.nbt.NBTTagCompound;
public class RobotAIBase extends EntityAIBase {
protected float destX, destY, destZ;
protected double dirX, dirY, dirZ;
protected EntityRobot robot;
private boolean isStarted = false;
public RobotAIBase(EntityRobot iRobot) {
robot = iRobot;
}
public void setDestination(EntityRobot robot, float x, float y, float z) {
robot.isDocked = false;
robot.currentDockingStation = null;
destX = x;
destY = y;
destZ = z;
dirX = destX - robot.posX;
dirY = destY - robot.posY;
dirZ = destZ - robot.posZ;
double magnitude = Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
dirX /= magnitude;
dirY /= magnitude;
dirZ /= magnitude;
robot.motionX = dirX / 10F;
robot.motionY = dirY / 10F;
robot.motionZ = dirZ / 10F;
}
@Override
public void updateTask() {
super.updateTask();
if (!isStarted) {
start();
isStarted = true;
}
}
public void writeToNBT(NBTTagCompound nbt) {
nbt.setFloat("destX", destX);
nbt.setFloat("destY", destY);
nbt.setFloat("destZ", destZ);
nbt.setDouble("dirX", dirX);
nbt.setDouble("dirY", dirY);
nbt.setDouble("dirZ", dirZ);
}
public void readFromNBT(NBTTagCompound nbt) {
destX = nbt.getFloat("destX");
destY = nbt.getFloat("destY");
destZ = nbt.getFloat("destZ");
dirX = nbt.getDouble("dirX");
dirY = nbt.getDouble("dirY");
dirZ = nbt.getDouble("dirZ");
}
@Override
public boolean shouldExecute() {
return true;
}
public boolean isDone() {
return false;
}
public void start() {
}
}

View file

@ -1,49 +0,0 @@
/**
* 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.LinkedList;
public class RobotAIComposite extends RobotAIBase {
LinkedList<RobotAIBase> cpts = new LinkedList<RobotAIBase>();
public RobotAIComposite(EntityRobot iRobot, RobotAIBase... icpts) {
super(iRobot);
for (RobotAIBase ai : icpts) {
cpts.add(ai);
}
}
@Override
public void updateTask() {
if (cpts.size() > 0) {
if (cpts.getFirst().isDone()) {
cpts.removeFirst();
} else {
cpts.getFirst().updateTask();
}
}
}
@Override
public boolean shouldExecute() {
if (cpts.size() > 0) {
return cpts.getFirst().shouldExecute();
} else {
return true;
}
}
@Override
public boolean isDone() {
return cpts.size() == 0;
}
}

View file

@ -1,36 +0,0 @@
/**
* 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 buildcraft.robots.DockingStation;
public class RobotAIDocked extends RobotAIBase {
private DockingStation station;
public RobotAIDocked(EntityRobot iRobot, DockingStation iStation) {
super(iRobot);
station = iStation;
}
@Override
public void updateTask() {
super.updateTask();
robot.isDocked = true;
robot.motionX = 0;
robot.motionY = 0;
robot.motionZ = 0;
robot.posX = station.pipe.xCoord + 0.5F + station.side.offsetX * 0.5F;
robot.posY = station.pipe.yCoord + 0.5F + station.side.offsetY * 0.5F;
robot.posZ = station.pipe.zCoord + 0.5F + station.side.offsetZ * 0.5F;
robot.currentDockingStation = station;
}
}

View file

@ -1,27 +0,0 @@
/**
* 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 buildcraft.robots.DockingStation;
public class RobotAIGoToDock extends RobotAIComposite {
public RobotAIGoToDock(EntityRobot iRobot, DockingStation station) {
super(iRobot,
new RobotAIMoveTo(iRobot,
station.pipe.xCoord + 0.5F + station.side.offsetX * 1.5F,
station.pipe.yCoord + 0.5F + station.side.offsetY * 1.5F,
station.pipe.zCoord + 0.5F + station.side.offsetZ * 1.5F),
new RobotAIDirectMoveTo(iRobot,
station.pipe.xCoord + 0.5F + station.side.offsetX * 0.5F,
station.pipe.yCoord + 0.5F + station.side.offsetY * 0.5F,
station.pipe.zCoord + 0.5F + station.side.offsetZ * 0.5F),
new RobotAIDocked(iRobot, station));
}
}

View file

@ -1,87 +0,0 @@
/**
* 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 net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
public class RobotAIMoveAround extends RobotAIBase {
protected float aroundX, aroundY, aroundZ;
double prevDistance = Double.MAX_VALUE;
public RobotAIMoveAround(EntityRobot robot) {
super(robot);
}
public RobotAIMoveAround (EntityRobot robot, float x, float y, float z) {
super(robot);
aroundX = x;
aroundY = y;
aroundZ = z;
randomDestination(robot);
}
@Override
public void updateTask() {
super.updateTask();
double distance = robot.getDistance(destX, destY, destZ);
if (distance >= prevDistance) {
randomDestination(robot);
prevDistance = Double.MAX_VALUE;
} else {
prevDistance = robot.getDistance(destX, destY, destZ);
}
}
public void randomDestination(EntityRobot robot) {
for (int i = 0; i < 5; ++i) {
float testX = aroundX + robot.worldObj.rand.nextFloat() * 10F - 5F;
float testY = aroundY + robot.worldObj.rand.nextFloat() * 5F;
float testZ = aroundZ + robot.worldObj.rand.nextFloat() * 10F - 5F;
Block block = robot.worldObj.getBlock((int) testX, (int) testY,
(int) testZ);
// We set a destination. If it's wrong, we try a new one.
// Eventually, we'll accept even a wrong one if none can be easily
// found.
setDestination(robot, testX, testY, testZ);
if (block == Blocks.air) {
return;
}
}
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setFloat("aroundX", aroundX);
nbt.setFloat("aroundY", aroundY);
nbt.setFloat("aroundZ", aroundZ);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
aroundX = nbt.getFloat("aroundX");
aroundY = nbt.getFloat("aroundY");
aroundZ = nbt.getFloat("aroundZ");
}
}

View file

@ -1,99 +0,0 @@
/**
* 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.LinkedList;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.core.BlockIndex;
import buildcraft.core.utils.PathFinding;
public class RobotAIMoveTo extends RobotAIBase {
private PathFinding pathSearch;
private LinkedList<BlockIndex> path;
private double prevDistance = Double.MAX_VALUE;
private float dx, dy, dz;
public RobotAIMoveTo (EntityRobot robot, float x, float y, float z) {
super(robot);
dx = x;
dy = y;
dz = z;
}
public RobotAIMoveTo(EntityRobot robot, LinkedList<BlockIndex> iPath) {
super(robot);
path = iPath;
dx = path.getLast().x;
dy = path.getLast().y;
dz = path.getLast().z;
setNextInPath();
}
@Override
public void updateTask() {
super.updateTask();
if (path != null) {
double distance = robot.getDistance(destX, destY, destZ);
if (!robot.isMoving() || distance > prevDistance) {
if (path.size() > 0) {
path.removeFirst();
}
setNextInPath();
} else {
prevDistance = robot.getDistance(destX, destY, destZ);
}
if (path.size() == 0) {
robot.motionX = 0;
robot.motionY = 0;
robot.motionZ = 0;
}
} else if (pathSearch == null) {
pathSearch = new PathFinding
(robot.worldObj,
new BlockIndex((int) Math.floor(robot.posX), (int) Math.floor(robot.posY),
(int) Math.floor(robot.posZ)),
new BlockIndex((int) Math.floor(dx), (int) Math.floor(dy), (int) Math.floor(dz)));
} else if (pathSearch.isDone()) {
path = pathSearch.getResult();
setNextInPath();
} else {
pathSearch.iterate(PathFinding.PATH_ITERATIONS);
}
}
private void setNextInPath() {
if (path.size() > 0) {
BlockIndex next = path.getFirst();
setDestination(robot, next.x + 0.5F, next.y + 0.5F, next.z + 0.5F);
prevDistance = Double.MAX_VALUE;
}
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public boolean isDone() {
return path != null && path.size() == 0;
}
}

View file

@ -0,0 +1,114 @@
/**
* 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.boards;
import net.minecraft.block.Block;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.ForgeHooks;
import buildcraft.core.BlockIndex;
import buildcraft.core.utils.BlockUtil;
import buildcraft.robots.AIRobot;
import buildcraft.robots.EntityRobotBase;
public class AIRobotCutWood extends AIRobot {
private float blockDamage = 0;
private BlockIndex woodToChop;
private Block block;
private int meta;
private float hardness;
private float speed;
public AIRobotCutWood(EntityRobotBase iRobot, BlockIndex iWoodToChop) {
super(iRobot);
woodToChop = iWoodToChop;
float a1 = (float) Math.atan2(woodToChop.z - Math.floor(robot.posZ),
woodToChop.x - Math.floor(robot.posX));
float a2 = 0;
if (Math.floor(robot.posY) < woodToChop.y) {
a2 = (float) -Math.PI / 4;
if (Math.floor(robot.posX) == woodToChop.x && Math.floor(robot.posZ) == woodToChop.z) {
a2 -= (float) Math.PI / 4;
}
} else if (Math.floor(robot.posY) > woodToChop.y) {
a2 = (float) Math.PI / 2;
if (Math.floor(robot.posX) == woodToChop.x && Math.floor(robot.posZ) == woodToChop.z) {
a2 += (float) Math.PI / 4;
}
}
robot.setItemAngles(a1, a2);
robot.setItemActive(true);
block = robot.worldObj.getBlock(woodToChop.x, woodToChop.y, woodToChop.z);
meta = robot.worldObj.getBlockMetadata(woodToChop.x, woodToChop.y, woodToChop.z);
hardness = block.getBlockHardness(robot.worldObj, woodToChop.x, woodToChop.y, woodToChop.z);
speed = getBreakSpeed(robot, robot.getItemInUse(), block, meta);
}
@Override
public void update() {
blockDamage += speed / hardness / 30F;
if (blockDamage > 1.0F) {
robot.worldObj.destroyBlockInWorldPartially(robot.getEntityId(), woodToChop.x,
woodToChop.y, woodToChop.z, -1);
blockDamage = 0;
BlockUtil.breakBlock((WorldServer) robot.worldObj, woodToChop.x, woodToChop.y, woodToChop.z, 6000);
robot.worldObj.setBlockToAir(woodToChop.x, woodToChop.y, woodToChop.z);
robot.setItemActive(false);
robot.getItemInUse().getItem().onBlockDestroyed(robot.getItemInUse(), robot.worldObj, block, woodToChop.x,
woodToChop.y, woodToChop.z, robot);
if (robot.getItemInUse().getItemDamage() >= robot.getItemInUse().getMaxDamage()) {
robot.setItemInUse(null);
}
terminate();
} else {
robot.worldObj.destroyBlockInWorldPartially(robot.getEntityId(), woodToChop.x,
woodToChop.y, woodToChop.z, (int) (blockDamage * 10.0F) - 1);
}
}
private float getBreakSpeed(EntityRobotBase robot, ItemStack usingItem, Block block, int meta) {
ItemStack stack = usingItem;
float f = stack == null ? 1.0F : stack.getItem().getDigSpeed(stack, block, meta);
if (f > 1.0F) {
int i = EnchantmentHelper.getEfficiencyModifier(robot);
ItemStack itemstack = usingItem;
if (i > 0 && itemstack != null) {
float f1 = i * i + 1;
boolean canHarvest = ForgeHooks.canToolHarvestBlock(block, meta, itemstack);
if (!canHarvest && f <= 1.0F) {
f += f1 * 0.08F;
} else {
f += f1;
}
}
}
return f;
}
}

View file

@ -0,0 +1,83 @@
/**
* 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.boards;
import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.core.robots.AIRobotGoToDock;
import buildcraft.robots.AIRobot;
import buildcraft.robots.DockingStation;
import buildcraft.robots.DockingStationRegistry;
import buildcraft.robots.EntityRobotBase;
public class AIRobotFetchAxe extends AIRobot {
private DockingStation axeDocking = null;
public AIRobotFetchAxe(EntityRobotBase iRobot) {
super(iRobot);
}
@Override
public void update() {
for (DockingStation d : DockingStationRegistry.getStations()) {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
TileEntity nearbyTile = robot.worldObj.getTileEntity(d.pipe.xCoord + dir.offsetX, d.pipe.yCoord
+ dir.offsetY, d.pipe.zCoord
+ dir.offsetZ);
if (nearbyTile != null && nearbyTile instanceof IInventory) {
ArrayStackFilter filter = new ArrayStackFilter(new ItemStack(Items.wooden_axe));
ITransactor trans = Transactor.getTransactorFor(nearbyTile);
if (trans.remove(filter, dir.getOpposite(), false) != null) {
axeDocking = d;
startDelegateAI(new AIRobotGoToDock(robot, axeDocking));
return;
}
}
}
}
}
@Override
public void delegateAIEnded(AIRobot ai) {
ItemStack axeFound = null;
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
TileEntity nearbyTile = robot.worldObj.getTileEntity(axeDocking.pipe.xCoord + dir.offsetX,
axeDocking.pipe.yCoord
+ dir.offsetY, axeDocking.pipe.zCoord + dir.offsetZ);
if (nearbyTile != null && nearbyTile instanceof IInventory) {
ArrayStackFilter filter = new ArrayStackFilter(new ItemStack(Items.wooden_axe));
ITransactor trans = Transactor.getTransactorFor(nearbyTile);
axeFound = trans.remove(filter, dir.getOpposite(), true);
if (axeFound != null) {
break;
}
}
}
if (axeFound != null) {
robot.setItemInUse(axeFound);
terminate();
}
}
}

View file

@ -0,0 +1,108 @@
/**
* 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.boards;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.core.inventory.TransactorSimple;
import buildcraft.core.inventory.filters.IStackFilter;
import buildcraft.core.robots.AIRobotMoveToBlock;
import buildcraft.robots.AIRobot;
import buildcraft.robots.EntityRobotBase;
public class AIRobotFetchItem extends AIRobot {
public EntityItem target;
private float maxRange;
private IStackFilter stackFilter;
private int pickTime = -1;
public AIRobotFetchItem(EntityRobotBase iRobot, float iMaxRange, IStackFilter iStackFilter) {
super(iRobot);
maxRange = iMaxRange;
stackFilter = iStackFilter;
}
@Override
public void start() {
TransactorSimple inventoryInsert = new TransactorSimple(robot);
for (Object o : robot.worldObj.loadedEntityList) {
Entity e = (Entity) o;
if (!e.isDead && e instanceof EntityItem && !BoardRobotPicker.targettedItems.contains(e.getEntityId())) {
double dx = e.posX - robot.posX;
double dy = e.posY - robot.posY;
double dz = e.posZ - robot.posZ;
double sqrDistance = dx * dx + dy * dy + dz * dz;
double maxDistance = maxRange * maxRange;
if (sqrDistance >= maxDistance) {
continue;
} else if (stackFilter != null && !stackFilter.matches(((EntityItem) e).getEntityItem())) {
continue;
} else {
EntityItem item = (EntityItem) e;
if (inventoryInsert.inject(item.getEntityItem(), ForgeDirection.UNKNOWN, false) > 0) {
target = item;
BoardRobotPicker.targettedItems.add(e.getEntityId());
startDelegateAI(new AIRobotMoveToBlock(robot, (int) Math.floor(e.posX),
(int) Math.floor(e.posY), (int) Math.floor(e.posZ)));
return;
}
}
}
}
// No item was found, terminate this AI
terminate();
}
@Override
public void preempt() {
if (target.isDead) {
BoardRobotPicker.targettedItems.remove(target.getEntityId());
terminate();
}
}
@Override
public void update() {
if (target.isDead) {
BoardRobotPicker.targettedItems.remove(target.getEntityId());
terminate();
} else {
pickTime++;
if (pickTime > 20) {
TransactorSimple inventoryInsert = new TransactorSimple(robot);
target.getEntityItem().stackSize -= inventoryInsert.inject(
target.getEntityItem(), ForgeDirection.UNKNOWN,
true);
if (target.getEntityItem().stackSize <= 0) {
target.setDead();
}
BoardRobotPicker.targettedItems.remove(target.getEntityId());
terminate();
}
}
}
}

View file

@ -0,0 +1,60 @@
/**
* 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.boards;
import java.util.LinkedList;
import net.minecraft.init.Blocks;
import net.minecraft.world.IBlockAccess;
import buildcraft.core.BlockIndex;
import buildcraft.core.robots.AIRobotMoveToBlock;
import buildcraft.core.utils.IPathFound;
import buildcraft.core.utils.PathFinding;
import buildcraft.robots.AIRobot;
import buildcraft.robots.EntityRobotBase;
public class AIRobotGoToWood extends AIRobot {
public BlockIndex woodFound;
private PathFinding woodScanner = null;
public AIRobotGoToWood(EntityRobotBase iRobot) {
super(iRobot);
}
@Override
public void start() {
woodScanner = new PathFinding(robot.worldObj, new BlockIndex(robot), new IPathFound() {
@Override
public boolean endReached(IBlockAccess world, int x, int y, int z) {
return world.getBlock(x, y, z) == Blocks.log || world.getBlock(x, y, z) == Blocks.log2;
}
});
}
@Override
public void update() {
woodScanner.iterate(PathFinding.PATH_ITERATIONS);
if (woodScanner.isDone()) {
LinkedList<BlockIndex> path = woodScanner.getResult();
woodFound = path.removeLast();
startDelegateAI(new AIRobotMoveToBlock(robot, path));
}
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotMoveToBlock) {
terminate();
}
}
}

View file

@ -1,229 +1,44 @@
/**
* 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.boards;
import java.util.LinkedList;
import net.minecraft.block.Block;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.boards.IRedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardNBT;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.core.BlockIndex;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.robots.RobotAIGoToDock;
import buildcraft.core.robots.RobotAIMoveTo;
import buildcraft.core.utils.BlockUtil;
import buildcraft.core.utils.IPathFound;
import buildcraft.core.utils.PathFinding;
import buildcraft.robots.DockingStation;
import buildcraft.robots.DockingStationRegistry;
import buildcraft.robots.AIRobot;
import buildcraft.robots.EntityRobotBase;
public class BoardRobotLumberjack implements IRedstoneBoardRobot<EntityRobot> {
public class BoardRobotLumberjack extends RedstoneBoardRobot {
private static enum Stages {
LOOK_FOR_AXE, GO_TO_AXE_INVENTORY, LOOK_FOR_WOOD, GO_TO_WOOD, CUT_WOOD
};
private NBTTagCompound data;
private RedstoneBoardNBT board;
private int range;
private boolean initialized = false;
private PathFinding woodScanner = null;
private DockingStation axeDocking = null;
private Stages stage = Stages.LOOK_FOR_AXE;
private BlockIndex woodToChop;
private float blockDamage;
public BoardRobotLumberjack(NBTTagCompound nbt) {
data = nbt;
board = RedstoneBoardRegistry.instance.getRedstoneBoard(nbt);
public BoardRobotLumberjack(EntityRobotBase iRobot, NBTTagCompound nbt) {
super(iRobot);
}
@Override
public void updateBoard(EntityRobot robot) {
if (robot.worldObj.isRemote) {
return;
}
if (!initialized) {
range = data.getInteger("range");
initialized = true;
}
if (stage == Stages.LOOK_FOR_AXE) {
for (DockingStation d : DockingStationRegistry.getStations()) {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
TileEntity nearbyTile = robot.worldObj.getTileEntity(d.pipe.xCoord + dir.offsetX, d.pipe.yCoord
+ dir.offsetY, d.pipe.zCoord
+ dir.offsetZ);
if (nearbyTile != null && nearbyTile instanceof IInventory) {
ArrayStackFilter filter = new ArrayStackFilter(new ItemStack(Items.wooden_axe));
ITransactor trans = Transactor.getTransactorFor(nearbyTile);
if (trans.remove(filter, dir.getOpposite(), false) != null) {
axeDocking = d;
robot.setMainAI(new RobotAIGoToDock(robot, axeDocking));
stage = Stages.GO_TO_AXE_INVENTORY;
return;
}
}
}
}
} else if (stage == Stages.GO_TO_AXE_INVENTORY) {
if (robot.currentDockingStation != null && robot.currentDockingStation.equals(axeDocking)) {
ItemStack axeFound = null;
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
TileEntity nearbyTile = robot.worldObj.getTileEntity(axeDocking.pipe.xCoord + dir.offsetX,
axeDocking.pipe.yCoord
+ dir.offsetY, axeDocking.pipe.zCoord + dir.offsetZ);
if (nearbyTile != null && nearbyTile instanceof IInventory) {
ArrayStackFilter filter = new ArrayStackFilter(new ItemStack(Items.wooden_axe));
ITransactor trans = Transactor.getTransactorFor(nearbyTile);
axeFound = trans.remove(filter, dir.getOpposite(), true);
if (axeFound != null) {
break;
}
}
}
reset();
if (axeFound == null) {
stage = Stages.LOOK_FOR_AXE;
public void update() {
if (robot.getItemInUse() == null) {
startDelegateAI(new AIRobotFetchAxe(robot));
} else {
robot.setItemInUse(axeFound);
stage = Stages.LOOK_FOR_WOOD;
startDelegateAI(new AIRobotGoToWood(robot));
}
}
} else if (stage == Stages.LOOK_FOR_WOOD) {
if (woodScanner == null) {
woodScanner = new PathFinding(robot.worldObj, new BlockIndex(robot), new IPathFound() {
@Override
public boolean endReached(IBlockAccess world, int x, int y, int z) {
return world.getBlock(x, y, z) == Blocks.log || world.getBlock(x, y, z) == Blocks.log2;
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotGoToWood) {
startDelegateAI(new AIRobotCutWood(robot, ((AIRobotGoToWood) ai).woodFound));
}
});
} else {
woodScanner.iterate(PathFinding.PATH_ITERATIONS);
if (woodScanner.isDone()) {
LinkedList<BlockIndex> path = woodScanner.getResult();
woodToChop = path.removeLast();
robot.setMainAI(new RobotAIMoveTo(robot, path));
stage = Stages.GO_TO_WOOD;
}
}
} else if (stage == Stages.GO_TO_WOOD) {
if (robot.currentAI.isDone()) {
stage = Stages.CUT_WOOD;
blockDamage = 0;
float a1 = (float) Math.atan2(woodToChop.z - Math.floor(robot.posZ),
woodToChop.x - Math.floor(robot.posX));
float a2 = 0;
if (Math.floor(robot.posY) < woodToChop.y) {
a2 = (float) -Math.PI / 4;
if (Math.floor(robot.posX) == woodToChop.x && Math.floor(robot.posZ) == woodToChop.z) {
a2 -= (float) Math.PI / 4;
}
} else if (Math.floor(robot.posY) > woodToChop.y) {
a2 = (float) Math.PI / 2;
if (Math.floor(robot.posX) == woodToChop.x && Math.floor(robot.posZ) == woodToChop.z) {
a2 += (float) Math.PI / 4;
}
}
robot.setItemAngle(a1, a2);
robot.setItemActive(true);
}
} else if (stage == Stages.CUT_WOOD) {
Block block = robot.worldObj.getBlock(woodToChop.x, woodToChop.y, woodToChop.z);
int meta = robot.worldObj.getBlockMetadata(woodToChop.x, woodToChop.y, woodToChop.z);
float hardness = block.getBlockHardness(robot.worldObj, woodToChop.x, woodToChop.y, woodToChop.z);
float speed = getBreakSpeed(robot, robot.itemInUse, block, meta);
blockDamage += speed / hardness / 30F;
if (blockDamage > 1.0F) {
robot.worldObj.destroyBlockInWorldPartially(robot.getEntityId(), woodToChop.x,
woodToChop.y, woodToChop.z, -1);
blockDamage = 0;
BlockUtil.breakBlock((WorldServer) robot.worldObj, woodToChop.x, woodToChop.y, woodToChop.z, 6000);
robot.worldObj.setBlockToAir(woodToChop.x, woodToChop.y, woodToChop.z);
stage = Stages.LOOK_FOR_WOOD;
robot.setItemActive(false);
robot.itemInUse.getItem().onBlockDestroyed(robot.itemInUse, robot.worldObj, block, woodToChop.x,
woodToChop.y, woodToChop.z, robot);
if (robot.itemInUse.getItemDamage() >= robot.itemInUse.getMaxDamage()) {
robot.setItemInUse(null);
stage = Stages.LOOK_FOR_AXE;
}
reset();
} else {
robot.worldObj.destroyBlockInWorldPartially(robot.getEntityId(), woodToChop.x,
woodToChop.y, woodToChop.z, (int) (blockDamage * 10.0F) - 1);
}
}
}
private void reset() {
axeDocking = null;
woodToChop = null;
woodScanner = null;
}
@Override
public RedstoneBoardRobotNBT getNBTHandler() {
return BoardRobotLumberjackNBT.instance;
}
private float getBreakSpeed(EntityRobot robot, ItemStack usingItem, Block block, int meta) {
ItemStack stack = usingItem;
float f = stack == null ? 1.0F : stack.getItem().getDigSpeed(stack, block, meta);
if (f > 1.0F) {
int i = EnchantmentHelper.getEfficiencyModifier(robot);
ItemStack itemstack = usingItem;
if (i > 0 && itemstack != null) {
float f1 = i * i + 1;
boolean canHarvest = ForgeHooks.canToolHarvestBlock(block, meta, itemstack);
if (!canHarvest && f <= 1.0F) {
f += f1 * 0.08F;
} else {
f += f1;
}
}
}
return f;
}
}

View file

@ -17,11 +17,12 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import buildcraft.api.boards.IRedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.utils.NBTUtils;
import buildcraft.core.utils.StringUtils;
import buildcraft.robots.EntityRobotBase;
public final class BoardRobotLumberjackNBT extends RedstoneBoardRobotNBT {
@ -48,8 +49,8 @@ public final class BoardRobotLumberjackNBT extends RedstoneBoardRobotNBT {
}
@Override
public IRedstoneBoardRobot create(NBTTagCompound nbt) {
return new BoardRobotLumberjack(nbt);
public RedstoneBoardRobot create(NBTTagCompound nbt, EntityRobotBase robot) {
return new BoardRobotLumberjack(robot, nbt);
}
@Override

View file

@ -3,65 +3,46 @@ package buildcraft.core.robots.boards;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.boards.IBoardParameter;
import buildcraft.api.boards.IBoardParameterStack;
import buildcraft.api.boards.IRedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardNBT;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.core.inventory.TransactorSimple;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.core.inventory.filters.IStackFilter;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.robots.RobotAIMoveTo;
import buildcraft.core.robots.RobotAIReturnToDock;
import buildcraft.core.robots.AIRobotGoToDock;
import buildcraft.robots.AIRobot;
import buildcraft.robots.DockingStation;
import buildcraft.robots.EntityRobotBase;
import buildcraft.transport.PipeTransportItems;
import buildcraft.transport.TileGenericPipe;
import buildcraft.transport.TravelingItem;
public class BoardRobotPicker implements IRedstoneBoardRobot<EntityRobot> {
public class BoardRobotPicker extends RedstoneBoardRobot {
private static Set<Integer> targettedItems = new HashSet<Integer>();
public static Set<Integer> targettedItems = new HashSet<Integer>();
private SafeTimeTracker scanTracker = new SafeTimeTracker(40, 10);
private SafeTimeTracker pickTracker = new SafeTimeTracker(20, 0);
private SafeTimeTracker unloadTracker = new SafeTimeTracker(20, 0);
private EntityItem target;
private int pickTime = -1;
private NBTTagCompound data;
private RedstoneBoardNBT board;
private IBoardParameter[] params;
private int range;
private IStackFilter stackFilter;
private boolean initialized = false;
public BoardRobotPicker(NBTTagCompound nbt) {
public BoardRobotPicker(EntityRobotBase robot, NBTTagCompound nbt) {
super(robot);
data = nbt;
board = RedstoneBoardRegistry.instance.getRedstoneBoard(nbt);
params = board.getParameters(nbt);
}
@Override
public void updateBoard(EntityRobot robot) {
TransactorSimple inventoryInsert = new TransactorSimple(robot);
if (robot.worldObj.isRemote) {
return;
}
if (!initialized) {
range = data.getInteger("range");
range = nbt.getInteger("range");
ItemStack[] stacks = new ItemStack[params.length];
@ -75,56 +56,47 @@ public class BoardRobotPicker implements IRedstoneBoardRobot<EntityRobot> {
} else {
stackFilter = null;
}
initialized = true;
}
if (target != null) {
if (target.isDead) {
targettedItems.remove(target.getEntityId());
target = null;
robot.setMainAI(new RobotAIReturnToDock(robot));
scan(robot);
} else if (pickTime == -1) {
if (robot.currentAI.isDone()) {
pickTracker = new SafeTimeTracker(200);
pickTime = 0;
@Override
public void update() {
if (scanTracker.markTimeIfDelay(robot.worldObj)) {
startDelegateAI(new AIRobotFetchItem(robot, range, stackFilter));
}
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotFetchItem) {
if (((AIRobotFetchItem) ai).target != null) {
// if we could get an item, let's try to get another one
startDelegateAI(new AIRobotFetchItem(robot, range, stackFilter));
} else {
pickTime++;
// otherwise, let's return to base
startDelegateAI(new AIRobotGoToDock(robot, robot.getMainDockingStation()));
}
} else if (ai instanceof AIRobotGoToDock) {
emptyContainerInStation();
}
}
if (pickTime > 20) {
target.getEntityItem().stackSize -= inventoryInsert.inject(
target.getEntityItem(), ForgeDirection.UNKNOWN,
true);
private void emptyContainerInStation() {
DockingStation station = robot.getCurrentDockingStation();
if (target.getEntityItem().stackSize <= 0) {
target.setDead();
}
}
}
} else {
if (robot.isDocked) {
TileGenericPipe pipe = (TileGenericPipe) robot.worldObj
.getTileEntity(robot.currentDockingStation.pipe.xCoord, robot.currentDockingStation.pipe.yCoord,
robot.currentDockingStation.pipe.zCoord);
.getTileEntity(station.pipe.xCoord, station.pipe.yCoord, station.pipe.zCoord);
if (pipe != null && pipe.pipe.transport instanceof PipeTransportItems) {
if (unloadTracker.markTimeIfDelay(robot.worldObj)) {
for (int i = 0; i < robot.getSizeInventory(); ++i) {
if (robot.getStackInSlot(i) != null) {
float cx = robot.currentDockingStation.pipe.xCoord + 0.5F + 0.2F
* robot.currentDockingStation.side.offsetX;
float cy = robot.currentDockingStation.pipe.yCoord + 0.5F + 0.2F
* robot.currentDockingStation.side.offsetY;
float cz = robot.currentDockingStation.pipe.zCoord + 0.5F + 0.2F
* robot.currentDockingStation.side.offsetZ;
float cx = station.pipe.xCoord + 0.5F + 0.2F * station.side.offsetX;
float cy = station.pipe.yCoord + 0.5F + 0.2F * station.side.offsetY;
float cz = station.pipe.zCoord + 0.5F + 0.2F * station.side.offsetZ;
TravelingItem item = TravelingItem.make(cx, cy,
cz, robot.getStackInSlot(i));
((PipeTransportItems) pipe.pipe.transport)
.injectItem(item, robot.currentDockingStation.side.getOpposite());
((PipeTransportItems) pipe.pipe.transport).injectItem(item, station.side.getOpposite());
robot.setInventorySlotContents(i, null);
@ -133,49 +105,6 @@ public class BoardRobotPicker implements IRedstoneBoardRobot<EntityRobot> {
}
}
}
}
if (scanTracker.markTimeIfDelay(robot.worldObj)) {
scan(robot);
}
}
}
public void scan(EntityRobot robot) {
TransactorSimple inventoryInsert = new TransactorSimple(robot);
for (Object o : robot.worldObj.loadedEntityList) {
Entity e = (Entity) o;
if (!e.isDead && e instanceof EntityItem && !targettedItems.contains(e.getEntityId())) {
double dx = e.posX - robot.posX;
double dy = e.posY - robot.posY;
double dz = e.posZ - robot.posZ;
double sqrDistance = dx * dx + dy * dy + dz * dz;
double maxDistance = range * range;
if (sqrDistance >= maxDistance) {
continue;
} else if (stackFilter != null && !stackFilter.matches(((EntityItem) e).getEntityItem())) {
continue;
} else {
EntityItem item = (EntityItem) e;
if (inventoryInsert.inject(item.getEntityItem(), ForgeDirection.UNKNOWN, false) > 0) {
target = item;
targettedItems.add(e.getEntityId());
robot.isDocked = false;
robot.setMainAI(new RobotAIMoveTo(robot, (float) e.posX,
(float) e.posY, (float) e.posZ));
pickTime = -1;
break;
}
}
}
}
}
@Override
public RedstoneBoardRobotNBT getNBTHandler() {

View file

@ -18,12 +18,13 @@ import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import buildcraft.api.boards.IBoardParameter;
import buildcraft.api.boards.IRedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.utils.NBTUtils;
import buildcraft.core.utils.StringUtils;
import buildcraft.robots.EntityRobotBase;
public final class BoardRobotPickerNBT extends RedstoneBoardRobotNBT {
@ -56,8 +57,8 @@ public final class BoardRobotPickerNBT extends RedstoneBoardRobotNBT {
}
@Override
public IRedstoneBoardRobot create(NBTTagCompound nbt) {
return new BoardRobotPicker(nbt);
public RedstoneBoardRobot create(NBTTagCompound nbt, EntityRobotBase object) {
return new BoardRobotPicker(object, nbt);
}
@Override

View file

@ -56,7 +56,6 @@ import buildcraft.core.CreativeTabBuildCraft;
import buildcraft.core.ItemRobot;
import buildcraft.core.TileBuffer;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.robots.RobotAIDocked;
import buildcraft.core.utils.MatrixTranformations;
import buildcraft.core.utils.Utils;
import buildcraft.robots.DockingStationRegistry;
@ -797,7 +796,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
robot.setPosition(px, py, pz);
robot.setMainDockingStation(DockingStationRegistry.getStation(x, y, z, rayTraceResult.sideHit));
robot.setMainAI(new RobotAIDocked(robot, robot.mainDockingStation));
robot.setCurrentDockingStation(robot.getMainDockingStation());
world.spawnEntityInWorld(robot);
if (!player.capabilities.isCreativeMode) {