diff --git a/api/buildcraft/api/robots/EntityRobotBase.java b/api/buildcraft/api/robots/EntityRobotBase.java index 48a59878..54faab86 100755 --- a/api/buildcraft/api/robots/EntityRobotBase.java +++ b/api/buildcraft/api/robots/EntityRobotBase.java @@ -8,6 +8,7 @@ */ package buildcraft.api.robots; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -56,4 +57,8 @@ public abstract class EntityRobotBase extends EntityLiving implements IInventory public abstract boolean containsItems(); + public abstract void unreachableEntityDetected(Entity entity); + + public abstract boolean isKnownUnreachable(Entity entity); + } diff --git a/common/buildcraft/core/robots/AIRobotFetchItem.java b/common/buildcraft/core/robots/AIRobotFetchItem.java index 95260273..a0c603d1 100755 --- a/common/buildcraft/core/robots/AIRobotFetchItem.java +++ b/common/buildcraft/core/robots/AIRobotFetchItem.java @@ -22,6 +22,7 @@ import buildcraft.core.robots.boards.BoardRobotPicker; public class AIRobotFetchItem extends AIRobot { public EntityItem target; + public boolean noItemPicked = false; private float maxRange; private IStackFilter stackFilter; @@ -35,14 +36,64 @@ public class AIRobotFetchItem extends AIRobot { } @Override - public void start() { + public void preempt(AIRobot ai) { + if (target != null && target.isDead) { + noItemPicked = true; + terminate(); + } + } + + @Override + public void update() { + if (target == null) { + scanForItem(); + } else { + pickTime++; + + if (pickTime > 5) { + TransactorSimple inventoryInsert = new TransactorSimple(robot); + + target.getEntityItem().stackSize -= inventoryInsert.inject( + target.getEntityItem(), ForgeDirection.UNKNOWN, + true); + + if (target.getEntityItem().stackSize <= 0) { + target.setDead(); + } + + terminate(); + } + } + } + + @Override + public void delegateAIEnded(AIRobot ai) { + if (ai instanceof AIRobotGotoBlock) { + if (((AIRobotGotoBlock) ai).unreachable) { + robot.unreachableEntityDetected(target); + noItemPicked = true; + terminate(); + } + } + } + + @Override + public void end() { + if (target != null) { + BoardRobotPicker.targettedItems.remove(target.getEntityId()); + } + } + + private void scanForItem() { double previousDistance = Double.MAX_VALUE; 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())) { + if (!e.isDead && e instanceof EntityItem + && !BoardRobotPicker.targettedItems.contains(e.getEntityId()) + && !robot.isKnownUnreachable(e)) { double dx = e.posX - robot.posX; double dy = e.posY - robot.posY; double dz = e.posZ - robot.posZ; @@ -80,45 +131,8 @@ public class AIRobotFetchItem extends AIRobot { } else { // No item was found, terminate this AI + noItemPicked = true; terminate(); } } - - @Override - public void preempt(AIRobot ai) { - if (target.isDead) { - BoardRobotPicker.targettedItems.remove(target.getEntityId()); - terminate(); - } - } - - @Override - public void update() { - if (target.isDead) { - terminate(); - } else { - pickTime++; - - if (pickTime > 5) { - TransactorSimple inventoryInsert = new TransactorSimple(robot); - - target.getEntityItem().stackSize -= inventoryInsert.inject( - target.getEntityItem(), ForgeDirection.UNKNOWN, - true); - - if (target.getEntityItem().stackSize <= 0) { - target.setDead(); - } - - terminate(); - } - } - } - - @Override - public void end() { - if (target != null) { - BoardRobotPicker.targettedItems.remove(target.getEntityId()); - } - } } diff --git a/common/buildcraft/core/robots/AIRobotGotoBlock.java b/common/buildcraft/core/robots/AIRobotGotoBlock.java index d7b144b4..f9a0783a 100755 --- a/common/buildcraft/core/robots/AIRobotGotoBlock.java +++ b/common/buildcraft/core/robots/AIRobotGotoBlock.java @@ -17,6 +17,8 @@ import buildcraft.core.utils.PathFindingJob; public class AIRobotGotoBlock extends AIRobotGoto { + public boolean unreachable = false; + private PathFinding pathSearch; private PathFindingJob pathSearchJob; private LinkedList path; @@ -48,7 +50,7 @@ public class AIRobotGotoBlock extends AIRobotGoto { (int) Math.floor(robot.posY), (int) Math.floor(robot.posZ)), new BlockIndex( (int) Math.floor(finalX), (int) Math.floor(finalY), (int) Math.floor(finalZ))); - pathSearchJob = new PathFindingJob(pathSearch); + pathSearchJob = new PathFindingJob(pathSearch, 100); pathSearchJob.start(); } } @@ -68,11 +70,16 @@ public class AIRobotGotoBlock extends AIRobotGoto { prevDistance = robot.getDistance(nextX, nextY, nextZ); } } else { - if (!pathSearchJob.isAlive()) { - if (pathSearch.isDone()) { - path = pathSearch.getResult(); - setNextInPath(); + if (pathSearchJob.isDone()) { + path = pathSearch.getResult(); + + if (path.size() == 0) { + unreachable = true; + terminate(); + return; } + + setNextInPath(); } } diff --git a/common/buildcraft/core/robots/AIRobotSearchBlock.java b/common/buildcraft/core/robots/AIRobotSearchBlock.java index 6a25b43b..cfd90fc7 100755 --- a/common/buildcraft/core/robots/AIRobotSearchBlock.java +++ b/common/buildcraft/core/robots/AIRobotSearchBlock.java @@ -39,12 +39,10 @@ public class AIRobotSearchBlock extends AIRobot { @Override public void update() { - if (!blockScannerJob.isAlive()) { - if (blockScanner.isDone()) { - LinkedList path = blockScanner.getResult(); - blockFound = path.removeLast(); - startDelegateAI(new AIRobotGotoBlock(robot, path)); - } + if (blockScannerJob.isDone()) { + LinkedList path = blockScanner.getResult(); + blockFound = path.removeLast(); + startDelegateAI(new AIRobotGotoBlock(robot, path)); } } diff --git a/common/buildcraft/core/robots/EntityRobot.java b/common/buildcraft/core/robots/EntityRobot.java index 8d17878c..b893e55c 100755 --- a/common/buildcraft/core/robots/EntityRobot.java +++ b/common/buildcraft/core/robots/EntityRobot.java @@ -9,6 +9,7 @@ package buildcraft.core.robots; import java.util.Date; +import java.util.WeakHashMap; import io.netty.buffer.ByteBuf; @@ -85,6 +86,7 @@ public class EntityRobot extends EntityRobotBase implements private String boardID; private ResourceLocation texture; private DockingStation currentDockingStation; + private WeakHashMap unreachableEntities = new WeakHashMap(); private double mjStored; @@ -681,4 +683,14 @@ public class EntityRobot extends EntityRobotBase implements return false; } + + @Override + public void unreachableEntityDetected(Entity entity) { + unreachableEntities.put(entity, true); + } + + @Override + public boolean isKnownUnreachable(Entity entity) { + return unreachableEntities.containsKey(entity); + } } diff --git a/common/buildcraft/core/robots/boards/BoardRobotPicker.java b/common/buildcraft/core/robots/boards/BoardRobotPicker.java index 5c521732..9bbf6957 100755 --- a/common/buildcraft/core/robots/boards/BoardRobotPicker.java +++ b/common/buildcraft/core/robots/boards/BoardRobotPicker.java @@ -25,6 +25,7 @@ import buildcraft.api.robots.EntityRobotBase; import buildcraft.core.inventory.filters.ArrayStackFilter; import buildcraft.core.inventory.filters.IStackFilter; import buildcraft.core.robots.AIRobotFetchItem; +import buildcraft.core.robots.AIRobotGotoDock; import buildcraft.core.robots.AIRobotGotoSleep; import buildcraft.core.robots.AIRobotGotoStationToUnload; import buildcraft.core.robots.AIRobotSleep; @@ -73,7 +74,9 @@ public class BoardRobotPicker extends RedstoneBoardRobot { @Override public void delegateAIEnded(AIRobot ai) { if (ai instanceof AIRobotFetchItem) { - if (((AIRobotFetchItem) ai).target != null) { + if (((AIRobotFetchItem) ai).noItemPicked) { + startDelegateAI(new AIRobotGotoDock(robot, (DockingStation) robot.getLinkedStation())); + } 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 { diff --git a/common/buildcraft/core/utils/PathFindingJob.java b/common/buildcraft/core/utils/PathFindingJob.java index 8946c20c..a72065f3 100755 --- a/common/buildcraft/core/utils/PathFindingJob.java +++ b/common/buildcraft/core/utils/PathFindingJob.java @@ -8,25 +8,47 @@ */ package buildcraft.core.utils; +import java.util.Date; + public class PathFindingJob extends Thread { private PathFinding pathFinding; private boolean stop = false; + private int maxIterations; - public PathFindingJob(PathFinding iPathFinding) { + private boolean done = false; + + public PathFindingJob(PathFinding iPathFinding, int iMaxIterations) { super("Path Finding"); pathFinding = iPathFinding; + maxIterations = iMaxIterations; + } + + public PathFindingJob(PathFinding iPathFinding) { + this(iPathFinding, 1000); } @Override public void run() { try { - while (!isTerminated() && !pathFinding.isDone()) { + for (int i = 0; i < maxIterations; ++i) { + if (isTerminated() || pathFinding.isDone()) { + break; + } + + long startTime = new Date().getTime(); + long elapsedtime = 0; + pathFinding.iterate(); + + elapsedtime = new Date().getTime() - startTime; + sleep(elapsedtime); } } catch (Throwable t) { t.printStackTrace(); + } finally { + done = true; } } @@ -38,4 +60,8 @@ public class PathFindingJob extends Thread { return stop; } + public synchronized boolean isDone() { + return done; + } + }