From 16e3fd93051484aa0ac1c2eff46ca1638d31a326 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 18 Nov 2018 21:41:42 -0800 Subject: [PATCH 01/31] IPathingControlManager --- .../pathing/calc/IPathingControlManager.java | 31 +++++++++++++++++++ .../baritone/utils/PathingControlManager.java | 24 +++++++++----- 2 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/api/java/baritone/api/pathing/calc/IPathingControlManager.java diff --git a/src/api/java/baritone/api/pathing/calc/IPathingControlManager.java b/src/api/java/baritone/api/pathing/calc/IPathingControlManager.java new file mode 100644 index 000000000..ffaa18b84 --- /dev/null +++ b/src/api/java/baritone/api/pathing/calc/IPathingControlManager.java @@ -0,0 +1,31 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.pathing.calc; + +import baritone.api.process.IBaritoneProcess; +import baritone.api.process.PathingCommand; + +import java.util.Optional; + +public interface IPathingControlManager { + void registerProcess(IBaritoneProcess process); + + Optional mostRecentInControl(); + + Optional mostRecentCommand(); +} diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java index fa58a0694..f5fff5460 100644 --- a/src/main/java/baritone/utils/PathingControlManager.java +++ b/src/main/java/baritone/utils/PathingControlManager.java @@ -20,6 +20,7 @@ package baritone.utils; import baritone.Baritone; import baritone.api.event.events.TickEvent; import baritone.api.event.listener.AbstractGameEventListener; +import baritone.api.pathing.calc.IPathingControlManager; import baritone.api.pathing.goals.Goal; import baritone.api.process.IBaritoneProcess; import baritone.api.process.PathingCommand; @@ -27,13 +28,10 @@ import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; import net.minecraft.util.math.BlockPos; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; -public class PathingControlManager { +public class PathingControlManager implements IPathingControlManager { private final Baritone baritone; private final HashSet processes; // unGh private IBaritoneProcess inControlLastTick; @@ -54,12 +52,16 @@ public class PathingControlManager { }); } + @Override public void registerProcess(IBaritoneProcess process) { process.onLostControl(); // make sure it's reset processes.add(process); } - public void cancelEverything() { + public void cancelEverything() { // called by PathingBehavior on TickEvent Type OUT + inControlLastTick = null; + inControlThisTick = null; + command = null; for (IBaritoneProcess proc : processes) { proc.onLostControl(); if (proc.isActive() && !proc.isTemporary()) { // it's okay for a temporary thing (like combat pause) to maintain control even if you say to cancel @@ -69,8 +71,14 @@ public class PathingControlManager { } } - public IBaritoneProcess inControlThisTick() { - return inControlThisTick; + @Override + public Optional mostRecentInControl() { + return Optional.ofNullable(inControlThisTick); + } + + @Override + public Optional mostRecentCommand() { + return Optional.ofNullable(command); } public void preTick() { From d95a72f2cc3a525bccf6eb5e3c7ff669e8f86feb Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 19 Nov 2018 17:14:54 -0800 Subject: [PATCH 02/31] correct wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e458484a9..9fa8a2c96 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd # FAQ -## Can I use Baritone as a library in my hacked client? +## Can I use Baritone as a library in my custom utility client? Sure! (As long as usage is in compliance with the LGPL 3 License) From e5184efdaa3b5b6d102765d1cba225bf6f91a3d9 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 20 Nov 2018 08:00:11 -0800 Subject: [PATCH 03/31] fix cached path loop --- src/main/java/baritone/cache/ChunkPacker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/cache/ChunkPacker.java b/src/main/java/baritone/cache/ChunkPacker.java index 44153fdcd..0627ebb4c 100644 --- a/src/main/java/baritone/cache/ChunkPacker.java +++ b/src/main/java/baritone/cache/ChunkPacker.java @@ -124,7 +124,7 @@ public final class ChunkPacker { private static PathingBlockType getPathingBlockType(IBlockState state) { Block block = state.getBlock(); - if (block.equals(Blocks.WATER)) { + if (block.equals(Blocks.WATER) && !MovementHelper.isFlowing(state)) { // only water source blocks are plausibly usable, flowing water should be avoid return PathingBlockType.WATER; } From 14650f93c5af19148bf41e962c50b8d27b646f7f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 20 Nov 2018 08:19:27 -0800 Subject: [PATCH 04/31] walk into lava less --- .../movement/movements/MovementDescend.java | 29 +++++++++++++++++++ .../baritone/pathing/path/PathExecutor.java | 14 +++------ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index 05c140e4f..ea7177b49 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -21,17 +21,22 @@ import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.pathing.movement.MovementStatus; import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.Rotation; +import baritone.api.utils.RotationUtils; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; +import baritone.utils.BlockStateInterface; import baritone.utils.pathing.MutableMoveResult; import net.minecraft.block.Block; import net.minecraft.block.BlockFalling; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; public class MovementDescend extends Movement { @@ -190,6 +195,18 @@ public class MovementDescend extends Movement { // System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY())); }*/ } + if (safeMode()) { + double destX = (src.getX() + 0.5) * 0.25 + (dest.getX() + 0.5) * 0.75; + double destZ = (src.getZ() + 0.5) * 0.25 + (dest.getZ() + 0.5) * 0.75; + EntityPlayerSP player = ctx.player(); + state.setTarget(new MovementState.MovementTarget( + new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F), + new Vec3d(destX, dest.getY(), destZ), + new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch), + false + )).setInput(Input.MOVE_FORWARD, true); + return state; + } double diffX = ctx.player().posX - (dest.getX() + 0.5); double diffZ = ctx.player().posZ - (dest.getZ() + 0.5); double ab = Math.sqrt(diffX * diffX + diffZ * diffZ); @@ -210,4 +227,16 @@ public class MovementDescend extends Movement { } return state; } + + public boolean safeMode() { + // (dest - src) + dest is offset 1 more in the same direction + // so it's the block we'd need to worry about running into if we decide to sprint straight through this descend + BlockPos into = dest.subtract(src.down()).add(dest); + for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks + if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(ctx, into.up(y)))) { + return true; + } + } + return false; + } } diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index 5dfc420d1..af0fe142e 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -378,16 +378,10 @@ public class PathExecutor implements IPathExecutor, Helper { IMovement current = path.movements().get(pathPosition); if (current instanceof MovementDescend && pathPosition < path.length() - 2) { - // (dest - src) + dest is offset 1 more in the same direction - // so it's the block we'd need to worry about running into if we decide to sprint straight through this descend - - BlockPos into = current.getDest().subtract(current.getSrc().down()).add(current.getDest()); - for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks - if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(ctx, into.up(y)))) { - logDebug("Sprinting would be unsafe"); - ctx.player().setSprinting(false); - return; - } + if (((MovementDescend) current).safeMode()) { + logDebug("Sprinting would be unsafe"); + ctx.player().setSprinting(false); + return; } IMovement next = path.movements().get(pathPosition + 1); From 033da7e73770842cffdffbb7639bdcff64ae11c8 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 20 Nov 2018 13:22:33 -0800 Subject: [PATCH 05/31] fix coefficient --- .../baritone/pathing/movement/movements/MovementDescend.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index ea7177b49..d868c5fc1 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -196,8 +196,8 @@ public class MovementDescend extends Movement { }*/ } if (safeMode()) { - double destX = (src.getX() + 0.5) * 0.25 + (dest.getX() + 0.5) * 0.75; - double destZ = (src.getZ() + 0.5) * 0.25 + (dest.getZ() + 0.5) * 0.75; + double destX = (src.getX() + 0.5) * 0.19 + (dest.getX() + 0.5) * 0.81; + double destZ = (src.getZ() + 0.5) * 0.19 + (dest.getZ() + 0.5) * 0.81; EntityPlayerSP player = ctx.player(); state.setTarget(new MovementState.MovementTarget( new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F), From 3bb16de67e3fef08aed510a6c03beabba1a2130d Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 20 Nov 2018 16:32:44 -0800 Subject: [PATCH 06/31] greatly increase mining visual scan range --- src/main/java/baritone/process/MineProcess.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 204e11c57..a0495adef 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -205,7 +205,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro /*public static List searchWorld(List mining, int max, World world) { }*/ - public static List searchWorld(IPlayerContext ctx, List mining, int max, List alreadyKnown) { + public static List searchWorld(IPlayerContext ctx, List mining, int max, List alreadyKnown) { List locs = new ArrayList<>(); List uninteresting = new ArrayList<>(); //long b = System.currentTimeMillis(); @@ -232,15 +232,16 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro public void addNearby() { knownOreLocations.addAll(droppedItemsScan(mining, ctx.world())); BlockPos playerFeet = ctx.playerFeet(); - int searchDist = 4; // why four? idk + BlockStateInterface bsi = new BlockStateInterface(ctx); + int searchDist = 10; + double fakedBlockReachDistance = 20; // at least 10 * sqrt(3) with some extra space to account for positioning within the block for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) { for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) { for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) { - BlockPos pos = new BlockPos(x, y, z); // crucial to only add blocks we can see because otherwise this // is an x-ray and it'll get caught - if (mining.contains(BlockStateInterface.getBlock(ctx, pos)) && RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()).isPresent()) { - knownOreLocations.add(pos); + if (mining.contains(bsi.get0(x, y, z).getBlock()) && RotationUtils.reachable(ctx.player(), new BlockPos(x, y, z), fakedBlockReachDistance).isPresent()) { + knownOreLocations.add(new BlockPos(x, y, z)); } } } From fb971301a423187259086b5bb26ad55422be5e49 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 20 Nov 2018 16:32:55 -0800 Subject: [PATCH 07/31] fix getting permanently stuck on sideways fence gates in our way --- src/main/java/baritone/pathing/movement/MovementHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 15d790409..72177669c 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -200,7 +200,7 @@ public interface MovementHelper extends ActionCosts, Helper { return true; } - return isHorizontalBlockPassable(gatePos, state, playerPos, BlockFenceGate.OPEN); + return state.getValue(BlockFenceGate.OPEN); } static boolean isHorizontalBlockPassable(BlockPos blockPos, IBlockState blockState, BlockPos playerPos, PropertyBool propertyOpen) { From 2a674cb869b3bb47f3d08132c9c186a2ee573866 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 20 Nov 2018 18:58:41 -0800 Subject: [PATCH 08/31] don't sprint straight into danger --- .../pathing/movement/movements/MovementTraverse.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index 2dc0e0cfd..aa25b5b64 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java @@ -226,7 +226,10 @@ public class MovementTraverse extends Movement { if (ctx.playerFeet().equals(dest)) { return state.setStatus(MovementStatus.SUCCESS); } - if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(ctx, ctx.playerFeet())) { + BlockPos into = dest.subtract(src).add(dest); + Block intoBelow = BlockStateInterface.get(ctx, into).getBlock(); + Block intoAbove = BlockStateInterface.get(ctx, into.up()).getBlock(); + if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(ctx, ctx.playerFeet()) && !MovementHelper.avoidWalkingInto(intoBelow) && !MovementHelper.avoidWalkingInto(intoAbove)) { state.setInput(Input.SPRINT, true); } Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock(); From cfa874982c855865475fab3e984b2e4caccf5519 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Wed, 21 Nov 2018 11:00:46 -0800 Subject: [PATCH 09/31] fix a bunch of stuff in pillar, fixes #266 --- .../baritone/pathing/movement/movements/MovementPillar.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index 9c2c58e14..2898c4267 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -194,12 +194,13 @@ public class MovementPillar extends Movement { } - state.setInput(Input.SNEAK, ctx.player().posY > dest.getY()); // delay placement by 1 tick for ncp compatibility + state.setInput(Input.SNEAK, ctx.player().posY > dest.getY() || ctx.player().posY < src.getY() + 0.5D); // delay placement by 1 tick for ncp compatibility // since (lower down) we only right click once player.isSneaking, and that happens the tick after we request to sneak double diffX = ctx.player().posX - (dest.getX() + 0.5); double diffZ = ctx.player().posZ - (dest.getZ() + 0.5); double dist = Math.sqrt(diffX * diffX + diffZ * diffZ); + double flatMotion = Math.sqrt(ctx.player().motionX * ctx.player().motionX + ctx.player().motionZ * ctx.player().motionZ); if (dist > 0.17) {//why 0.17? because it seemed like a good number, that's why //[explanation added after baritone port lol] also because it needs to be less than 0.2 because of the 0.3 sneak limit //and 0.17 is reasonably less than 0.2 @@ -209,7 +210,7 @@ public class MovementPillar extends Movement { // revise our target to both yaw and pitch if we're going to be moving forward state.setTarget(new MovementState.MovementTarget(rotation, true)); - } else { + } else if (flatMotion < 0.05) { // If our Y coordinate is above our goal, stop jumping state.setInput(Input.JUMP, ctx.player().posY < dest.getY()); } From 8db26af36cfb09dd577c7081aefc13d911a0802d Mon Sep 17 00:00:00 2001 From: Leijurv Date: Wed, 21 Nov 2018 11:02:12 -0800 Subject: [PATCH 10/31] tweak sneak range for ncp compatibility --- .../baritone/pathing/movement/movements/MovementPillar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index 2898c4267..78a626286 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -194,7 +194,7 @@ public class MovementPillar extends Movement { } - state.setInput(Input.SNEAK, ctx.player().posY > dest.getY() || ctx.player().posY < src.getY() + 0.5D); // delay placement by 1 tick for ncp compatibility + state.setInput(Input.SNEAK, ctx.player().posY > dest.getY() || ctx.player().posY < src.getY() + 0.2D); // delay placement by 1 tick for ncp compatibility // since (lower down) we only right click once player.isSneaking, and that happens the tick after we request to sneak double diffX = ctx.player().posX - (dest.getX() + 0.5); From aed8dae175f298cfd588ee226494c9cf6912800c Mon Sep 17 00:00:00 2001 From: Leijurv Date: Wed, 21 Nov 2018 17:03:24 -0800 Subject: [PATCH 11/31] hehe --- .../java/baritone/api/event/events/ChunkEvent.java | 11 ++++++++++- .../launch/mixins/MixinNetHandlerPlayClient.java | 5 +++-- src/main/java/baritone/event/GameEventHandler.java | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/event/events/ChunkEvent.java b/src/api/java/baritone/api/event/events/ChunkEvent.java index 1541b1f1f..a74bed17b 100644 --- a/src/api/java/baritone/api/event/events/ChunkEvent.java +++ b/src/api/java/baritone/api/event/events/ChunkEvent.java @@ -94,7 +94,16 @@ public final class ChunkEvent { /** * When the chunk is being populated with blocks, tile entities, etc. + *

+ * And it's a full chunk */ - POPULATE + POPULATE_FULL, + + /** + * When the chunk is being populated with blocks, tile entities, etc. + *

+ * And it's a partial chunk + */ + POPULATE_PARTIAL } } diff --git a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java index 9fc1bd6f7..a716cb878 100644 --- a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java +++ b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java @@ -44,12 +44,13 @@ public class MixinNetHandlerPlayClient { ) ) private void preRead(SPacketChunkData packetIn, CallbackInfo ci) { + packetIn.isFullChunk(); for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) { ibaritone.getGameEventHandler().onChunkEvent( new ChunkEvent( EventState.PRE, - ChunkEvent.Type.POPULATE, + packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL, packetIn.getChunkX(), packetIn.getChunkZ() ) @@ -68,7 +69,7 @@ public class MixinNetHandlerPlayClient { ibaritone.getGameEventHandler().onChunkEvent( new ChunkEvent( EventState.POST, - ChunkEvent.Type.POPULATE, + packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL, packetIn.getChunkX(), packetIn.getChunkZ() ) diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index 7ac046436..9f16283e9 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -70,7 +70,7 @@ public final class GameEventHandler implements IEventBus, Helper { ChunkEvent.Type type = event.getType(); boolean isPostPopulate = state == EventState.POST - && type == ChunkEvent.Type.POPULATE; + && (type == ChunkEvent.Type.POPULATE_FULL || type == ChunkEvent.Type.POPULATE_PARTIAL); World world = baritone.getPlayerContext().world(); From 4b8c85f8a630db97bc23c503fbbb38c6526bd407 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 22 Nov 2018 08:57:27 -0800 Subject: [PATCH 12/31] whoops --- .../java/baritone/launch/mixins/MixinNetHandlerPlayClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java index a716cb878..e2cc98427 100644 --- a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java +++ b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java @@ -44,7 +44,6 @@ public class MixinNetHandlerPlayClient { ) ) private void preRead(SPacketChunkData packetIn, CallbackInfo ci) { - packetIn.isFullChunk(); for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) { ibaritone.getGameEventHandler().onChunkEvent( From 1e9786d5b923bffd8f02ef1964a6672540183aed Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 22 Nov 2018 09:39:54 -0800 Subject: [PATCH 13/31] add a secondary failure cutoff --- src/api/java/baritone/api/Settings.java | 18 ++++++++++++---- .../api/pathing/calc/IPathFinder.java | 2 +- .../baritone/behavior/PathingBehavior.java | 16 +++++++++----- .../pathing/calc/AStarPathFinder.java | 21 ++++++++++++++----- .../pathing/calc/AbstractNodeCostSearch.java | 16 ++++++-------- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 7fce02540..f4fd7db14 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -247,14 +247,24 @@ public class Settings { public Setting movementTimeoutTicks = new Setting<>(100); /** - * Pathing can never take longer than this + * Pathing ends after this amount of time, if a path has been found */ - public Setting pathTimeoutMS = new Setting<>(2000L); + public Setting primaryTimeoutMS = new Setting<>(500L); /** - * Planning ahead while executing a segment can never take longer than this + * Pathing can never take longer than this, even if that means failing to find any path at all */ - public Setting planAheadTimeoutMS = new Setting<>(4000L); + public Setting failureTimeoutMS = new Setting<>(2000L); + + /** + * Planning ahead while executing a segment ends after this amount of time, if a path has been found + */ + public Setting planAheadPrimaryTimeoutMS = new Setting<>(4000L); + + /** + * Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all + */ + public Setting planAheadFailureTimeoutMS = new Setting<>(5000L); /** * For debugging, consider nodes much much slower diff --git a/src/api/java/baritone/api/pathing/calc/IPathFinder.java b/src/api/java/baritone/api/pathing/calc/IPathFinder.java index f70196a69..fa83295f7 100644 --- a/src/api/java/baritone/api/pathing/calc/IPathFinder.java +++ b/src/api/java/baritone/api/pathing/calc/IPathFinder.java @@ -36,7 +36,7 @@ public interface IPathFinder { * * @return The final path */ - PathCalculationResult calculate(long timeout); + PathCalculationResult calculate(long primaryTimeout, long failureTimeout); /** * Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 1943b215e..f2017eefc 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -40,7 +40,10 @@ import baritone.utils.PathRenderer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.EmptyChunk; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Optional; import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; @@ -396,11 +399,14 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller return; } - long timeout; + long primaryTimeout; + long failureTimeout; if (current == null) { - timeout = Baritone.settings().pathTimeoutMS.get(); + primaryTimeout = Baritone.settings().primaryTimeoutMS.get(); + failureTimeout = Baritone.settings().failureTimeoutMS.get(); } else { - timeout = Baritone.settings().planAheadTimeoutMS.get(); + primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.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 AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context); @@ -410,7 +416,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, logDebug("Starting to search for path from " + start + " to " + goal); } - PathCalculationResult calcResult = pathfinder.calculate(timeout); + PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout); Optional path = calcResult.getPath(); if (Baritone.settings().cutoffAtLoadBoundary.get()) { path = path.map(p -> { diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index f65920945..aa83bc442 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -49,7 +49,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel } @Override - protected Optional calculate0(long timeout) { + protected Optional calculate0(long primaryTimeout, long failureTimeout) { startNode = getNodeAtPosition(startX, startY, startZ, BetterBlockPos.longHash(startX, startY, startZ)); startNode.cost = 0; startNode.combinedCost = startNode.estimatedCostToGoal; @@ -68,10 +68,11 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel long startTime = System.nanoTime() / 1000000L; boolean slowPath = Baritone.settings().slowPath.get(); if (slowPath) { - logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.get() + "ms instead of " + timeout + "ms"); + logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.get() + "ms instead of " + primaryTimeout + "ms"); } - long timeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : timeout); - //long lastPrintout = 0; + long primaryTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : primaryTimeout); + long failureTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : failureTimeout); + boolean failing = true; int numNodes = 0; int numMovementsConsidered = 0; int numEmptyChunk = 0; @@ -79,7 +80,14 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get(); boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get(); - while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && System.nanoTime() / 1000000L - timeoutTime < 0 && !cancelRequested) { + while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) { + long now = System.nanoTime() / 1000000L; + if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) { + break; + } + if (failing == bestPathSoFar().isPresent()) { + throw new IllegalStateException(); + } if (slowPath) { try { Thread.sleep(Baritone.settings().slowPathTimeDelayMS.get()); @@ -166,6 +174,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel } bestHeuristicSoFar[i] = heuristic; bestSoFar[i] = neighbor; + if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) { + failing = false; + } } } } diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index ac4efa4d2..6d9ad67ed 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -83,13 +83,14 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { cancelRequested = true; } - public synchronized PathCalculationResult calculate(long timeout) { + @Override + public synchronized PathCalculationResult calculate(long primaryTimeout, long failureTimeout) { if (isFinished) { throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!"); } this.cancelRequested = false; try { - IPath path = calculate0(timeout).map(IPath::postProcess).orElse(null); + IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null); isFinished = true; if (cancelRequested) { return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path); @@ -112,7 +113,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { } } - protected abstract Optional calculate0(long timeout); + protected abstract Optional calculate0(long primaryTimeout, long failureTimeout); /** * Determines the distance squared from the specified node to the start @@ -157,7 +158,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { @Override public Optional bestPathSoFar() { - if (startNode == null || bestSoFar == null || bestSoFar[0] == null) { + if (startNode == null || bestSoFar == null) { return Optional.empty(); } for (int i = 0; i < bestSoFar.length; i++) { @@ -165,12 +166,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { continue; } if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared - try { - return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context)); - } catch (IllegalStateException ex) { - System.out.println("Unable to construct path to render"); - return Optional.empty(); - } + return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context)); } } // instead of returning bestSoFar[0], be less misleading From 7c51106d27c120db1f419a2a3437c3b89f412ac2 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 22 Nov 2018 10:08:55 -0800 Subject: [PATCH 14/31] unneeded --- src/main/java/baritone/pathing/calc/AStarPathFinder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index aa83bc442..d00619211 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -85,9 +85,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) { break; } - if (failing == bestPathSoFar().isPresent()) { - throw new IllegalStateException(); - } if (slowPath) { try { Thread.sleep(Baritone.settings().slowPathTimeDelayMS.get()); From b5a4e65fbf9cd05a54624cb7e46662a52808c92c Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 07:47:28 -0800 Subject: [PATCH 15/31] unable to start a parkour jump from stairs --- src/main/java/baritone/pathing/movement/MovementHelper.java | 2 +- .../baritone/pathing/movement/movements/MovementParkour.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 72177669c..ff73b0f29 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -274,7 +274,7 @@ public interface MovementHelper extends ActionCosts, Helper { // if assumeWalkOnWater is off, we can only walk on water if there is water above it return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get(); } - if (block instanceof BlockGlass || block instanceof BlockStainedGlass) { + if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) { return true; } if (block instanceof BlockSlab) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index 44334569c..9010251d8 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -33,6 +33,7 @@ import baritone.utils.BlockStateInterface; import baritone.utils.Helper; import baritone.utils.pathing.MutableMoveResult; import net.minecraft.block.Block; +import net.minecraft.block.BlockStairs; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; @@ -68,7 +69,7 @@ public class MovementParkour extends Movement { return; } IBlockState standingOn = context.get(x, y - 1, z); - if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || MovementHelper.isBottomSlab(standingOn)) { + if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn)) { return; } int xDiff = dir.getXOffset(); From 0d7131413aaad269ca6dec5348f02e5df0bb3827 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 07:55:59 -0800 Subject: [PATCH 16/31] prevent double jumping --- .../baritone/pathing/movement/movements/MovementAscend.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java index 9c33742e4..0baef8819 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java @@ -211,6 +211,10 @@ public class MovementAscend extends Movement { return state; } + if (ctx.playerFeet().equals(src.up())) { + return state; // no need to hit space if we're already jumping + } + if (headBonkClear()) { return state.setInput(Input.JUMP, true); } From 70f8d1d4aeac648581b8afd8486bb30d8e875bd9 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 09:00:52 -0800 Subject: [PATCH 17/31] fix bsi creation on wrong thread, cache chunks, fixes #210 --- .../mixins/MixinChunkProviderClient.java | 39 +++++++ src/launch/resources/mixins.baritone.json | 1 + src/main/java/baritone/pathing/calc/Path.java | 2 +- .../java/baritone/pathing/movement/Moves.java | 107 +++++++++--------- .../movement/movements/MovementParkour.java | 6 +- .../baritone/process/GetToBlockProcess.java | 12 +- .../java/baritone/process/MineProcess.java | 38 ++++--- .../baritone/utils/BlockStateInterface.java | 19 ++++ .../utils/ExampleBaritoneControl.java | 3 +- .../utils/accessor/IChunkProviderClient.java | 25 ++++ 10 files changed, 172 insertions(+), 80 deletions(-) create mode 100644 src/launch/java/baritone/launch/mixins/MixinChunkProviderClient.java create mode 100644 src/main/java/baritone/utils/accessor/IChunkProviderClient.java diff --git a/src/launch/java/baritone/launch/mixins/MixinChunkProviderClient.java b/src/launch/java/baritone/launch/mixins/MixinChunkProviderClient.java new file mode 100644 index 000000000..b4cada6ef --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinChunkProviderClient.java @@ -0,0 +1,39 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.launch.mixins; + +import baritone.utils.accessor.IChunkProviderClient; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.minecraft.client.multiplayer.ChunkProviderClient; +import net.minecraft.world.chunk.Chunk; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ChunkProviderClient.class) +public class MixinChunkProviderClient implements IChunkProviderClient { + + @Shadow + @Final + private Long2ObjectMap loadedChunks; + + @Override + public Long2ObjectMap loadedChunks() { + return this.loadedChunks; + } +} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index 9ea703306..09ebbafd4 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -10,6 +10,7 @@ "client": [ "MixinAnvilChunkLoader", "MixinBlockPos", + "MixinChunkProviderClient", "MixinChunkProviderServer", "MixinEntity", "MixinEntityLivingBase", diff --git a/src/main/java/baritone/pathing/calc/Path.java b/src/main/java/baritone/pathing/calc/Path.java index ee3b182b9..0b5b2cc71 100644 --- a/src/main/java/baritone/pathing/calc/Path.java +++ b/src/main/java/baritone/pathing/calc/Path.java @@ -129,7 +129,7 @@ class Path extends PathBase { private Movement runBackwards(BetterBlockPos src, BetterBlockPos dest, double cost) { for (Moves moves : Moves.values()) { - Movement move = moves.apply0(context.getBaritone(), src); + Movement move = moves.apply0(context, src); if (move.getDest().equals(dest)) { // have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution move.override(cost); diff --git a/src/main/java/baritone/pathing/movement/Moves.java b/src/main/java/baritone/pathing/movement/Moves.java index ebb970819..c5a6ceb6d 100644 --- a/src/main/java/baritone/pathing/movement/Moves.java +++ b/src/main/java/baritone/pathing/movement/Moves.java @@ -17,7 +17,6 @@ package baritone.pathing.movement; -import baritone.api.IBaritone; import baritone.api.utils.BetterBlockPos; import baritone.pathing.movement.movements.*; import baritone.utils.pathing.MutableMoveResult; @@ -31,8 +30,8 @@ import net.minecraft.util.EnumFacing; public enum Moves { DOWNWARD(0, -1, 0) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementDownward(baritone, src, src.down()); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementDownward(context.getBaritone(), src, src.down()); } @Override @@ -43,8 +42,8 @@ public enum Moves { PILLAR(0, +1, 0) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementPillar(baritone, src, src.up()); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementPillar(context.getBaritone(), src, src.up()); } @Override @@ -55,8 +54,8 @@ public enum Moves { TRAVERSE_NORTH(0, 0, -1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementTraverse(baritone, src, src.north()); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementTraverse(context.getBaritone(), src, src.north()); } @Override @@ -67,8 +66,8 @@ public enum Moves { TRAVERSE_SOUTH(0, 0, +1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementTraverse(baritone, src, src.south()); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementTraverse(context.getBaritone(), src, src.south()); } @Override @@ -79,8 +78,8 @@ public enum Moves { TRAVERSE_EAST(+1, 0, 0) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementTraverse(baritone, src, src.east()); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementTraverse(context.getBaritone(), src, src.east()); } @Override @@ -91,8 +90,8 @@ public enum Moves { TRAVERSE_WEST(-1, 0, 0) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementTraverse(baritone, src, src.west()); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementTraverse(context.getBaritone(), src, src.west()); } @Override @@ -103,8 +102,8 @@ public enum Moves { ASCEND_NORTH(0, +1, -1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementAscend(baritone, src, new BetterBlockPos(src.x, src.y + 1, src.z - 1)); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x, src.y + 1, src.z - 1)); } @Override @@ -115,8 +114,8 @@ public enum Moves { ASCEND_SOUTH(0, +1, +1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementAscend(baritone, src, new BetterBlockPos(src.x, src.y + 1, src.z + 1)); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x, src.y + 1, src.z + 1)); } @Override @@ -127,8 +126,8 @@ public enum Moves { ASCEND_EAST(+1, +1, 0) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementAscend(baritone, src, new BetterBlockPos(src.x + 1, src.y + 1, src.z)); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x + 1, src.y + 1, src.z)); } @Override @@ -139,8 +138,8 @@ public enum Moves { ASCEND_WEST(-1, +1, 0) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementAscend(baritone, src, new BetterBlockPos(src.x - 1, src.y + 1, src.z)); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x - 1, src.y + 1, src.z)); } @Override @@ -151,13 +150,13 @@ public enum Moves { DESCEND_EAST(+1, -1, 0, false, true) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { + public Movement apply0(CalculationContext context, BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); - apply(new CalculationContext(baritone), src.x, src.y, src.z, res); + apply(context, src.x, src.y, src.z, res); if (res.y == src.y - 1) { - return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } else { - return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } } @@ -169,13 +168,13 @@ public enum Moves { DESCEND_WEST(-1, -1, 0, false, true) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { + public Movement apply0(CalculationContext context, BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); - apply(new CalculationContext(baritone), src.x, src.y, src.z, res); + apply(context, src.x, src.y, src.z, res); if (res.y == src.y - 1) { - return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } else { - return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } } @@ -187,13 +186,13 @@ public enum Moves { DESCEND_NORTH(0, -1, -1, false, true) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { + public Movement apply0(CalculationContext context, BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); - apply(new CalculationContext(baritone), src.x, src.y, src.z, res); + apply(context, src.x, src.y, src.z, res); if (res.y == src.y - 1) { - return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } else { - return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } } @@ -205,13 +204,13 @@ public enum Moves { DESCEND_SOUTH(0, -1, +1, false, true) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { + public Movement apply0(CalculationContext context, BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); - apply(new CalculationContext(baritone), src.x, src.y, src.z, res); + apply(context, src.x, src.y, src.z, res); if (res.y == src.y - 1) { - return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } else { - return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); + return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z)); } } @@ -223,8 +222,8 @@ public enum Moves { DIAGONAL_NORTHEAST(+1, 0, -1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementDiagonal(baritone, src, EnumFacing.NORTH, EnumFacing.EAST); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementDiagonal(context.getBaritone(), src, EnumFacing.NORTH, EnumFacing.EAST); } @Override @@ -235,8 +234,8 @@ public enum Moves { DIAGONAL_NORTHWEST(-1, 0, -1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementDiagonal(baritone, src, EnumFacing.NORTH, EnumFacing.WEST); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementDiagonal(context.getBaritone(), src, EnumFacing.NORTH, EnumFacing.WEST); } @Override @@ -247,8 +246,8 @@ public enum Moves { DIAGONAL_SOUTHEAST(+1, 0, +1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementDiagonal(baritone, src, EnumFacing.SOUTH, EnumFacing.EAST); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementDiagonal(context.getBaritone(), src, EnumFacing.SOUTH, EnumFacing.EAST); } @Override @@ -259,8 +258,8 @@ public enum Moves { DIAGONAL_SOUTHWEST(-1, 0, +1) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return new MovementDiagonal(baritone, src, EnumFacing.SOUTH, EnumFacing.WEST); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return new MovementDiagonal(context.getBaritone(), src, EnumFacing.SOUTH, EnumFacing.WEST); } @Override @@ -271,8 +270,8 @@ public enum Moves { PARKOUR_NORTH(0, 0, -4, true, false) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return MovementParkour.cost(baritone, src, EnumFacing.NORTH); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return MovementParkour.cost(context, src, EnumFacing.NORTH); } @Override @@ -283,8 +282,8 @@ public enum Moves { PARKOUR_SOUTH(0, 0, +4, true, false) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return MovementParkour.cost(baritone, src, EnumFacing.SOUTH); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return MovementParkour.cost(context, src, EnumFacing.SOUTH); } @Override @@ -295,8 +294,8 @@ public enum Moves { PARKOUR_EAST(+4, 0, 0, true, false) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return MovementParkour.cost(baritone, src, EnumFacing.EAST); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return MovementParkour.cost(context, src, EnumFacing.EAST); } @Override @@ -307,8 +306,8 @@ public enum Moves { PARKOUR_WEST(-4, 0, 0, true, false) { @Override - public Movement apply0(IBaritone baritone, BetterBlockPos src) { - return MovementParkour.cost(baritone, src, EnumFacing.WEST); + public Movement apply0(CalculationContext context, BetterBlockPos src) { + return MovementParkour.cost(context, src, EnumFacing.WEST); } @Override @@ -336,7 +335,7 @@ public enum Moves { this(x, y, z, false, false); } - public abstract Movement apply0(IBaritone baritone, BetterBlockPos src); + public abstract Movement apply0(CalculationContext context, BetterBlockPos src); public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) { if (dynamicXZ || dynamicY) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index 9010251d8..80d6feb4f 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -57,11 +57,11 @@ public class MovementParkour extends Movement { this.dist = dist; } - public static MovementParkour cost(IBaritone baritone, BetterBlockPos src, EnumFacing direction) { + public static MovementParkour cost(CalculationContext context, BetterBlockPos src, EnumFacing direction) { MutableMoveResult res = new MutableMoveResult(); - cost(new CalculationContext(baritone), src.x, src.y, src.z, direction, res); + cost(context, src.x, src.y, src.z, direction, res); int dist = Math.abs(res.x - src.x) + Math.abs(res.z - src.z); - return new MovementParkour(baritone, src, dist, direction); + return new MovementParkour(context.getBaritone(), src, dist, direction); } public static void cost(CalculationContext context, int x, int y, int z, EnumFacing dir, MutableMoveResult res) { diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index 5eefe6a92..95f2122b3 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -24,6 +24,7 @@ import baritone.api.pathing.goals.GoalGetToBlock; import baritone.api.process.IGetToBlockProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; +import baritone.pathing.movement.CalculationContext; import baritone.utils.BaritoneProcessHelper; import net.minecraft.block.Block; import net.minecraft.util.math.BlockPos; @@ -46,7 +47,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl public void getToBlock(Block block) { gettingTo = block; knownLocations = null; - rescan(new ArrayList<>()); + rescan(new ArrayList<>(), new CalculationContext(baritone)); } @Override @@ -57,7 +58,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (knownLocations == null) { - rescan(new ArrayList<>()); + rescan(new ArrayList<>(), new CalculationContext(baritone)); } if (knownLocations.isEmpty()) { logDirect("No known locations of " + gettingTo + ", canceling GetToBlock"); @@ -76,7 +77,8 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get(); if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain List current = new ArrayList<>(knownLocations); - Baritone.getExecutor().execute(() -> rescan(current)); + CalculationContext context = new CalculationContext(baritone); + Baritone.getExecutor().execute(() -> rescan(current, context)); } Goal goal = new GoalComposite(knownLocations.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)); if (goal.isInGoal(ctx.playerFeet())) { @@ -96,7 +98,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl return "Get To Block " + gettingTo; } - private void rescan(List known) { - knownLocations = MineProcess.searchWorld(ctx, Collections.singletonList(gettingTo), 64, known); + private void rescan(List known, CalculationContext context) { + knownLocations = MineProcess.searchWorld(context, Collections.singletonList(gettingTo), 64, known); } } \ No newline at end of file diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index a0495adef..a59695c72 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -27,6 +27,7 @@ import baritone.api.utils.RotationUtils; import baritone.cache.CachedChunk; import baritone.cache.ChunkPacker; import baritone.cache.WorldScanner; +import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; import baritone.utils.BlockStateInterface; @@ -88,7 +89,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get(); if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain List curr = new ArrayList<>(knownOreLocations); - Baritone.getExecutor().execute(() -> rescan(curr)); + CalculationContext context = new CalculationContext(baritone); + Baritone.getExecutor().execute(() -> rescan(curr, context)); } if (Baritone.settings().legitMine.get()) { addNearby(); @@ -116,7 +118,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro private Goal updateGoal() { List locs = knownOreLocations; if (!locs.isEmpty()) { - List locs2 = prune(ctx, new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT); + List locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT); // can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new)); knownOreLocations = locs2; @@ -151,14 +153,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return branchPointRunaway; } - private void rescan(List already) { + private void rescan(List already, CalculationContext context) { if (mining == null) { return; } if (Baritone.settings().legitMine.get()) { return; } - List locs = searchWorld(ctx, mining, ORE_LOCATIONS_COUNT, already); + List locs = searchWorld(context, mining, ORE_LOCATIONS_COUNT, already); locs.addAll(droppedItemsScan(mining, ctx.world())); if (locs.isEmpty()) { logDebug("No locations for " + mining + " known, cancelling"); @@ -205,13 +207,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro /*public static List searchWorld(List mining, int max, World world) { }*/ - public static List searchWorld(IPlayerContext ctx, List mining, int max, List alreadyKnown) { + public static List searchWorld(CalculationContext ctx, List mining, int max, List alreadyKnown) { + IPlayerContext ipc; List locs = new ArrayList<>(); List uninteresting = new ArrayList<>(); //long b = System.currentTimeMillis(); for (Block m : mining) { if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) { - locs.addAll(ctx.worldData().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 1)); + locs.addAll(ctx.worldData().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 1)); } else { uninteresting.add(m); } @@ -222,7 +225,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } if (!uninteresting.isEmpty()) { //long before = System.currentTimeMillis(); - locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx, uninteresting, max, 10, 26)); + locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 26)); //System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms"); } locs.addAll(alreadyKnown); @@ -246,22 +249,22 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } } } - knownOreLocations = prune(ctx, knownOreLocations, mining, ORE_LOCATIONS_COUNT); + knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, mining, ORE_LOCATIONS_COUNT); } - public static List prune(IPlayerContext ctx, List locs2, List mining, int max) { + public static List prune(CalculationContext ctx, List locs2, List mining, int max) { List dropped = droppedItemsScan(mining, ctx.world()); List locs = locs2 .stream() .distinct() // remove any that are within loaded chunks that aren't actually what we want - .filter(pos -> ctx.world().getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.getBlock(ctx, pos)) || dropped.contains(pos)) + .filter(pos -> ctx.world().getChunk(pos) instanceof EmptyChunk || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos)) // remove any that are implausible to mine (encased in bedrock, or touching lava) - .filter(pos -> MineProcess.plausibleToBreak(ctx, pos)) + .filter(pos -> MineProcess.plausibleToBreak(ctx.bsi(), pos)) - .sorted(Comparator.comparingDouble(ctx.playerFeet()::distanceSq)) + .sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq)) .collect(Collectors.toList()); if (locs.size() > max) { @@ -270,12 +273,13 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return locs; } - public static boolean plausibleToBreak(IPlayerContext ctx, BlockPos pos) { - if (MovementHelper.avoidBreaking(new BlockStateInterface(ctx), pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(ctx, pos))) { + public static boolean plausibleToBreak(BlockStateInterface bsi, BlockPos pos) { + if (MovementHelper.avoidBreaking(bsi, pos.getX(), pos.getY(), pos.getZ(), bsi.get0(pos))) { return false; } + // bedrock above and below makes it implausible, otherwise we're good - return !(BlockStateInterface.getBlock(ctx, pos.up()) == Blocks.BEDROCK && BlockStateInterface.getBlock(ctx, pos.down()) == Blocks.BEDROCK); + return !(bsi.get0(pos.up()).getBlock() == Blocks.BEDROCK && bsi.get0(pos.down()).getBlock() == Blocks.BEDROCK); } @Override @@ -290,6 +294,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro this.knownOreLocations = new ArrayList<>(); this.branchPoint = null; this.branchPointRunaway = null; - rescan(new ArrayList<>()); + if (mining != null) { + rescan(new ArrayList<>(), new CalculationContext(baritone)); + } } } diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index 63ba8d83b..9b6401e96 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -21,12 +21,17 @@ import baritone.Baritone; import baritone.api.utils.IPlayerContext; import baritone.cache.CachedRegion; import baritone.cache.WorldData; +import baritone.utils.accessor.IChunkProviderClient; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.EmptyChunk; /** * Wraps get for chuck caching capability @@ -36,6 +41,7 @@ import net.minecraft.world.chunk.Chunk; public class BlockStateInterface { private final World world; + private final Long2ObjectMap loadedChunks; private final WorldData worldData; private Chunk prev = null; @@ -50,6 +56,10 @@ public class BlockStateInterface { public BlockStateInterface(World world, WorldData worldData) { this.worldData = worldData; this.world = world; + this.loadedChunks = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks(); + if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) { + throw new IllegalStateException(); + } } public World getWorld() { @@ -66,6 +76,10 @@ public class BlockStateInterface { // and toBreak and stuff fails when the movement is instantiated out of load range but it's not able to BlockStateInterface.get what it's going to walk on } + public IBlockState get0(BlockPos pos) { + return get0(pos.getX(), pos.getY(), pos.getZ()); + } + public IBlockState get0(int x, int y, int z) { // Mickey resigned // Invalid vertical position @@ -84,7 +98,12 @@ public class BlockStateInterface { if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) { return cached.getBlockState(x, y, z); } + Chunk c2 = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4)); Chunk chunk = world.getChunk(x >> 4, z >> 4); + + if ((c2 != null && c2 != chunk) || (c2 == null && !(chunk instanceof EmptyChunk))) { + throw new IllegalStateException((((IChunkProviderClient) world.getChunkProvider()).loadedChunks() == loadedChunks) + " " + x + " " + y + " " + c2 + " " + chunk); + } if (chunk.isLoaded()) { prev = chunk; return chunk.getBlockState(x, y, z); diff --git a/src/main/java/baritone/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java index 841349e46..93e2742a8 100644 --- a/src/main/java/baritone/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java @@ -28,6 +28,7 @@ import baritone.behavior.Behavior; import baritone.behavior.PathingBehavior; import baritone.cache.ChunkPacker; import baritone.cache.Waypoint; +import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.Moves; import baritone.process.CustomGoalProcess; @@ -446,7 +447,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper { return true; } if (msg.equals("costs")) { - List moves = Stream.of(Moves.values()).map(x -> x.apply0(baritone, ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new)); + List moves = Stream.of(Moves.values()).map(x -> x.apply0(new CalculationContext(baritone), ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new)); while (moves.contains(null)) { moves.remove(null); } diff --git a/src/main/java/baritone/utils/accessor/IChunkProviderClient.java b/src/main/java/baritone/utils/accessor/IChunkProviderClient.java new file mode 100644 index 000000000..19f146854 --- /dev/null +++ b/src/main/java/baritone/utils/accessor/IChunkProviderClient.java @@ -0,0 +1,25 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.utils.accessor; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.minecraft.world.chunk.Chunk; + +public interface IChunkProviderClient { + Long2ObjectMap loadedChunks(); +} From b228f4c6fb6d8a952634a5949dc3dba2145f5f75 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 09:03:51 -0800 Subject: [PATCH 18/31] remove extraneous checks in bsi --- .../pathing/movement/MovementHelper.java | 2 +- .../baritone/utils/BlockStateInterface.java | 19 ++++++------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index ff73b0f29..917adc7c2 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -86,7 +86,7 @@ public interface MovementHelper extends ActionCosts, Helper { // so the only remaining dynamic isPassables are snow and trapdoor // if they're cached as a top block, we don't know their metadata // default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible) - if (bsi.getWorld().getChunk(x >> 4, z >> 4) instanceof EmptyChunk) { + if (!bsi.worldContainsLoadedChunk(x, z)) { return true; } if (snow) { diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index 9b6401e96..b6b264d0d 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -31,7 +31,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.EmptyChunk; /** * Wraps get for chuck caching capability @@ -40,7 +39,6 @@ import net.minecraft.world.chunk.EmptyChunk; */ public class BlockStateInterface { - private final World world; private final Long2ObjectMap loadedChunks; private final WorldData worldData; @@ -55,15 +53,14 @@ public class BlockStateInterface { public BlockStateInterface(World world, WorldData worldData) { this.worldData = worldData; - this.world = world; this.loadedChunks = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks(); if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) { throw new IllegalStateException(); } } - public World getWorld() { - return world; + public boolean worldContainsLoadedChunk(int blockX, int blockZ) { + return loadedChunks.containsKey(ChunkPos.asLong(blockX >> 4, blockZ >> 4)); } public static Block getBlock(IPlayerContext ctx, BlockPos pos) { // won't be called from the pathing thread because the pathing thread doesn't make a single blockpos pog @@ -98,13 +95,9 @@ public class BlockStateInterface { if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) { return cached.getBlockState(x, y, z); } - Chunk c2 = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4)); - Chunk chunk = world.getChunk(x >> 4, z >> 4); + Chunk chunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4)); - if ((c2 != null && c2 != chunk) || (c2 == null && !(chunk instanceof EmptyChunk))) { - throw new IllegalStateException((((IChunkProviderClient) world.getChunkProvider()).loadedChunks() == loadedChunks) + " " + x + " " + y + " " + c2 + " " + chunk); - } - if (chunk.isLoaded()) { + if (chunk != null && chunk.isLoaded()) { prev = chunk; return chunk.getBlockState(x, y, z); } @@ -135,8 +128,8 @@ public class BlockStateInterface { if (prevChunk != null && prevChunk.x == x >> 4 && prevChunk.z == z >> 4) { return true; } - prevChunk = world.getChunk(x >> 4, z >> 4); - if (prevChunk.isLoaded()) { + prevChunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4)); + if (prevChunk != null && prevChunk.isLoaded()) { prev = prevChunk; return true; } From 6ed8d617cd01e2fcf97859ba4c5ef1ec14b675ba Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 09:31:25 -0800 Subject: [PATCH 19/31] improve path checks, and add a overlap splice option --- .../java/baritone/api/pathing/calc/IPath.java | 11 +++++-- .../baritone/pathing/path/PathExecutor.java | 2 +- .../baritone/pathing/path/SplicedPath.java | 29 ++++++++++++++----- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/api/java/baritone/api/pathing/calc/IPath.java b/src/api/java/baritone/api/pathing/calc/IPath.java index 0844ab90b..133de5efc 100644 --- a/src/api/java/baritone/api/pathing/calc/IPath.java +++ b/src/api/java/baritone/api/pathing/calc/IPath.java @@ -21,9 +21,9 @@ import baritone.api.Settings; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.movement.IMovement; import baritone.api.utils.BetterBlockPos; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import java.util.HashSet; import java.util.List; /** @@ -153,9 +153,10 @@ public interface IPath { if (path.size() != movements.size() + 1) { throw new IllegalStateException("Size of path array is unexpected"); } + HashSet seenSoFar = new HashSet<>(); for (int i = 0; i < path.size() - 1; i++) { - BlockPos src = path.get(i); - BlockPos dest = path.get(i + 1); + BetterBlockPos src = path.get(i); + BetterBlockPos dest = path.get(i + 1); IMovement movement = movements.get(i); if (!src.equals(movement.getSrc())) { throw new IllegalStateException("Path source is not equal to the movement source"); @@ -163,6 +164,10 @@ public interface IPath { if (!dest.equals(movement.getDest())) { throw new IllegalStateException("Path destination is not equal to the movement destination"); } + if (seenSoFar.contains(src)) { + throw new IllegalStateException("Path doubles back on itself, making a loop"); + } + seenSoFar.add(src); } } } diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index af0fe142e..171dd769a 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -458,7 +458,7 @@ public class PathExecutor implements IPathExecutor, Helper { if (next == null) { return cutIfTooLong(); } - return SplicedPath.trySplice(path, next.path).map(path -> { + return SplicedPath.trySplice(path, next.path, false).map(path -> { if (!path.getDest().equals(next.getPath().getDest())) { throw new IllegalStateException(); } diff --git a/src/main/java/baritone/pathing/path/SplicedPath.java b/src/main/java/baritone/pathing/path/SplicedPath.java index 5048a84a0..92610c863 100644 --- a/src/main/java/baritone/pathing/path/SplicedPath.java +++ b/src/main/java/baritone/pathing/path/SplicedPath.java @@ -62,7 +62,7 @@ public class SplicedPath extends PathBase { return numNodes; } - public static Optional trySplice(IPath first, IPath second) { + public static Optional trySplice(IPath first, IPath second, boolean allowOverlapCutoff) { if (second == null || first == null) { return Optional.empty(); } @@ -72,18 +72,31 @@ public class SplicedPath extends PathBase { if (!first.getDest().equals(second.getSrc())) { return Optional.empty(); } - HashSet a = new HashSet<>(first.positions()); - for (int i = 1; i < second.length(); i++) { - if (a.contains(second.positions().get(i))) { + HashSet secondPos = new HashSet<>(second.positions()); + int firstPositionInSecond = -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))) { + firstPositionInSecond = i; + } + } + if (firstPositionInSecond != -1) { + if (!allowOverlapCutoff) { return Optional.empty(); } + } else { + firstPositionInSecond = first.length() - 1; + } + int positionInSecond = second.positions().indexOf(first.positions().get(firstPositionInSecond)); + if (!allowOverlapCutoff && positionInSecond != 0) { + throw new IllegalStateException(); } List positions = new ArrayList<>(); List movements = new ArrayList<>(); - positions.addAll(first.positions()); - positions.addAll(second.positions().subList(1, second.length())); - movements.addAll(first.movements()); - movements.addAll(second.movements()); + positions.addAll(first.positions().subList(0, firstPositionInSecond + 1)); + movements.addAll(first.movements().subList(0, firstPositionInSecond)); + + positions.addAll(second.positions().subList(positionInSecond + 1, second.length())); + movements.addAll(second.movements().subList(positionInSecond, second.length() - 1)); return Optional.of(new SplicedPath(positions, movements, first.getNumNodesConsidered() + second.getNumNodesConsidered(), first.getGoal())); } } From dd47e20070c1ada8ad5f48a58343a4456ce4d664 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:20:48 -0800 Subject: [PATCH 20/31] remove unneeded --- src/main/java/baritone/process/MineProcess.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index a59695c72..4ea753871 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -204,11 +204,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return ret; } - /*public static List searchWorld(List mining, int max, World world) { - - }*/ public static List searchWorld(CalculationContext ctx, List mining, int max, List alreadyKnown) { - IPlayerContext ipc; List locs = new ArrayList<>(); List uninteresting = new ArrayList<>(); //long b = System.currentTimeMillis(); From a98c5d7d9987f7511e70ea28cfbe02e411264aa0 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:25:02 -0800 Subject: [PATCH 21/31] my house --- src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index ac4efa4d2..26601b13e 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -87,7 +87,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { if (isFinished) { throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!"); } - this.cancelRequested = false; + cancelRequested = false; try { IPath path = calculate0(timeout).map(IPath::postProcess).orElse(null); isFinished = true; From 4502adda28b317f15bd8dad1b3584e43b3e4b402 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:36:06 -0800 Subject: [PATCH 22/31] segmented path calculator --- .../api/utils/PathCalculationResult.java | 3 + .../baritone/behavior/PathingBehavior.java | 11 ++- .../utils/pathing/SegmentedCalculator.java | 87 +++++++++++++++++++ 3 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 src/main/java/baritone/utils/pathing/SegmentedCalculator.java diff --git a/src/api/java/baritone/api/utils/PathCalculationResult.java b/src/api/java/baritone/api/utils/PathCalculationResult.java index df0099520..20aef9de7 100644 --- a/src/api/java/baritone/api/utils/PathCalculationResult.java +++ b/src/api/java/baritone/api/utils/PathCalculationResult.java @@ -33,6 +33,9 @@ public class PathCalculationResult { public PathCalculationResult(Type type, IPath path) { this.path = path; this.type = type; + if (type == null) { + throw new IllegalArgumentException("come on"); + } } public final Optional getPath() { diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index f2017eefc..42186b5b2 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -40,10 +40,7 @@ import baritone.utils.PathRenderer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.EmptyChunk; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Optional; +import java.util.*; import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; @@ -410,6 +407,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, } 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); + if (!Objects.equals(pathfinder.getGoal(), goal)) { + logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance"); + } inProgress = pathfinder; Baritone.getExecutor().execute(() -> { if (talkAboutIt) { @@ -480,12 +480,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, }); } - private AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) { + public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) { Goal transformed = goal; if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) { BlockPos pos = ((IGoalRenderPos) goal).getGoalPos(); if (context.world().getChunk(pos) instanceof EmptyChunk) { - logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance"); transformed = new GoalXZ(pos.getX(), pos.getZ()); } } diff --git a/src/main/java/baritone/utils/pathing/SegmentedCalculator.java b/src/main/java/baritone/utils/pathing/SegmentedCalculator.java new file mode 100644 index 000000000..a0b8e27c1 --- /dev/null +++ b/src/main/java/baritone/utils/pathing/SegmentedCalculator.java @@ -0,0 +1,87 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.utils.pathing; + +import baritone.Baritone; +import baritone.api.pathing.calc.IPath; +import baritone.api.pathing.goals.Goal; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.PathCalculationResult; +import baritone.behavior.PathingBehavior; +import baritone.pathing.calc.AbstractNodeCostSearch; +import baritone.pathing.movement.CalculationContext; +import baritone.pathing.path.SplicedPath; + +import java.util.Optional; +import java.util.function.Consumer; + +/** + * Calculate and splice many path segments to reach a goal + * + * @author leijurv + */ +public class SegmentedCalculator { + private final BetterBlockPos start; + private final Goal goal; + private final CalculationContext context; + + private SegmentedCalculator(BetterBlockPos start, Goal goal, CalculationContext context) { + this.start = start; + this.goal = goal; + this.context = context; + } + + private Optional doCalc() { + Optional soFar = Optional.empty(); + while (true) { + PathCalculationResult result = segment(soFar); + switch (result.getType()) { + case SUCCESS_SEGMENT: + 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 EXCEPTION: // if path calculation threw an exception, we're done + return soFar; + default: // CANCELLATION and null should not be possible, nothing else has access to this, so it can't have been canceled + throw new IllegalStateException(); + } + 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); + soFar = Optional.of(combined); + } + } + + private PathCalculationResult segment(Optional previous) { + BetterBlockPos segmentStart = previous.map(IPath::getDest).orElse(start); // <-- e p i c + AbstractNodeCostSearch search = PathingBehavior.createPathfinder(segmentStart, goal, previous.orElse(null), context); + 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 + } + + public static void calculateSegmentsThreaded(BetterBlockPos start, Goal goal, CalculationContext context, Consumer> onCompletion) { + Baritone.getExecutor().execute(() -> { + Optional result; + try { + result = new SegmentedCalculator(start, goal, context).doCalc(); + } catch (Exception ex) { + ex.printStackTrace(); + result = Optional.empty(); + } + onCompletion.accept(result); + }); + } +} From 653861107dd00a504f93000d8d7601e114e1e3b0 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:50:03 -0800 Subject: [PATCH 23/31] explain documentation more --- src/api/java/baritone/api/Settings.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index f4fd7db14..a835ed73f 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -247,7 +247,9 @@ public class Settings { public Setting movementTimeoutTicks = new Setting<>(100); /** - * Pathing ends after this amount of time, if a path has been found + * Pathing ends after this amount of time, but only if a path has been found + *

+ * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout */ public Setting primaryTimeoutMS = new Setting<>(500L); @@ -257,7 +259,9 @@ public class Settings { public Setting failureTimeoutMS = new Setting<>(2000L); /** - * Planning ahead while executing a segment ends after this amount of time, if a path has been found + * Planning ahead while executing a segment ends after this amount of time, but only if a path has been found + *

+ * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout */ public Setting planAheadPrimaryTimeoutMS = new Setting<>(4000L); From d854750ee8a088a540caffca5819f2c2c18a2428 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:52:56 -0800 Subject: [PATCH 24/31] improve accuracy of GoalGetToBlock heuristic --- .../java/baritone/api/pathing/goals/GoalGetToBlock.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java index 959b6fcc6..c4856cdd6 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java @@ -48,10 +48,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { int xDiff = x - this.x; int yDiff = y - this.y; int zDiff = z - this.z; - if (yDiff < 0) { - yDiff++; - } - return Math.abs(xDiff) + Math.abs(yDiff) + Math.abs(zDiff) <= 1; + return Math.abs(xDiff) + Math.abs(yDiff < 0 ? yDiff + 1 : yDiff) + Math.abs(zDiff) <= 1; } @Override @@ -59,7 +56,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { int xDiff = x - this.x; int yDiff = y - this.y; int zDiff = z - this.z; - return GoalBlock.calculate(xDiff, yDiff, zDiff); + return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff); } @Override From b7052791531cf502a99015388e2c7a86986eb3bf Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:55:02 -0800 Subject: [PATCH 25/31] consistency --- src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java index 4ed1bf5ee..b1dc07a1d 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java +++ b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java @@ -63,10 +63,7 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos { int xDiff = x - this.x; int yDiff = y - this.y; int zDiff = z - this.z; - if (yDiff < 0) { - yDiff++; - } - return GoalBlock.calculate(xDiff, yDiff, zDiff); + return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff); } @Override From 84cd4b1acb5ab1d82035d7c983c942f88a3a8555 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:58:23 -0800 Subject: [PATCH 26/31] unused --- .../baritone/api/pathing/goals/GoalComposite.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalComposite.java b/src/api/java/baritone/api/pathing/goals/GoalComposite.java index 2926b8528..415f74e56 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalComposite.java +++ b/src/api/java/baritone/api/pathing/goals/GoalComposite.java @@ -17,10 +17,7 @@ package baritone.api.pathing.goals; -import net.minecraft.util.math.BlockPos; - import java.util.Arrays; -import java.util.Collection; /** * A composite of many goals, any one of which satisfies the composite. @@ -40,14 +37,6 @@ public class GoalComposite implements Goal { this.goals = goals; } - public GoalComposite(BlockPos... blocks) { - this(Arrays.asList(blocks)); - } - - public GoalComposite(Collection blocks) { - this(blocks.stream().map(GoalBlock::new).toArray(Goal[]::new)); - } - @Override public boolean isInGoal(int x, int y, int z) { for (Goal goal : goals) { From 5aa78cd478acf8b907be25c0e6ff3230ec504df5 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 11:22:49 -0800 Subject: [PATCH 27/31] crucial performance optimization --- src/main/java/baritone/cache/ChunkPacker.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/cache/ChunkPacker.java b/src/main/java/baritone/cache/ChunkPacker.java index 0627ebb4c..cd072bb6f 100644 --- a/src/main/java/baritone/cache/ChunkPacker.java +++ b/src/main/java/baritone/cache/ChunkPacker.java @@ -92,7 +92,8 @@ public final class ChunkPacker { for (int z = 0; z < 16; z++) { // @formatter:off - https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html + https: +//www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html // @formatter:on for (int x = 0; x < 16; x++) { for (int y = 255; y >= 0; y--) { @@ -124,7 +125,7 @@ public final class ChunkPacker { private static PathingBlockType getPathingBlockType(IBlockState state) { Block block = state.getBlock(); - if (block.equals(Blocks.WATER) && !MovementHelper.isFlowing(state)) { + if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) { // only water source blocks are plausibly usable, flowing water should be avoid return PathingBlockType.WATER; } From 7632d667c9711dbe687b4105ebfa273636549d40 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 22 Nov 2018 09:39:54 -0800 Subject: [PATCH 28/31] add a secondary failure cutoff --- src/api/java/baritone/api/Settings.java | 18 ++++++++++++---- .../api/pathing/calc/IPathFinder.java | 2 +- .../baritone/behavior/PathingBehavior.java | 16 +++++++++----- .../pathing/calc/AStarPathFinder.java | 21 ++++++++++++++----- .../pathing/calc/AbstractNodeCostSearch.java | 16 ++++++-------- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 7fce02540..f4fd7db14 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -247,14 +247,24 @@ public class Settings { public Setting movementTimeoutTicks = new Setting<>(100); /** - * Pathing can never take longer than this + * Pathing ends after this amount of time, if a path has been found */ - public Setting pathTimeoutMS = new Setting<>(2000L); + public Setting primaryTimeoutMS = new Setting<>(500L); /** - * Planning ahead while executing a segment can never take longer than this + * Pathing can never take longer than this, even if that means failing to find any path at all */ - public Setting planAheadTimeoutMS = new Setting<>(4000L); + public Setting failureTimeoutMS = new Setting<>(2000L); + + /** + * Planning ahead while executing a segment ends after this amount of time, if a path has been found + */ + public Setting planAheadPrimaryTimeoutMS = new Setting<>(4000L); + + /** + * Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all + */ + public Setting planAheadFailureTimeoutMS = new Setting<>(5000L); /** * For debugging, consider nodes much much slower diff --git a/src/api/java/baritone/api/pathing/calc/IPathFinder.java b/src/api/java/baritone/api/pathing/calc/IPathFinder.java index f70196a69..fa83295f7 100644 --- a/src/api/java/baritone/api/pathing/calc/IPathFinder.java +++ b/src/api/java/baritone/api/pathing/calc/IPathFinder.java @@ -36,7 +36,7 @@ public interface IPathFinder { * * @return The final path */ - PathCalculationResult calculate(long timeout); + PathCalculationResult calculate(long primaryTimeout, long failureTimeout); /** * Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 1943b215e..f2017eefc 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -40,7 +40,10 @@ import baritone.utils.PathRenderer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.EmptyChunk; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Optional; import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; @@ -396,11 +399,14 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller return; } - long timeout; + long primaryTimeout; + long failureTimeout; if (current == null) { - timeout = Baritone.settings().pathTimeoutMS.get(); + primaryTimeout = Baritone.settings().primaryTimeoutMS.get(); + failureTimeout = Baritone.settings().failureTimeoutMS.get(); } else { - timeout = Baritone.settings().planAheadTimeoutMS.get(); + primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.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 AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context); @@ -410,7 +416,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, logDebug("Starting to search for path from " + start + " to " + goal); } - PathCalculationResult calcResult = pathfinder.calculate(timeout); + PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout); Optional path = calcResult.getPath(); if (Baritone.settings().cutoffAtLoadBoundary.get()) { path = path.map(p -> { diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index f65920945..aa83bc442 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -49,7 +49,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel } @Override - protected Optional calculate0(long timeout) { + protected Optional calculate0(long primaryTimeout, long failureTimeout) { startNode = getNodeAtPosition(startX, startY, startZ, BetterBlockPos.longHash(startX, startY, startZ)); startNode.cost = 0; startNode.combinedCost = startNode.estimatedCostToGoal; @@ -68,10 +68,11 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel long startTime = System.nanoTime() / 1000000L; boolean slowPath = Baritone.settings().slowPath.get(); if (slowPath) { - logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.get() + "ms instead of " + timeout + "ms"); + logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.get() + "ms instead of " + primaryTimeout + "ms"); } - long timeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : timeout); - //long lastPrintout = 0; + long primaryTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : primaryTimeout); + long failureTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : failureTimeout); + boolean failing = true; int numNodes = 0; int numMovementsConsidered = 0; int numEmptyChunk = 0; @@ -79,7 +80,14 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get(); boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get(); - while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && System.nanoTime() / 1000000L - timeoutTime < 0 && !cancelRequested) { + while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) { + long now = System.nanoTime() / 1000000L; + if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) { + break; + } + if (failing == bestPathSoFar().isPresent()) { + throw new IllegalStateException(); + } if (slowPath) { try { Thread.sleep(Baritone.settings().slowPathTimeDelayMS.get()); @@ -166,6 +174,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel } bestHeuristicSoFar[i] = heuristic; bestSoFar[i] = neighbor; + if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) { + failing = false; + } } } } diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index 26601b13e..f2dcf4b19 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -83,13 +83,14 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { cancelRequested = true; } - public synchronized PathCalculationResult calculate(long timeout) { + @Override + public synchronized PathCalculationResult calculate(long primaryTimeout, long failureTimeout) { if (isFinished) { throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!"); } cancelRequested = false; try { - IPath path = calculate0(timeout).map(IPath::postProcess).orElse(null); + IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null); isFinished = true; if (cancelRequested) { return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path); @@ -112,7 +113,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { } } - protected abstract Optional calculate0(long timeout); + protected abstract Optional calculate0(long primaryTimeout, long failureTimeout); /** * Determines the distance squared from the specified node to the start @@ -157,7 +158,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { @Override public Optional bestPathSoFar() { - if (startNode == null || bestSoFar == null || bestSoFar[0] == null) { + if (startNode == null || bestSoFar == null) { return Optional.empty(); } for (int i = 0; i < bestSoFar.length; i++) { @@ -165,12 +166,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { continue; } if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared - try { - return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context)); - } catch (IllegalStateException ex) { - System.out.println("Unable to construct path to render"); - return Optional.empty(); - } + return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context)); } } // instead of returning bestSoFar[0], be less misleading From 50d4b5b4ed8324822eda7900f62dab1afea5dca1 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 22 Nov 2018 10:08:55 -0800 Subject: [PATCH 29/31] unneeded --- src/main/java/baritone/pathing/calc/AStarPathFinder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index aa83bc442..d00619211 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -85,9 +85,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) { break; } - if (failing == bestPathSoFar().isPresent()) { - throw new IllegalStateException(); - } if (slowPath) { try { Thread.sleep(Baritone.settings().slowPathTimeDelayMS.get()); From 038533c33f1cb3d2c44f87ebd3c64f0e2c537049 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:50:03 -0800 Subject: [PATCH 30/31] explain documentation more --- src/api/java/baritone/api/Settings.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index f4fd7db14..a835ed73f 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -247,7 +247,9 @@ public class Settings { public Setting movementTimeoutTicks = new Setting<>(100); /** - * Pathing ends after this amount of time, if a path has been found + * Pathing ends after this amount of time, but only if a path has been found + *

+ * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout */ public Setting primaryTimeoutMS = new Setting<>(500L); @@ -257,7 +259,9 @@ public class Settings { public Setting failureTimeoutMS = new Setting<>(2000L); /** - * Planning ahead while executing a segment ends after this amount of time, if a path has been found + * Planning ahead while executing a segment ends after this amount of time, but only if a path has been found + *

+ * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout */ public Setting planAheadPrimaryTimeoutMS = new Setting<>(4000L); From 9c5274dde41a5bb546b2cb3f8040e6f4f01a744f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 13:12:18 -0800 Subject: [PATCH 31/31] runnable conversion --- src/main/java/baritone/behavior/PathingBehavior.java | 5 +---- .../java/baritone/utils/pathing/SegmentedCalculator.java | 8 ++++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 26e8687c5..42186b5b2 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -40,10 +40,7 @@ import baritone.utils.PathRenderer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.EmptyChunk; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Optional; +import java.util.*; import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; diff --git a/src/main/java/baritone/utils/pathing/SegmentedCalculator.java b/src/main/java/baritone/utils/pathing/SegmentedCalculator.java index a0b8e27c1..75dd0282a 100644 --- a/src/main/java/baritone/utils/pathing/SegmentedCalculator.java +++ b/src/main/java/baritone/utils/pathing/SegmentedCalculator.java @@ -72,7 +72,7 @@ public class SegmentedCalculator { 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 } - public static void calculateSegmentsThreaded(BetterBlockPos start, Goal goal, CalculationContext context, Consumer> onCompletion) { + public static void calculateSegmentsThreaded(BetterBlockPos start, Goal goal, CalculationContext context, Consumer onCompletion, Runnable onFailure) { Baritone.getExecutor().execute(() -> { Optional result; try { @@ -81,7 +81,11 @@ public class SegmentedCalculator { ex.printStackTrace(); result = Optional.empty(); } - onCompletion.accept(result); + if (result.isPresent()) { + onCompletion.accept(result.get()); + } else { + onFailure.run(); + } }); } }