precompute scaffolding variants to remove branch in dependency graph lookup

This commit is contained in:
Leijurv
2021-08-27 16:13:29 -07:00
parent e5773da108
commit 9fce9ef5e3
5 changed files with 19 additions and 9 deletions

View File

@@ -37,6 +37,14 @@ public final class BlockStateCachedData {
}
}
private static final BlockStateCachedData[] PER_STATE_WITH_SCAFFOLDING = new BlockStateCachedData[PER_STATE.length];
static {
for (int i = 0; i < PER_STATE.length; i++) {
PER_STATE_WITH_SCAFFOLDING[i] = PER_STATE[i] != null && PlaceOrderDependencyGraph.treatAsScaffolding(PER_STATE[i]) ? SCAFFOLDING : PER_STATE[i];
}
}
public final boolean fullyWalkableTop;
private final int collisionHeightBlips;
public final boolean isAir;
@@ -54,6 +62,10 @@ public final class BlockStateCachedData {
return PER_STATE[state];
}
public static BlockStateCachedData getScaffoldingVariant(int state) {
return PER_STATE_WITH_SCAFFOLDING[state];
}
public BlockStateCachedData(BlockStateCachedDataBuilder builder) {
builder.sanityCheck();
this.isAir = builder.isAir();

View File

@@ -47,7 +47,7 @@ public class GreedySolver {
long pos = node.pos;
BlockStateCachedData above = at(BetterBlockPos.offsetBy(pos, 0, 2, 0), worldState);
BlockStateCachedData head = at(Face.UP.offset(pos), worldState);
if (Main.DEBUG && head.collidesWithPlayer) {
if (Main.DEBUG && head.collidesWithPlayer) { // needed because PlayerPhysics doesn't get this
throw new IllegalStateException();
}
BlockStateCachedData feet = at(pos, worldState);

View File

@@ -17,6 +17,7 @@
package baritone.builder;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
import baritone.builder.mc.DebugStates;
import baritone.builder.mc.VanillaBlockStateDataProvider;
@@ -47,6 +48,7 @@ public class Main {
public static final Random RAND = new Random(5021);
public static void main() throws InterruptedException {
System.out.println("Those costs are " + (ActionCosts.FALL_N_BLOCKS_COST[2] / 2) + " and " + ActionCosts.JUMP_ONE_BLOCK_COST + " and " + ActionCosts.FALL_N_BLOCKS_COST[1]);
for (Face face : Face.VALUES) {
System.out.println(face);
System.out.println(face.x);

View File

@@ -57,13 +57,7 @@ public class PlaceOrderDependencyGraph {
}
public BlockStateCachedData data(long pos) {
int state = state(pos);
BlockStateCachedData data = BlockStateCachedData.get(state);
if (treatAsScaffolding(data)) {
return BlockStateCachedData.SCAFFOLDING;
} else {
return data;
}
return BlockStateCachedData.getScaffoldingVariant(state(pos));
}
// example: dirt at 0,0,0 torch at 0,1,0. outgoingEdge(0,0,0,UP) returns true, incomingEdge(0,1,0,DOWN) returns true
@@ -90,6 +84,7 @@ public class PlaceOrderDependencyGraph {
}
public boolean airTreatedAsScaffolding(long pos) {
// alternatively, could be return BlockStateCachedData.getScaffoldingVariant(state(pos)) == BlockStateCachedData.SCAFFOLDING
return treatAsScaffolding(BlockStateCachedData.get(state(pos)));
}
@@ -105,7 +100,7 @@ public class PlaceOrderDependencyGraph {
return states.bounds;
}
private boolean treatAsScaffolding(BlockStateCachedData state) {
public static boolean treatAsScaffolding(BlockStateCachedData state) {
return state.isAir;
}
}

View File

@@ -10,6 +10,7 @@ Current restrictions that the builder will have, at least initially:
* No breaking blocks. If you want to `cleararea` you can just use the old one, it works fine for that specific thing, at least.
* For that reason, the schematic area should be clear. Think of this like a 3d printer going from bottom to top. It takes in a schematic, generates a plan of how to build it, and executes it.
* Because it generates a full plan, if you think about it, this means that your schematic needs to be plannable. Therefore, if your schematic has something unplaceable in it, it won't even begin to do anything. I'll probably add an option to just skip impossible blocks with a warning. But plan for certain things (e.g. lava) to not be possible.
* Ancillary only placed old-baritone-style to assist in movement
This is less dependent on Minecraft code. I'm too annoyed by things like `IBlockState` -> `BlockState` or `player.motionY()` -> `player.getMotion().y` or `== Blocks.AIR` -> `instanceof BlockAir`. For now, I've put everything that imports from Minecraft code into a subpackage called `mc`. I will probably stick with that. Basically I hate having to change all the stupid mapping names and deal with merge conflicts on those. For that reason I plan to use `int` instead of `IBlockState` everywhere, and basically do like `cachedData[state].isAir` instead of `state.getBlock() instanceof BlockAir` (so like `cachedData` would be a `BlockStateCachedData[]` with one entry per valid `IBlockState`). Then, for different versions of the game, all that would need to change is the code to populate array. This should help with checks like can-walk-on and can-place-against.