diff --git a/src/main/java/baritone/bot/Settings.java b/src/main/java/baritone/bot/Settings.java index f3069051..075218aa 100644 --- a/src/main/java/baritone/bot/Settings.java +++ b/src/main/java/baritone/bot/Settings.java @@ -135,6 +135,15 @@ public class Settings { */ public Setting maxFallHeight = new Setting<>(3); + /** + * If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord + * doesn't matter yet, and replace it with a GoalXZ to the same place before calculating a path. + * Once a segment ends within chunk load range of the GoalBlock, it will go back to normal behavior + * of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away, + * your Y coordinate's accuracy doesn't matter at all until you get much much closer. + */ + public Setting simplifyUnloadedYCoord = new Setting<>(true); + /** * If a movement takes this many ticks more than its initial cost estimate, cancel it */ diff --git a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java index 324028db..54101a16 100644 --- a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java @@ -26,12 +26,15 @@ import baritone.bot.pathing.calc.AStarPathFinder; import baritone.bot.pathing.calc.AbstractNodeCostSearch; import baritone.bot.pathing.calc.IPathFinder; import baritone.bot.pathing.goals.Goal; +import baritone.bot.pathing.goals.GoalBlock; +import baritone.bot.pathing.goals.GoalXZ; import baritone.bot.pathing.path.IPath; import baritone.bot.pathing.path.PathExecutor; import baritone.bot.utils.BlockStateInterface; import baritone.bot.utils.PathRenderer; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.EmptyChunk; import java.awt.*; import java.util.Collections; @@ -258,10 +261,18 @@ public class PathingBehavior extends Behavior { * @return */ private Optional findPath(BlockPos start, Optional previous) { + Goal goal = this.goal; if (goal == null) { displayChatMessageRaw("no goal"); return Optional.empty(); } + if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof GoalBlock) { + BlockPos pos = ((GoalBlock) goal).getGoalPos(); + if (world().getChunk(pos) instanceof EmptyChunk) { + displayChatMessageRaw("Simplifying GoalBlock to GoalXZ due to distance"); + goal = new GoalXZ(pos.getX(), pos.getZ()); + } + } try { IPathFinder pf = new AStarPathFinder(start, goal, previous.map(IPath::positions)); return pf.calculate(); diff --git a/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java b/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java index f9c4a9da..3fdb5fee 100644 --- a/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java +++ b/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java @@ -44,11 +44,11 @@ public class GoalYLevel implements Goal { public double heuristic(BlockPos pos) { if (pos.getY() > level) { // need to descend - return FALL_N_BLOCKS_COST[1] * (pos.getY() - level); + return FALL_N_BLOCKS_COST[2] / 2 * (pos.getY() - level); } if (pos.getY() < level) { // need to ascend - return (level - pos.getY()) * JUMP_ONE_BLOCK_COST; + return (level - pos.getY()) * JUMP_ONE_BLOCK_COST * 0.9; } return 0; }