diff --git a/common/buildcraft/core/utils/concurrency/IIterableAlgorithm.java b/common/buildcraft/core/utils/concurrency/IIterableAlgorithm.java new file mode 100644 index 00000000..4bfe6427 --- /dev/null +++ b/common/buildcraft/core/utils/concurrency/IIterableAlgorithm.java @@ -0,0 +1,17 @@ +/** + * 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.utils.concurrency; + +public interface IIterableAlgorithm { + + abstract void iterate(); + + abstract boolean isDone(); + +} \ No newline at end of file diff --git a/common/buildcraft/core/utils/PathFindingJob.java b/common/buildcraft/core/utils/concurrency/IterableAlgorithmRunner.java similarity index 80% rename from common/buildcraft/core/utils/PathFindingJob.java rename to common/buildcraft/core/utils/concurrency/IterableAlgorithmRunner.java index 3febe645..0ca1d528 100755 --- a/common/buildcraft/core/utils/PathFindingJob.java +++ b/common/buildcraft/core/utils/concurrency/IterableAlgorithmRunner.java @@ -6,33 +6,32 @@ * 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.utils; +package buildcraft.core.utils.concurrency; import java.util.Date; -public class PathFindingJob extends Thread { +public class IterableAlgorithmRunner extends Thread { - private PathFinding pathFinding; + private IIterableAlgorithm pathFinding; private boolean stop = false; private int maxIterations; private boolean done = false; - public PathFindingJob(PathFinding iPathFinding, int iMaxIterations) { + public IterableAlgorithmRunner(IIterableAlgorithm iPathFinding, int iMaxIterations) { super("Path Finding"); pathFinding = iPathFinding; maxIterations = iMaxIterations; } - public PathFindingJob(PathFinding iPathFinding) { + public IterableAlgorithmRunner(IIterableAlgorithm iPathFinding) { this(iPathFinding, 1000); } @Override public void run() { try { - pathFinding.preRun(); for (int i = 0; i < maxIterations; ++i) { if (isTerminated() || pathFinding.isDone()) { break; diff --git a/common/buildcraft/core/utils/PathFinding.java b/common/buildcraft/core/utils/concurrency/PathFinding.java similarity index 76% rename from common/buildcraft/core/utils/PathFinding.java rename to common/buildcraft/core/utils/concurrency/PathFinding.java index 4ac5b5e1..427414c7 100755 --- a/common/buildcraft/core/utils/PathFinding.java +++ b/common/buildcraft/core/utils/concurrency/PathFinding.java @@ -6,7 +6,7 @@ * 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.utils; +package buildcraft.core.utils.concurrency; import java.util.ArrayList; import java.util.Collection; @@ -17,26 +17,23 @@ import net.minecraft.world.World; import buildcraft.api.core.BlockIndex; import buildcraft.api.core.BuildCraftAPI; import buildcraft.api.core.IZone; +import buildcraft.core.utils.IBlockFilter; /** * This class implements a 3D path finding based on the A* algorithm, following * guidelines documented on http://www.policyalmanac.org/games/aStarTutorial.htm * . */ -public class PathFinding { +public class PathFinding implements IIterableAlgorithm { public static int PATH_ITERATIONS = 1000; private World world; private BlockIndex start; private BlockIndex end; - private BlockIndex boxEnd; private IBlockFilter pathFound; - private float maxDistance = -1; - private float sqrMaxDistance = -1; private IZone zone; private double maxDistanceToEnd = 0; - private boolean targetNotFound; private HashMap openList = new HashMap(); private HashMap closedList = new HashMap(); @@ -68,58 +65,7 @@ public class PathFinding { maxDistanceToEnd = iMaxDistanceToEnd; } - // TODO: It's probably more efficient to start a search first, and then to - // compute the path, instead of computing all possible path from the get - // go. - public PathFinding(World iWorld, BlockIndex iStart, IBlockFilter iPathFound, float iMaxDistance, IZone iZone) { - world = iWorld; - start = iStart; - pathFound = iPathFound; - - Node startNode = new Node(); - startNode.parent = null; - startNode.movementCost = 0; - startNode.destinationCost = 0; - startNode.totalWeight = startNode.movementCost + startNode.destinationCost; - startNode.index = iStart; - openList.put(start, startNode); - nextIteration = startNode; - maxDistance = iMaxDistance; - sqrMaxDistance = maxDistance * maxDistance; - maxDistance = maxDistance * 1.25f; - zone = iZone; - targetNotFound = false; - } - - public void preRun() { - if (end == null) { - targetNotFound = searchForTarget(64); - } - } - - - private boolean searchForTarget(int range) { - for (int dx = -range; dx <= range; dx++) { - for (int dz = -range; dz <= range; dz++) { - int x = start.x + dx; - int z = start.z + dz; - if (world.getChunkProvider().chunkExists (x >> 4, z >> 4)) { - int height = world.getChunkFromChunkCoords(x >> 4, z >> 4).getHeightValue(x & 0xF, z & 0xF); - for (int dy = -range; dy <= height; dy++) { - int y = Math.max(0, start.y + dy); - if (zone != null && !zone.contains(x, y, z)) { - continue; - } - if (pathFound.matches(world, x, y, z)) { - return false; - } - } - } - } - } - return true; - } - + @Override public void iterate() { iterate(PATH_ITERATIONS); } @@ -145,8 +91,9 @@ public class PathFinding { } } + @Override public boolean isDone() { - return nextIteration == null || (end == null && targetNotFound); + return nextIteration == null; } public LinkedList getResult() { @@ -400,33 +347,7 @@ public class PathFinding { resultMoves[2][2][2] = 0; } - - if (maxDistance != -1) { - for (int dx = -1; dx <= +1; ++dx) { - for (int dy = -1; dy <= +1; ++dy) { - for (int dz = -1; dz <= +1; ++dz) { - int x = from.index.x + dx; - int y = from.index.y + dy; - int z = from.index.z + dz; - - float distX = x - start.x; - float distY = y - start.y; - float distZ = z - start.z; - float sqrDist = distX * distX + distY * distY + distZ * distZ; - - if (sqrDist > sqrMaxDistance) { - resultMoves[dx + 1][dy + 1][dz + 1] = 0; - } - } - } - } - } - return resultMoves; } - private boolean totalDistanceExceeded(Node nextNode) { - return maxDistance != -1 && nextNode.totalWeight > maxDistance; - } - } diff --git a/common/buildcraft/core/utils/concurrency/PathFindingSearch.java b/common/buildcraft/core/utils/concurrency/PathFindingSearch.java new file mode 100644 index 00000000..340d8236 --- /dev/null +++ b/common/buildcraft/core/utils/concurrency/PathFindingSearch.java @@ -0,0 +1,188 @@ +/** + * 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.utils.concurrency; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + +import net.minecraft.world.World; + +import buildcraft.api.core.BlockIndex; +import buildcraft.api.core.BuildCraftAPI; +import buildcraft.api.core.IZone; +import buildcraft.core.utils.IBlockFilter; + +public class PathFindingSearch implements IIterableAlgorithm { + + public static int PATH_ITERATIONS = 1000; + + private static HashMap> reservations = new HashMap>(); + + private World world; + private BlockIndex start; + private List pathFinders; + private IBlockFilter pathFound; + private IZone zone; + + private int searchRadius; + private int searchX; + private int searchY; + private int searchZ; + private int searchHeight; + + public PathFindingSearch(World iWorld, BlockIndex iStart, IBlockFilter iPathFound, float iMaxDistance, IZone iZone) { + world = iWorld; + start = iStart; + pathFound = iPathFound; + + pathFinders = new LinkedList(); + searchRadius = 1; + searchX = -1; + searchY = -1; + searchZ = -1; + getSearchHeight(start.x + searchX, start.z + searchZ); + } + + @Override + public void iterate() { + if (pathFinders.size() < 5 && searchRadius < 64) { + iterateSearch(PATH_ITERATIONS * 50); + } + iteratePathFind(PATH_ITERATIONS); + } + + private void iterateSearch(int itNumber) { + for (int i = 0; i < itNumber; ++i) { + int currX = start.x + searchX; + int currY = start.y + searchY; + int currZ = start.z + searchZ; + if (0 <= currY && currY <= searchHeight) { + if (isTarget(currX, currY, currZ)) { + pathFinders.add(new PathFinding(world, start, new BlockIndex(currX, currY, currZ))); + } + } + + searchY += 1; + if (searchY > searchRadius) { + searchY = -searchRadius; + searchZ += 1; + if (searchZ > searchRadius) { + searchZ = -searchRadius; + searchX += 1; + if (searchX > searchRadius) { + searchRadius += 1; + searchX = -searchRadius; + searchY = -searchRadius; + searchZ = -searchRadius; + } + } + searchHeight = getSearchHeight(start.x + searchX, start.z + searchZ); + } + if (pathFinders.size() >= 5) { + return; + } + } + } + + private boolean isTarget(int x, int y, int z) { + if (zone != null && !zone.contains(x, y, z)) { + return false; + } + if (!pathFound.matches(world, x, y, z)) { + return false; + } + synchronized (reservations) { + if (reservations.containsKey(world.provider.dimensionId)) { + HashSet dimReservations = reservations + .get(world.provider.dimensionId); + if (dimReservations.contains(new BlockIndex(x, y, z))) { + return false; + } + } + } + if (!BuildCraftAPI.isSoftBlock(world, x - 1, y, z) + && !BuildCraftAPI.isSoftBlock(world, x + 1, y, z) + && !BuildCraftAPI.isSoftBlock(world, x, y, z - 1) + && !BuildCraftAPI.isSoftBlock(world, x, y, z + 1) + && !BuildCraftAPI.isSoftBlock(world, x, y - 1, z) + && !BuildCraftAPI.isSoftBlock(world, x, y + 1, z)) { + return false; + } + return true; + } + + private int getSearchHeight(int x, int z) { + if (world.getChunkProvider().chunkExists(x >> 4, z >> 4)) { + return 256; + } else { + return -1; + } + } + + public void iteratePathFind(int itNumber) { + for (PathFinding pathFinding : new ArrayList(pathFinders)) { + pathFinding.iterate(itNumber / pathFinders.size()); + if (pathFinding.isDone()) { + LinkedList path = pathFinding.getResult(); + if (path != null && path.size() > 0) { + if (reserve(path.getLast())) { + return; + } + } + pathFinders.remove(pathFinding); + } + } + } + + @Override + public boolean isDone() { + for (PathFinding pathFinding : pathFinders) { + if (pathFinding.isDone()) { + return true; + } + } + return searchRadius >= 64; + } + + public LinkedList getResult() { + for (PathFinding pathFinding : pathFinders) { + if (pathFinding.isDone()) { + return pathFinding.getResult(); + } + } + return new LinkedList(); + } + + private boolean reserve(BlockIndex block) { + synchronized (reservations) { + if (!reservations.containsKey(world.provider.dimensionId)) { + reservations.put(world.provider.dimensionId, + new HashSet()); + } + HashSet dimReservations = reservations + .get(world.provider.dimensionId); + if (dimReservations.contains(block)) { + return false; + } + dimReservations.add(block); + return true; + } + } + + public void unreserve(BlockIndex block) { + synchronized (reservations) { + if (reservations.containsKey(world.provider.dimensionId)) { + reservations.get(world.provider.dimensionId).remove(block); + } + } + } +} diff --git a/common/buildcraft/robots/EntityRobot.java b/common/buildcraft/robots/EntityRobot.java index b5b48692..426144d9 100644 --- a/common/buildcraft/robots/EntityRobot.java +++ b/common/buildcraft/robots/EntityRobot.java @@ -247,6 +247,7 @@ public class EntityRobot extends EntityRobotBase implements @Override public void onEntityUpdate() { + this.worldObj.theProfiler.startSection("bcEntityRobot"); if (!firstUpdateDone) { firstUpdate(); firstUpdateDone = true; @@ -305,7 +306,9 @@ public class EntityRobot extends EntityRobotBase implements } if (linkedDockingStation != null) { + this.worldObj.theProfiler.startSection("bcRobotAIMainCycle"); mainAI.cycle(); + this.worldObj.theProfiler.endSection(); if (energySpendPerCycle != mainAI.getActiveAI().getEnergyCost()) { energySpendPerCycle = mainAI.getActiveAI().getEnergyCost(); @@ -319,6 +322,7 @@ public class EntityRobot extends EntityRobotBase implements } super.onEntityUpdate(); + this.worldObj.theProfiler.endSection(); } @SideOnly(Side.CLIENT) private void spawnEnergyFX() { diff --git a/common/buildcraft/robots/ai/AIRobotGotoBlock.java b/common/buildcraft/robots/ai/AIRobotGotoBlock.java index 1ec5f66e..cb043a35 100755 --- a/common/buildcraft/robots/ai/AIRobotGotoBlock.java +++ b/common/buildcraft/robots/ai/AIRobotGotoBlock.java @@ -17,15 +17,15 @@ import net.minecraftforge.common.util.Constants; import buildcraft.api.core.BlockIndex; import buildcraft.api.robots.EntityRobotBase; -import buildcraft.core.utils.PathFinding; -import buildcraft.core.utils.PathFindingJob; +import buildcraft.core.utils.concurrency.IterableAlgorithmRunner; +import buildcraft.core.utils.concurrency.PathFinding; public class AIRobotGotoBlock extends AIRobotGoto { public boolean unreachable = false; private PathFinding pathSearch; - private PathFindingJob pathSearchJob; + private IterableAlgorithmRunner pathSearchJob; private LinkedList path; private double prevDistance = Double.MAX_VALUE; private float finalX, finalY, finalZ; @@ -70,7 +70,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)), maxDistance); - pathSearchJob = new PathFindingJob(pathSearch, 100); + pathSearchJob = new IterableAlgorithmRunner(pathSearch, 100); pathSearchJob.start(); } else if (path != null) { double distance = robot.getDistance(nextX, nextY, nextZ); diff --git a/common/buildcraft/robots/ai/AIRobotGotoRandomGroundBlock.java b/common/buildcraft/robots/ai/AIRobotGotoRandomGroundBlock.java index 2b364cac..e8f69530 100755 --- a/common/buildcraft/robots/ai/AIRobotGotoRandomGroundBlock.java +++ b/common/buildcraft/robots/ai/AIRobotGotoRandomGroundBlock.java @@ -15,8 +15,8 @@ import buildcraft.api.core.IZone; import buildcraft.api.robots.AIRobot; import buildcraft.api.robots.EntityRobotBase; import buildcraft.core.utils.IBlockFilter; -import buildcraft.core.utils.PathFinding; -import buildcraft.core.utils.PathFindingJob; +import buildcraft.core.utils.concurrency.IterableAlgorithmRunner; +import buildcraft.core.utils.concurrency.PathFinding; public class AIRobotGotoRandomGroundBlock extends AIRobot { @@ -24,7 +24,7 @@ public class AIRobotGotoRandomGroundBlock extends AIRobot { private int range; private PathFinding pathFinding; - private PathFindingJob pathFindingJob; + private IterableAlgorithmRunner pathFindingJob; private IBlockFilter filter; private IZone zone; @@ -68,7 +68,7 @@ public class AIRobotGotoRandomGroundBlock extends AIRobot { blockFound = aiFind.blockFound; pathFinding = new PathFinding(robot.worldObj, new BlockIndex(robot), blockFound); - pathFindingJob = new PathFindingJob(pathFinding); + pathFindingJob = new IterableAlgorithmRunner(pathFinding); pathFindingJob.start(); } else if (ai instanceof AIRobotGotoBlock) { terminate(); diff --git a/common/buildcraft/robots/ai/AIRobotSearchBlock.java b/common/buildcraft/robots/ai/AIRobotSearchBlock.java index a2b69e5e..054a3d96 100755 --- a/common/buildcraft/robots/ai/AIRobotSearchBlock.java +++ b/common/buildcraft/robots/ai/AIRobotSearchBlock.java @@ -16,17 +16,16 @@ import buildcraft.api.core.BlockIndex; import buildcraft.api.robots.AIRobot; import buildcraft.api.robots.EntityRobotBase; import buildcraft.core.utils.IBlockFilter; -import buildcraft.core.utils.PathFinding; -import buildcraft.core.utils.PathFindingJob; +import buildcraft.core.utils.concurrency.IterableAlgorithmRunner; +import buildcraft.core.utils.concurrency.PathFindingSearch; public class AIRobotSearchBlock extends AIRobot { public BlockIndex blockFound; public LinkedList path; - private PathFinding blockScanner = null; - private PathFindingJob blockScannerJob; + private PathFindingSearch blockScanner = null; + private IterableAlgorithmRunner blockScannerJob; private IBlockFilter pathFound; - private int stopBefore = 0; public AIRobotSearchBlock(EntityRobotBase iRobot) { super(iRobot); @@ -36,13 +35,12 @@ public class AIRobotSearchBlock extends AIRobot { super(iRobot); pathFound = iPathFound; - stopBefore = 0; } @Override public void start() { - blockScanner = new PathFinding(robot.worldObj, new BlockIndex(robot), pathFound, 64, robot.getZoneToWork()); - blockScannerJob = new PathFindingJob(blockScanner); + blockScanner = new PathFindingSearch(robot.worldObj, new BlockIndex(robot), pathFound, 64, robot.getZoneToWork()); + blockScannerJob = new IterableAlgorithmRunner(blockScanner, 40000); blockScannerJob.start(); } @@ -94,4 +92,8 @@ public class AIRobotSearchBlock extends AIRobot { blockFound = new BlockIndex(nbt.getCompoundTag("blockFound")); } } + + public void unreserve() { + blockScanner.unreserve(blockFound); + } } diff --git a/common/buildcraft/robots/boards/BoardRobotFarmer.java b/common/buildcraft/robots/boards/BoardRobotFarmer.java index 1f74889b..1afbbb56 100644 --- a/common/buildcraft/robots/boards/BoardRobotFarmer.java +++ b/common/buildcraft/robots/boards/BoardRobotFarmer.java @@ -20,13 +20,13 @@ import buildcraft.api.core.BuildCraftAPI; import buildcraft.api.robots.AIRobot; import buildcraft.api.robots.EntityRobotBase; import buildcraft.core.inventory.filters.IStackFilter; +import buildcraft.core.utils.IBlockFilter; +import buildcraft.robots.ResourceIdBlock; import buildcraft.robots.ai.AIRobotFetchAndEquipItemStack; import buildcraft.robots.ai.AIRobotGotoBlock; import buildcraft.robots.ai.AIRobotGotoSleep; import buildcraft.robots.ai.AIRobotSearchBlock; import buildcraft.robots.ai.AIRobotUseToolOnBlock; -import buildcraft.core.utils.IBlockFilter; -import buildcraft.robots.ResourceIdBlock; import buildcraft.robots.RobotRegistry; public class BoardRobotFarmer extends RedstoneBoardRobot { @@ -71,6 +71,7 @@ public class BoardRobotFarmer extends RedstoneBoardRobot { if (searchAI.blockFound != null && RobotRegistry.getRegistry(robot.worldObj).take( new ResourceIdBlock(searchAI.blockFound), robot)) { + ((AIRobotSearchBlock) ai).unreserve(); if (blockFound != null) { robot.getRegistry().release(new ResourceIdBlock(blockFound)); @@ -79,11 +80,12 @@ public class BoardRobotFarmer extends RedstoneBoardRobot { blockFound = searchAI.blockFound; startDelegateAI(new AIRobotGotoBlock(robot, searchAI.path)); } else { + if (searchAI.blockFound != null) { + ((AIRobotSearchBlock) ai).unreserve(); + } startDelegateAI(new AIRobotGotoSleep(robot)); } } else if (ai instanceof AIRobotGotoBlock) { - AIRobotGotoBlock gotoBlock = (AIRobotGotoBlock) ai; - startDelegateAI(new AIRobotUseToolOnBlock(robot, blockFound)); } else if (ai instanceof AIRobotFetchAndEquipItemStack) { if (robot.getHeldItem() == null) { diff --git a/common/buildcraft/robots/boards/BoardRobotGenericBreakBlock.java b/common/buildcraft/robots/boards/BoardRobotGenericBreakBlock.java index f403f673..6228c6c5 100644 --- a/common/buildcraft/robots/boards/BoardRobotGenericBreakBlock.java +++ b/common/buildcraft/robots/boards/BoardRobotGenericBreakBlock.java @@ -23,13 +23,13 @@ import buildcraft.api.robots.EntityRobotBase; import buildcraft.api.statements.IStatementParameter; import buildcraft.api.statements.StatementParameterItemStack; import buildcraft.core.inventory.filters.IStackFilter; +import buildcraft.core.utils.IBlockFilter; import buildcraft.robots.ai.AIRobotBreak; import buildcraft.robots.ai.AIRobotFetchAndEquipItemStack; import buildcraft.robots.ai.AIRobotGotoBlock; import buildcraft.robots.ai.AIRobotGotoSleep; import buildcraft.robots.ai.AIRobotSearchBlock; import buildcraft.robots.DockingStation; -import buildcraft.core.utils.IBlockFilter; import buildcraft.robots.ResourceIdBlock; import buildcraft.robots.statements.ActionRobotFilter; import buildcraft.transport.gates.ActionIterator; @@ -104,6 +104,7 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { if (robot.getRegistry().take(new ResourceIdBlock(indexStored), robot)) { startDelegateAI(new AIRobotGotoBlock(robot, ((AIRobotSearchBlock) ai).path)); } + ((AIRobotSearchBlock) ai).unreserve(); } } else if (ai instanceof AIRobotGotoBlock) { startDelegateAI(new AIRobotBreak(robot, indexStored)); diff --git a/common/buildcraft/robots/boards/BoardRobotPlanter.java b/common/buildcraft/robots/boards/BoardRobotPlanter.java index e9d0d393..c7db83a2 100644 --- a/common/buildcraft/robots/boards/BoardRobotPlanter.java +++ b/common/buildcraft/robots/boards/BoardRobotPlanter.java @@ -31,15 +31,14 @@ import buildcraft.core.inventory.filters.ArrayStackFilter; import buildcraft.core.inventory.filters.ArrayStackOrListFilter; import buildcraft.core.inventory.filters.CompositeFilter; import buildcraft.core.inventory.filters.IStackFilter; -import buildcraft.core.inventory.filters.OreStackFilter; import buildcraft.core.utils.IBlockFilter; +import buildcraft.robots.ResourceIdBlock; import buildcraft.robots.ai.AIRobotFetchAndEquipItemStack; import buildcraft.robots.ai.AIRobotGotoBlock; import buildcraft.robots.ai.AIRobotGotoRandomGroundBlock; import buildcraft.robots.ai.AIRobotGotoSleep; import buildcraft.robots.ai.AIRobotSearchBlock; import buildcraft.robots.ai.AIRobotUseToolOnBlock; -import buildcraft.robots.ResourceIdBlock; import buildcraft.robots.statements.ActionRobotFilter; public class BoardRobotPlanter extends RedstoneBoardRobot { @@ -140,10 +139,15 @@ public class BoardRobotPlanter extends RedstoneBoardRobot { robot.getRegistry().release(new ResourceIdBlock(blockFound)); } + ((AIRobotSearchBlock) ai).unreserve(); + blockFound = gotoBlock.blockFound; gotoBlock.path.removeLast(); startDelegateAI(new AIRobotGotoBlock(robot, gotoBlock.path)); } else { + if (gotoBlock.blockFound != null) { + gotoBlock.unreserve(); + } startDelegateAI(new AIRobotGotoSleep(robot)); } } else if (ai instanceof AIRobotGotoBlock) { diff --git a/common/buildcraft/robots/boards/BoardRobotPump.java b/common/buildcraft/robots/boards/BoardRobotPump.java index eabbb2bf..21e7abe3 100644 --- a/common/buildcraft/robots/boards/BoardRobotPump.java +++ b/common/buildcraft/robots/boards/BoardRobotPump.java @@ -28,14 +28,14 @@ import buildcraft.api.robots.AIRobot; import buildcraft.api.robots.EntityRobotBase; import buildcraft.api.statements.IStatementParameter; import buildcraft.api.statements.StatementParameterItemStack; +import buildcraft.core.utils.IBlockFilter; +import buildcraft.robots.DockingStation; +import buildcraft.robots.ResourceIdBlock; import buildcraft.robots.ai.AIRobotGotoBlock; import buildcraft.robots.ai.AIRobotGotoSleep; import buildcraft.robots.ai.AIRobotGotoStationAndUnloadFluids; import buildcraft.robots.ai.AIRobotPumpBlock; import buildcraft.robots.ai.AIRobotSearchBlock; -import buildcraft.robots.DockingStation; -import buildcraft.core.utils.IBlockFilter; -import buildcraft.robots.ResourceIdBlock; import buildcraft.robots.statements.ActionRobotFilter; import buildcraft.transport.gates.ActionIterator; import buildcraft.transport.gates.StatementSlot; @@ -92,6 +92,7 @@ public class BoardRobotPump extends RedstoneBoardRobot { } else { startDelegateAI(new AIRobotGotoBlock(robot, ((AIRobotSearchBlock) ai).path)); } + ((AIRobotSearchBlock) ai).unreserve(); } } else if (ai instanceof AIRobotGotoBlock) { if (!ai.success()) {