Refactor the quarry algorithm: it now stores the next few planned blocks, and only searches the direct

column above the target on each target hit. It forces the list to recompute only if it finds a block.

Behaviour is almost identical to before, but should be a lot more efficient in terms of computing resources.
This commit is contained in:
Christian 2012-12-06 08:41:49 -05:00
parent 3b53947381
commit d91305cdb2

View file

@ -9,9 +9,11 @@
package buildcraft.factory;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.network.PacketDispatcher;
@ -241,64 +243,99 @@ public class TileQuarry extends TileMachine implements IMachine, IPowerReceptor,
}
private LinkedList<int[]> visitList = Lists.newLinkedList();
public boolean findTarget(boolean doSet) {
if (worldObj.isRemote)
return false;
boolean[][] blockedColumns = new boolean[bluePrintBuilder.bluePrint.sizeX - 2][bluePrintBuilder.bluePrint.sizeZ - 2];
// for (int searchX = 0; searchX < bluePrintBuilder.bluePrint.sizeX - 2; ++searchX) {
// for (int searchZ = 0; searchZ < bluePrintBuilder.bluePrint.sizeZ - 2; ++searchZ) {
// blockedColumns[searchX][searchZ] = false;
// }
// }
//
for (int searchY = yCoord + 3; searchY >= 0; --searchY) {
int startX, endX, incX;
if (searchY % 2 == 0) {
startX = 0;
endX = bluePrintBuilder.bluePrint.sizeX - 2;
incX = 1;
} else {
startX = bluePrintBuilder.bluePrint.sizeX - 3;
endX = -1;
incX = -1;
}
for (int searchX = startX; searchX != endX; searchX += incX) {
int startZ, endZ, incZ;
if (searchX % 2 == searchY % 2) {
startZ = 0;
endZ = bluePrintBuilder.bluePrint.sizeZ - 2;
incZ = 1;
} else {
startZ = bluePrintBuilder.bluePrint.sizeZ - 3;
endZ = -1;
incZ = -1;
}
for (int searchZ = startZ; searchZ != endZ; searchZ += incZ) {
if (!blockedColumns[searchX][searchZ]) {
int bx = box.xMin + searchX + 1, by = searchY, bz = box.zMin + searchZ + 1;
if (!BlockUtil.canChangeBlock(worldObj, bx, by, bz)) {
blockedColumns[searchX][searchZ] = true;
} else if (!BlockUtil.isSoftBlock(worldObj, bx, by, bz)) {
if (doSet) {
setTarget(bx, by + 1, bz);
}
return true;
}
}
}
}
if (visitList.isEmpty())
{
createColumnVisitList();
}
return false;
if (!doSet)
{
return !visitList.isEmpty();
}
if (visitList.isEmpty()) {
return false;
}
boolean foundTarget = false;
int[] target;
do {
if (visitList.isEmpty()) {
createColumnVisitList();
}
target = visitList.removeFirst();
boolean alternativeTarget = false;
for (int y = target[1]+1; y < yCoord+3; y++) {
if (BlockUtil.canChangeBlock(worldObj, target[0], y, target[2]) && !BlockUtil.isSoftBlock(worldObj, target[0], y, target[2])) {
createColumnVisitList();
alternativeTarget = true;
break;
}
}
foundTarget = !alternativeTarget;
}
while (!foundTarget);
setTarget(target[0],target[1] + 1,target[2]);
return true;
}
/**
* Make the column visit list: called once per layer
*/
private void createColumnVisitList() {
visitList.clear();
boolean[][] blockedColumns = new boolean[bluePrintBuilder.bluePrint.sizeX - 2][bluePrintBuilder.bluePrint.sizeZ - 2];
for (int searchY = yCoord + 3; searchY >= 0; --searchY) {
int startX, endX, incX;
if (searchY % 2 == 0) {
startX = 0;
endX = bluePrintBuilder.bluePrint.sizeX - 2;
incX = 1;
} else {
startX = bluePrintBuilder.bluePrint.sizeX - 3;
endX = -1;
incX = -1;
}
for (int searchX = startX; searchX != endX; searchX += incX) {
int startZ, endZ, incZ;
if (searchX % 2 == searchY % 2) {
startZ = 0;
endZ = bluePrintBuilder.bluePrint.sizeZ - 2;
incZ = 1;
} else {
startZ = bluePrintBuilder.bluePrint.sizeZ - 3;
endZ = -1;
incZ = -1;
}
for (int searchZ = startZ; searchZ != endZ; searchZ += incZ) {
if (!blockedColumns[searchX][searchZ]) {
int bx = box.xMin + searchX + 1, by = searchY, bz = box.zMin + searchZ + 1;
if (!BlockUtil.canChangeBlock(worldObj, bx, by, bz)) {
blockedColumns[searchX][searchZ] = true;
} else if (!BlockUtil.isSoftBlock(worldObj, bx, by, bz)) {
visitList.add(new int[] { bx, by, bz });
}
// Stop at two planes - generally any obstructions will have been found and will force a recompute prior to this
if (visitList.size() > bluePrintBuilder.bluePrint.sizeZ * bluePrintBuilder.bluePrint.sizeX * 2)
return;
}
}
}
}
}
@Override