many fixes to segment calculator, and chat demo usage

This commit is contained in:
Leijurv 2018-11-25 11:53:51 -08:00
parent 93217a3ae3
commit 2b56d68f7d
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
5 changed files with 53 additions and 7 deletions

View File

@ -330,12 +330,16 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} }
} }
public void secretCursedFunctionDoNotCall(IPath path) {
current = new PathExecutor(this, path);
}
/** /**
* See issue #209 * See issue #209
* *
* @return The starting {@link BlockPos} for a new path * @return The starting {@link BlockPos} for a new path
*/ */
public BlockPos pathStart() { // TODO move to a helper or util class public BetterBlockPos pathStart() { // TODO move to a helper or util class
BetterBlockPos feet = ctx.playerFeet(); BetterBlockPos feet = ctx.playerFeet();
if (!MovementHelper.canWalkOn(ctx, feet.down())) { if (!MovementHelper.canWalkOn(ctx, feet.down())) {
if (ctx.player().onGround) { if (ctx.player().onGround) {
@ -406,7 +410,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.get(); failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.get();
} }
CalculationContext context = new CalculationContext(baritone); // not safe to create on the other thread, it looks up a lot of stuff in minecraft CalculationContext context = new CalculationContext(baritone); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context); AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context, true);
if (!Objects.equals(pathfinder.getGoal(), goal)) { if (!Objects.equals(pathfinder.getGoal(), goal)) {
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance"); logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
} }
@ -480,9 +484,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}); });
} }
public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) { public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context, boolean allowSimplifyUnloaded) {
Goal transformed = goal; Goal transformed = goal;
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) { if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos && allowSimplifyUnloaded) {
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos(); BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
if (context.world().getChunk(pos) instanceof EmptyChunk) { if (context.world().getChunk(pos) instanceof EmptyChunk) {
transformed = new GoalXZ(pos.getX(), pos.getZ()); transformed = new GoalXZ(pos.getX(), pos.getZ());

View File

@ -255,6 +255,10 @@ public final class CachedWorld implements ICachedWorld, Helper {
}); });
} }
public void tryLoadFromDisk(int regionX, int regionZ) {
getOrCreateRegion(regionX, regionZ);
}
/** /**
* Returns the region ID based on the region coordinates. 0 will be * Returns the region ID based on the region coordinates. 0 will be
* returned if the specified region coordinates are out of bounds. * returned if the specified region coordinates are out of bounds.

View File

@ -77,6 +77,7 @@ public class SplicedPath extends PathBase {
for (int i = 0; i < first.length() - 1; i++) { // overlap in the very last element is fine (and required) so only go up to first.length() - 1 for (int i = 0; i < first.length() - 1; i++) { // overlap in the very last element is fine (and required) so only go up to first.length() - 1
if (secondPos.contains(first.positions().get(i))) { if (secondPos.contains(first.positions().get(i))) {
firstPositionInSecond = i; firstPositionInSecond = i;
break;
} }
} }
if (firstPositionInSecond != -1) { if (firstPositionInSecond != -1) {
@ -94,7 +95,7 @@ public class SplicedPath extends PathBase {
List<IMovement> movements = new ArrayList<>(); List<IMovement> movements = new ArrayList<>();
positions.addAll(first.positions().subList(0, firstPositionInSecond + 1)); positions.addAll(first.positions().subList(0, firstPositionInSecond + 1));
movements.addAll(first.movements().subList(0, firstPositionInSecond)); movements.addAll(first.movements().subList(0, firstPositionInSecond));
positions.addAll(second.positions().subList(positionInSecond + 1, second.length())); positions.addAll(second.positions().subList(positionInSecond + 1, second.length()));
movements.addAll(second.movements().subList(positionInSecond, second.length() - 1)); movements.addAll(second.movements().subList(positionInSecond, second.length() - 1));
return Optional.of(new SplicedPath(positions, movements, first.getNumNodesConsidered() + second.getNumNodesConsidered(), first.getGoal())); return Optional.of(new SplicedPath(positions, movements, first.getNumNodesConsidered() + second.getNumNodesConsidered(), first.getGoal()));

View File

@ -32,6 +32,7 @@ import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement; import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves; import baritone.pathing.movement.Moves;
import baritone.process.CustomGoalProcess; import baritone.process.CustomGoalProcess;
import baritone.utils.pathing.SegmentedCalculator;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.multiplayer.ChunkProviderClient; import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -202,6 +203,23 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
return true; return true;
} }
if (msg.equals("fullpath")) {
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
} else {
logDirect("Started segmented calculator");
SegmentedCalculator.calculateSegmentsThreaded(pathingBehavior.pathStart(), pathingBehavior.getGoal(), new CalculationContext(baritone), ipath -> {
logDirect("Found a path");
logDirect("Ends at " + ipath.getDest());
logDirect("Length " + ipath.length());
logDirect("Estimated time " + ipath.ticksRemainingFrom(0));
pathingBehavior.secretCursedFunctionDoNotCall(ipath); // it's okay when *I* do it
}, () -> {
logDirect("Path calculation failed, no path");
});
}
return true;
}
if (msg.equals("repack") || msg.equals("rescan")) { if (msg.equals("repack") || msg.equals("rescan")) {
ChunkProviderClient cli = (ChunkProviderClient) ctx.world().getChunkProvider(); ChunkProviderClient cli = (ChunkProviderClient) ctx.world().getChunkProvider();
int playerChunkX = ctx.playerFeet().getX() >> 4; int playerChunkX = ctx.playerFeet().getX() >> 4;

View File

@ -23,9 +23,11 @@ import baritone.api.pathing.goals.Goal;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.PathCalculationResult; import baritone.api.utils.PathCalculationResult;
import baritone.behavior.PathingBehavior; import baritone.behavior.PathingBehavior;
import baritone.cache.CachedWorld;
import baritone.pathing.calc.AbstractNodeCostSearch; import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.CalculationContext;
import baritone.pathing.path.SplicedPath; import baritone.pathing.path.SplicedPath;
import net.minecraft.util.EnumFacing;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -52,8 +54,8 @@ public class SegmentedCalculator {
PathCalculationResult result = segment(soFar); PathCalculationResult result = segment(soFar);
switch (result.getType()) { switch (result.getType()) {
case SUCCESS_SEGMENT: case SUCCESS_SEGMENT:
case SUCCESS_TO_GOAL:
break; break;
case SUCCESS_TO_GOAL: // if we've gotten all the way to the goal, we're done
case FAILURE: // if path calculation failed, we're done case FAILURE: // if path calculation failed, we're done
case EXCEPTION: // if path calculation threw an exception, we're done case EXCEPTION: // if path calculation threw an exception, we're done
return soFar; return soFar;
@ -62,13 +64,30 @@ public class SegmentedCalculator {
} }
IPath segment = result.getPath().get(); // path calculation result type is SUCCESS_SEGMENT, so the path must be present IPath segment = result.getPath().get(); // path calculation result type is SUCCESS_SEGMENT, so the path must be present
IPath combined = soFar.map(previous -> (IPath) SplicedPath.trySplice(previous, segment, true).get()).orElse(segment); IPath combined = soFar.map(previous -> (IPath) SplicedPath.trySplice(previous, segment, true).get()).orElse(segment);
loadAdjacent(combined.getDest().getX(), combined.getDest().getZ());
soFar = Optional.of(combined); soFar = Optional.of(combined);
if (result.getType() == PathCalculationResult.Type.SUCCESS_TO_GOAL) {
return soFar;
}
}
}
private void loadAdjacent(int blockX, int blockZ) {
BetterBlockPos bp = new BetterBlockPos(blockX, 64, blockZ);
CachedWorld cached = (CachedWorld) context.getBaritone().getPlayerContext().worldData().getCachedWorld();
for (int i = 0; i < 4; i++) {
// pathing thread is not allowed to load new cached regions from disk
// it checks if every chunk is loaded before getting blocks from it
// so you see path segments ending at multiples of 512 (plus or minus one) on either x or z axis
// this loads every adjacent chunk to the segment end, so it can continue into the next cached region
BetterBlockPos toLoad = bp.offset(EnumFacing.byHorizontalIndex(i), 16);
cached.tryLoadFromDisk(toLoad.x >> 9, toLoad.z >> 9);
} }
} }
private PathCalculationResult segment(Optional<IPath> previous) { private PathCalculationResult segment(Optional<IPath> previous) {
BetterBlockPos segmentStart = previous.map(IPath::getDest).orElse(start); // <-- e p i c BetterBlockPos segmentStart = previous.map(IPath::getDest).orElse(start); // <-- e p i c
AbstractNodeCostSearch search = PathingBehavior.createPathfinder(segmentStart, goal, previous.orElse(null), context); AbstractNodeCostSearch search = PathingBehavior.createPathfinder(segmentStart, goal, previous.orElse(null), context, false);
return search.calculate(Baritone.settings().primaryTimeoutMS.get(), Baritone.settings().failureTimeoutMS.get()); // use normal time settings, not the plan ahead settings, so as to not overwhelm the computer return search.calculate(Baritone.settings().primaryTimeoutMS.get(), Baritone.settings().failureTimeoutMS.get()); // use normal time settings, not the plan ahead settings, so as to not overwhelm the computer
} }