Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 111 additions & 6 deletions docs/entity-guides/movement.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ protected void shutDown() {
//Method from microbot
public static void exit() {
if (pathfindingExecutor != null) {
Rs2Walker.setTarget(null);
Rs2Walker.clearWalkingRoute("shortest-path-plugin:exit");
pathfindingExecutor.shutdownNow();
pathfindingExecutor = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ private boolean useTransport(Transport transport) {
if (transport.getCurrencyAmount() > 0) {
if (refreshCurrencyCache != null) {
int[] cached = refreshCurrencyCache.computeIfAbsent(transport.getCurrencyName(), name -> {
int invCount = Rs2Inventory.count(name);
int invCount = Rs2Inventory.itemQuantity(name);
int bankCount = useBankItems ? Rs2Bank.count(name) : 0;
return new int[]{invCount, bankCount};
});
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static void routeClearMissingReason(String threadName) {
LOG.warn("[WebWalk] clear | reason=<missing> thread={}", threadName);
}

/** Cancel / EXIT / traceProcessWalkExit compact WARN for production diagnosis. */
/** Cancel / EXIT / traceProcessWalkExit - compact WARN for production diagnosis. */
public static void exitWarn(String reason, boolean nullCurrent, boolean targetMismatch, boolean interrupted,
WorldPoint goal, WorldPoint current, int tailIdx, int tailMax, WorldPoint player) {
LOG.warn("[WebWalk] exit | r={} nullCur={} mismatch={} intr={} goal={} cur={} tail={}/{} at={}",
Expand All @@ -33,18 +33,23 @@ public static void exitDetailDebug(String fmt, Object... args) {
LOG.debug("[WebWalk] exit_dbg | " + fmt, args);
}

/** interim-in-flight and similar yields DEBUG to avoid tick spam. */
/** interim-in-flight and similar yields - DEBUG to avoid tick spam. */
public static void yieldDebug(String reason, WorldPoint player, WorldPoint goal, WorldPoint pathEnd, int idxStart, int pathLen) {
LOG.debug("[WebWalk] yield | r={} player={} goal={} end={} idx={}/{}",
reason, player, goal, pathEnd, idxStart, pathLen);
}

public static void earlyExit(String reason, WorldPoint player, WorldPoint goal, WorldPoint pathEnd, int idxStart, int pathLen) {
if ("interim-in-flight".equals(reason)) {
LOG.debug("[WebWalk] early_exit | r={} at={} goal={} end={} idx={}/{}",
reason, player, goal, pathEnd, idxStart, pathLen);
return;
}
LOG.info("[WebWalk] early_exit | r={} at={} goal={} end={} idx={}/{}",
reason, player, goal, pathEnd, idxStart, pathLen);
}

/** Path ends far from goal walking multi-hop segment. */
/** Path ends far from goal - walking multi-hop segment. */
public static void partialSegment(WorldPoint pathEnd, int distToGoal, WorldPoint goal, int waypointCount) {
LOG.info("[WebWalk] partial_seg | end={} dGoal={} goal={} nWp={}", pathEnd, distToGoal, goal, waypointCount);
}
Expand All @@ -65,7 +70,7 @@ public static void stallContextDebug(WorldPoint lastClick, boolean clickOk, long
LOG.debug("[WebWalk] stall_ctx | lastClick={} ok={} ageMs={} interim={}", lastClick, clickOk, clickAgeMs, interim);
}

/** Off-path / unreachable recovery / generic replan single INFO line. */
/** Off-path / unreachable recovery / generic replan - single INFO line. */
public static void recalc(String reason) {
LOG.info("[WebWalk] recalc | {}", reason);
}
Expand All @@ -86,12 +91,12 @@ public static void tailExceeded(int maxTail, WorldPoint target, WorldPoint curre
maxTail, target, current, interim, stuck, player);
}

/** Pathfinder {@link net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder} DEBUG volume. */
/** Pathfinder {@link net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder} - DEBUG volume. */
public static void pf(String fmt, Object... args) {
LOG.debug("[WebWalk] pf | " + fmt, args);
}

/** {@link net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig} refresh DEBUG volume. */
/** {@link net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig} refresh - DEBUG volume. */
public static void cfg(String fmt, Object... args) {
LOG.debug("[WebWalk] cfg | " + fmt, args);
}
Expand All @@ -100,7 +105,7 @@ public static void leagues(String fmt, Object... args) {
LOG.debug("[WebWalk] leagues | " + fmt, args);
}

/** Leagues calibration, region unlock, explicit no-op INFO (not tick-spam paths). */
/** Leagues calibration, region unlock, explicit no-op - INFO (not tick-spam paths). */
public static void leaguesInfo(String fmt, Object... args) {
LOG.info("[WebWalk] leagues | " + fmt, args);
}
Expand Down Expand Up @@ -131,7 +136,7 @@ public static void compareError(double totalMs, WorldPoint target, String err) {
LOG.warn("[WebWalk] compare_err | {}ms target={} err={}", String.format("%.1f", totalMs), target, err);
}

/** Banked-route helper: per-path transport scan DEBUG volume. */
/** Banked-route helper: per-path transport scan - DEBUG volume. */
public static void bankPathTransportsDebug(int count, WorldPoint from, WorldPoint to) {
LOG.debug("[WebWalk] bank_path | transports={} {} -> {}", count, from, to);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ public static boolean hasRequiredTransportItems(Transport transport) {
|| transport.getType() == TransportType.CHARTER_SHIP
|| transport.getType() == TransportType.SHIP
|| transport.getType() == TransportType.MINECART
|| transport.getType() == TransportType.MAGIC_CARPET) {
|| transport.getType() == TransportType.MAGIC_CARPET
|| (transport.getType() == TransportType.TRANSPORT && transport.getCurrencyAmount() > 0)) {
if (transport.getType() == TransportType.TELEPORTATION_SPELL && transport.getDisplayInfo() != null) {
String spellName = transport.getDisplayInfo().contains(":")
? transport.getDisplayInfo().split(":")[0].trim()
Expand Down Expand Up @@ -405,7 +406,8 @@ private static boolean isCurrencyBasedTransport(TransportType transportType) {
|| transportType == TransportType.CHARTER_SHIP
|| transportType == TransportType.SHIP
|| transportType == TransportType.MINECART
|| transportType == TransportType.MAGIC_CARPET;
|| transportType == TransportType.MAGIC_CARPET
|| transportType == TransportType.TRANSPORT;
}

private static int getCurrencyItemId(String currencyName) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Origin Destination Bidirectional Display info
# Static collision edge overrides for map data gaps. These block movement across the edge, not the whole tile.
3267 3227 0 3268 3227 0 true Al Kharid toll gate
3267 3228 0 3268 3228 0 true Al Kharid toll gate
3229 3472 0 3229 3471 0 true Varrock Palace garden south fence
3230 3472 0 3230 3471 0 true Varrock Palace garden south fence
3231 3472 0 3231 3471 0 true Varrock Palace garden south fence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@
3207 3217 0 Recipe for Disaster
3213 3222 0 Recipe for Disaster
3213 3221 0 Recipe for Disaster
# Al Kharid Gate
3267 3228 0 Prince Ali Rescue
3267 3227 0 Prince Ali Rescue
3268 3227 0 Prince Ali Rescue
3268 3228 0 Prince Ali Rescue
# Al Kharid toll gate is modeled as transports plus blocked edge overrides.
2936 9810 0 63 Agility
# Tree near Draynor Manor
3138 3352 0
Expand Down Expand Up @@ -236,4 +232,4 @@
2432 3118 0
2431 3118 0
2385 3068 0
2385 3069 0
2385 3069 0
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,14 @@
3097 3432 2 3097 3432 1 Climb-down;Ladder;16685

# Al Kharid
3267 3227 0 3268 3227 0 Pay-toll(10gp);Gate;2786 10 Coins 2
3267 3228 0 3268 3228 0 Pay-toll(10gp);Gate;2787 10 Coins 2
3268 3227 0 3267 3227 0 Pay-toll(10gp);Gate;2788 10 Coins 2
3268 3228 0 3267 3228 0 Pay-toll(10gp);Gate;2789 10 Coins 2
3267 3227 0 3268 3227 0 Open;Gate;2786 Prince Ali Rescue 1
3267 3228 0 3268 3228 0 Open;Gate;2787 Prince Ali Rescue 1
3268 3227 0 3267 3227 0 Open;Gate;2788 Prince Ali Rescue 1
3268 3228 0 3267 3228 0 Open;Gate;2789 Prince Ali Rescue 1
3298 3124 0 3297 3124 0 Open;Prison door;2692
3297 3124 0 3298 3124 0 Open;Prison door;2692
3303 3117 0 3304 3115 0 Go-through;Shantay pass;4031 1854 2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.runelite.client.plugins.microbot.shortestpath;

import net.runelite.api.Quest;
import net.runelite.api.VarPlayer;
import net.runelite.api.coords.WorldArea;
import net.runelite.api.coords.WorldPoint;
Expand All @@ -14,6 +15,10 @@
public class ShortestPathCoreTest {

private static SplitFlagMap collisionMap;
private static final WorldPoint AL_KHARID_GATE_WEST_SOUTH = new WorldPoint(3267, 3227, 0);
private static final WorldPoint AL_KHARID_GATE_WEST_NORTH = new WorldPoint(3267, 3228, 0);
private static final WorldPoint AL_KHARID_GATE_EAST_SOUTH = new WorldPoint(3268, 3227, 0);
private static final WorldPoint AL_KHARID_GATE_EAST_NORTH = new WorldPoint(3268, 3228, 0);

@BeforeClass
public static void loadCollisionMap() {
Expand Down Expand Up @@ -193,6 +198,52 @@ public void testTransportLoadingDoesNotThrow() {
assertTrue("Should load at least 100 transport origins", transports.size() > 100);
}

@Test
public void testAlKharidTollGateTransportsLoaded() {
HashMap<WorldPoint, Set<Transport>> transports = Transport.loadAllFromResources();

assertTollGateTransport(transports, AL_KHARID_GATE_WEST_SOUTH, AL_KHARID_GATE_EAST_SOUTH,
"Pay-toll(10gp)", 10, false);
assertTollGateTransport(transports, AL_KHARID_GATE_WEST_NORTH, AL_KHARID_GATE_EAST_NORTH,
"Pay-toll(10gp)", 10, false);
assertTollGateTransport(transports, AL_KHARID_GATE_EAST_SOUTH, AL_KHARID_GATE_WEST_SOUTH,
"Pay-toll(10gp)", 10, false);
assertTollGateTransport(transports, AL_KHARID_GATE_EAST_NORTH, AL_KHARID_GATE_WEST_NORTH,
"Pay-toll(10gp)", 10, false);

assertTollGateTransport(transports, AL_KHARID_GATE_WEST_SOUTH, AL_KHARID_GATE_EAST_SOUTH,
"Open", 0, true);
assertTollGateTransport(transports, AL_KHARID_GATE_WEST_NORTH, AL_KHARID_GATE_EAST_NORTH,
"Open", 0, true);
assertTollGateTransport(transports, AL_KHARID_GATE_EAST_SOUTH, AL_KHARID_GATE_WEST_SOUTH,
"Open", 0, true);
assertTollGateTransport(transports, AL_KHARID_GATE_EAST_NORTH, AL_KHARID_GATE_WEST_NORTH,
"Open", 0, true);
}

@Test
public void testAlKharidTollGateIsEdgeBlockedNotTileRestricted() {
Set<Integer> gateTiles = new HashSet<>(Arrays.asList(
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_WEST_SOUTH),
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_WEST_NORTH),
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_EAST_SOUTH),
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_EAST_NORTH)));

List<Restriction> restrictions = Restriction.loadAllFromResources();
assertFalse("Al Kharid gate tiles must not be quest-only restrictions",
restrictions.stream().anyMatch(r -> gateTiles.contains(r.getPackedWorldPoint())));

PathfinderConfig config = createMinimalConfig();
assertTrue("South Al Kharid gate edge should be blocked without transport",
config.isBlockedTransportStep(
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_WEST_SOUTH),
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_EAST_SOUTH)));
assertTrue("North Al Kharid gate edge should be blocked without transport",
config.isBlockedTransportStep(
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_WEST_NORTH),
WorldPointUtil.packWorldPoint(AL_KHARID_GATE_EAST_NORTH)));
}

@Test
public void testNewTransportTypesLoaded() {
HashMap<WorldPoint, Set<Transport>> transports = Transport.loadAllFromResources();
Expand Down Expand Up @@ -259,6 +310,27 @@ && new WorldPoint(3221, 3218, 0).equals(t.getDestination()))
return lumbridgeHomeTeleport.get();
}

private static void assertTollGateTransport(HashMap<WorldPoint, Set<Transport>> transports,
WorldPoint origin, WorldPoint destination, String action, int currencyAmount, boolean princeAliRequired) {
Optional<Transport> match = transports.getOrDefault(origin, Collections.emptySet()).stream()
.filter(t -> destination.equals(t.getDestination()))
.filter(t -> action.equals(t.getAction()))
.filter(t -> "Gate".equals(t.getName()))
.findFirst();

assertTrue("Missing Al Kharid toll gate transport " + action + " from " + origin + " to " + destination,
match.isPresent());
Transport transport = match.get();
assertEquals("Gate transport should use normal TRANSPORT type",
TransportType.TRANSPORT, transport.getType());
assertEquals("Unexpected gate currency amount", currencyAmount, transport.getCurrencyAmount());
if (currencyAmount > 0) {
assertEquals("Unexpected gate currency name", "Coins", transport.getCurrencyName());
}
assertEquals("Unexpected Prince Ali Rescue requirement on gate transport",
princeAliRequired, transport.getQuests().containsKey(Quest.PRINCE_ALI_RESCUE));
}

@Test
public void testFairyRingTransportsExist() {
HashMap<WorldPoint, Set<Transport>> transports = Transport.loadAllFromResources();
Expand Down
Loading
Loading