From 444f06e852f58a00f714b0f28a4bf2acd50bcfac Mon Sep 17 00:00:00 2001 From: infuse21 Date: Sat, 18 Jul 2026 12:39:16 +0100 Subject: [PATCH 01/48] ## Summary - Defers off-path recalculation while the player is still moving, animating, interacting, settling after doors/transports, or making recent route/interim progress. - Reworks route minimap clicks and unreachable-tile recovery to stay anchored to the planned raw path, use Euclidean minimap reach, and avoid backtracking to earlier nearby path branches. - Adds sticky interim checkpoint tracking so recovery/continuation clicks are not spammed while valid movement is already in flight. - Tightens door handling by deferring door probes while moving and only blacklisting wrong-traversal doors when the player started near the attempted door edge. - Improves charter ship destination widget lookup/clicking and optional confirmation handling. --- docs/entity-guides/movement.md | 32 +- .../shortestpath/ShortestPathPlugin.java | 2 +- .../pathfinder/PathfinderConfig.java | 2 +- .../microbot/util/walker/Rs2Walker.java | 1337 ++++++++++++++--- .../microbot/util/walker/WebWalkLog.java | 21 +- .../util/walker/Rs2WalkerUnitTest.java | 284 +++- 6 files changed, 1457 insertions(+), 221 deletions(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 4a658235f4..2ed25f0c5d 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -77,6 +77,8 @@ waitForDoorInteractionProgress(fromWp, toWp); **Defensive check:** In live testing, a door should produce one interaction followed by movement/path progress, not repeated `Raw path door handler resolved obstacle` messages every tick while the player is moving. +If a previous minimap click is still moving the player, do not attribute that movement to a new gate interaction. A valid gate can be blacklisted when the walker clicks an interim waypoint, notices the gate while movement is still in flight, then compares the pre/post positions from the old minimap movement against the gate edge. Wrong-traversal blacklisting should only run when the player started near the attempted door edge. + ## 5. Suppress the inverse adjacent transport after crossing a same-plane door Some doors are represented in `transports.tsv` as two adjacent same-plane transports, one for each direction. After the walker clicks one side and arrives on the other, immediately accepting the inverse transport can bounce the player back through the same door instead of letting the next minimap step continue away from it. Mark both tiles of a successful adjacent same-plane transport as recently handled for a short window. @@ -286,12 +288,38 @@ if (isStuckTooLong()) { After a handled transport, avoid expensive path-adjacent or raw transport scans on ordinary open-ground segments unless a nearby planned transport or recent door attempt exists. Those scans are recovery tools, and on long outdoor routes a no-op scan can add several seconds before the next minimap click. -For long-route minimap walking, let the next checkpoint selection happen before the current minimap target is fully consumed. Waiting until the player is only a few tiles from the interim makes the walker visibly stop before issuing the next click; handing off at a moderate remaining distance keeps movement continuous without rapid re-clicking. If an interim clears as close and no nearby route door/transport is pending, issue the next route-aligned continuation click immediately instead of waiting for idle-nudge recovery. +For long-route minimap walking, let the next checkpoint selection happen before the current minimap target is fully consumed. Waiting until the player is only a few tiles from the interim makes the walker visibly stop before issuing the next click; handing off at a moderate remaining distance keeps movement continuous without rapid re-clicking. If an interim clears as close and no nearby route door/transport is pending, issue the next route-aligned continuation click immediately instead of waiting for idle-nudge recovery. Stale-progress checks must also count distance progress toward the actual interim checkpoint, not only smoothed path index progress; sparse smoothed paths can otherwise clear valid raw-path checkpoints as stale while the player is still walking toward them. + +Before the first movement click, only scan a small number of immediate route edges for doors or blockers. A door several segments ahead can be handled after the first minimap click moves the player toward it; spending startup time scanning every nearby raw segment creates a visible cold start. Continuation clicks that keep an active route moving should be tail-exempt like `interim-in-flight`; otherwise very long routes can exhaust `MAX_PROCESS_WALK_TAIL_ITERATIONS` while still making progress and trigger an unnecessary auto-retry. Sticky interim targets should also clear when route-index progress goes stale. If the player keeps moving but the closest path index does not advance for `INTERIM_PROGRESS_TIMEOUT_MS`, treat the checkpoint as stale and select a fresh route-aligned target instead of waiting for max-age expiry. -When a route-following minimap click is outside the minimap clip, fallback clicks must stay on the raw path. A generic "reachable tile closer to target" fallback can select a tile far away from the route in open areas, especially near the final destination. +When a route-following minimap click is outside the minimap clip, fallback clicks must stay on the raw path. This includes the "clicked but no movement yet" retry after a route click and route-backed direct short-walks near the final destination. A generic "reachable tile closer to target" fallback can select a tile far away from the route in open areas, especially near fences and the final destination. Raw fallback must be anchored from the stabilized route index, not a fresh nearest-raw-tile lookup, or the walker can snap backward to an already-travelled branch. For adjacent same-plane shortcuts, do not treat any movement away from the origin as success. Some shortcuts, such as stepping stones, can fail and place the player on a fallback tile; once the player is settled away from the expected destination, stop the landing wait and replan from the actual tile. + +## 14. Keep optimistic recovery clicks route-backed and paced + +Unreachable-tile recovery is a fallback for bounded reachability false negatives, not a license to pick an arbitrary minimap point. Recovery clicks should use the same route-backed raw-path fallback as normal route movement, then store the actual clicked target as the sticky interim checkpoint. After issuing the click, wait only for movement to start or the checkpoint/goal to be reached; do not wait for a full idle cycle before returning to the walk loop. + +**Why this matters:** Bounded local reachability can report a valid route tile as unreachable even though the server pathfinder can still walk toward it. Arbitrary or repeated recovery clicks can pull the player away from the planned route and create visible stop-start movement. + +**Pattern to follow:** + +```java +int reach = STALL_RECOVERY_MINIMAP_REACH_EUCLIDEAN; +WorldPoint clickTarget = clampToEuclideanRadius(playerLoc, recoverTarget, reach - 1); +WorldPoint clickedTarget = clickMiniMapOrFallback(rawPath, clickTarget, playerLoc, reach - 1, false, rawAnchorIndex); +if (clickedTarget != null) { + interimTargetWp = clickedTarget; + waitForMovementStartAfterRecovery(target, playerLoc, clickedTarget, target, finishThreshold); +} +``` + +**Where this applies:** `Rs2Walker.processWalk` unreachable-smoothed-tile recovery, route-backed direct short-walks, and any fallback that runs after local reachability says a route tile is not currently reachable. + +**Defensive check:** Exercise a long outdoor route and a route with gates or transports. Recovery logs should select route-backed points, and there should be no long idle pause between `unreachable optimistic recovery` and the next route-aligned movement. + +After recovery sets a sticky interim target, do not issue another optimistic recovery while that interim is still active and movement/progress is fresh. Yield as `interim-in-flight` or another tail-exempt movement state until the checkpoint is close, stale, or expired. Otherwise the walker can loop through several recovery clicks while the player is already moving, especially when local reachability reports the next smoothed tile as unreachable. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathPlugin.java index 6a62b53d07..3f4c1437d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathPlugin.java @@ -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; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java index 211e1fdeef..92855da1cd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java @@ -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}; }); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 2c760efe15..68df3dceea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -126,29 +126,38 @@ public static WorldPoint getCurrentTarget() { private static volatile long interimSetAtMs = 0L; private static volatile long interimLastProgressAtMs = 0L; private static volatile int interimLastBestPathIdx = -1; + private static volatile int interimLastDistanceToTarget = Integer.MAX_VALUE; private static volatile long interimLastRetargetAtMs = 0L; /** Cooldown so partial-segment in-transit {@link #recalculatePath()} does not spam. */ private static volatile long lastPartialTransRecalcMs = 0L; private static final long PARTIAL_TRANS_RECAL_COOLDOWN_MS = 3500L; - private static final int INTERIM_CLOSE_TILES = 4; + private static final int INTERIM_CLOSE_TILES = 5; private static final int INTERIM_PRECLICK_TILES = 6; - private static final int INTERIM_RUN_PRECLICK_TILES = 11; + private static final int INTERIM_RUN_PRECLICK_TILES = 8; private static final int INTERIM_MOVING_POLL_MS = 450; private static final long INTERIM_PROGRESS_TIMEOUT_MS = 2500L; private static final long INTERIM_MAX_AGE_MS = 10_000L; private static final long INTERIM_RETARGET_COOLDOWN_MS = 900L; + private static final long ROUTE_PROGRESS_STALL_GRACE_MS = 4_000L; + private static final long OFF_PATH_RECALC_RECENT_MOVEMENT_MS = 2_000L; + private static final long OFF_PATH_RECALC_ROUTE_PROGRESS_GRACE_MS = 3_500L; + private static final long OFF_PATH_RECALC_MINIMAP_CLICK_GRACE_MS = 2_500L; + private static final int OFF_PATH_RECALC_DEFER_WAIT_MIN_MS = 250; + private static final int OFF_PATH_RECALC_DEFER_WAIT_MAX_MS = 1_200; private static final long RAW_SCAN_DOOR_FOCUS_MAX_MS = 2200L; private static final int RAW_SCAN_DOOR_FOCUS_MAX_ATTEMPTS = 3; private static final long DOOR_POST_INTERACT_SETTLE_MS = 900L; private static final long DOOR_EDGE_SKIP_COOLDOWN_MS = 700L; - private static final long RECOVERY_MOVEMENT_IN_FLIGHT_MS = 1400L; + private static final long RECOVERY_MOVEMENT_IN_FLIGHT_MS = 3_500L; private static final long DOOR_TRAVERSAL_RECOVERY_BLOCK_MS = 2_200L; + private static final long POST_DOOR_NUDGE_RECENT_ATTEMPT_MS = 6_000L; private static final int PATHFINDER_DONE_POLL_WAIT_MS = 1200; private static final int PATHFINDER_DONE_RETRY_SLEEP_MIN_MS = 120; private static final int PATHFINDER_DONE_RETRY_SLEEP_MAX_MS = 220; private static final long STARTUP_FIRST_CLICK_BUDGET_MS = 2200L; + private static final int STARTUP_PRECLICK_DOOR_SCAN_LOOKAHEAD_EDGES = 2; private static final int POST_DOOR_FAST_CLICK_MAX_EUCLIDEAN = 13; private static final int POST_DOOR_EDGE_NUDGE_MAX_FROM_PLAYER = 3; private static final int POST_DOOR_EDGE_NUDGE_WAIT_MS = 1200; @@ -162,7 +171,7 @@ public static WorldPoint getCurrentTarget() { private static final int UNREACHABLE_DOOR_RECOVERY_BACKTRACK_EDGES = 2; private static final int UNREACHABLE_DOOR_RECOVERY_LOOKAHEAD_EDGES = 10; private static final int STALL_RECOVERY_MINIMAP_REACH_EUCLIDEAN = 10; - private static final int NORMAL_MINIMAP_REACH_EUCLIDEAN = 12; + private static final int NORMAL_MINIMAP_REACH_EUCLIDEAN = 11; private static final int UNREACHABLE_RECOVERY_FORWARD_SCAN_TILES = 24; private static final long ACTIVE_ROUTE_IDLE_NUDGE_MS = 2_500L; private static final long ACTIVE_ROUTE_IDLE_NUDGE_COOLDOWN_MS = 2_000L; @@ -196,6 +205,7 @@ public static WorldPoint getCurrentTarget() { private static volatile WorldPoint routeProgressPathStart = null; private static volatile WorldPoint routeProgressPathEnd = null; private static volatile int routeProgressPathSize = -1; + private static volatile long routeProgressAdvancedAtMs = 0L; private static final java.util.Deque expectedTransportDestinations = new ArrayDeque<>(); private static final Set startupPhasesLogged = ConcurrentHashMap.newKeySet(); @@ -314,6 +324,24 @@ private enum WalkerPhase { STEADY } + private static final class WalkLoopSnapshot { + private final WorldPoint playerLoc; + private final HashMap closestReachableTiles; + + private WalkLoopSnapshot(WorldPoint playerLoc) { + this.playerLoc = playerLoc; + this.closestReachableTiles = getClosestIndexReachableTiles(playerLoc); + } + + private static WalkLoopSnapshot capture() { + return new WalkLoopSnapshot(Rs2Player.getWorldLocation()); + } + + private int closestTileIndex(List path) { + return getClosestTileIndex(path, playerLoc, closestReachableTiles); + } + } + private interface ObstaclePolicy { long segmentDoorTimeoutMs(); long unreachableDoorTimeoutMs(); @@ -420,6 +448,21 @@ private static ObstaclePolicy obstaclePolicyForCurrentPhase() { : STEADY_OBSTACLE_POLICY; } + static boolean shouldSkipStartupPreclickSegmentHandlers(boolean startupBeforeFirstClick, + int segmentIdx, + int routeStartIdx, + boolean recentDoorAttemptNearSegment, + boolean doorSettling, + boolean recoveryInFlight) { + if (!startupBeforeFirstClick || routeStartIdx < 0 || segmentIdx < routeStartIdx) { + return false; + } + if (recentDoorAttemptNearSegment || doorSettling || recoveryInFlight) { + return false; + } + return segmentIdx > routeStartIdx + STARTUP_PRECLICK_DOOR_SCAN_LOOKAHEAD_EDGES; + } + /** * Same-plane Chebyshev distance from player to {@code dest} strictly less than {@code maxChebyshevExclusive}. * Requires matching {@link WorldPoint#getPlane()} before using {@link WorldPoint#distanceTo2D} — that method only @@ -491,6 +534,7 @@ private static int tightFinishThreshold(WorldPoint goal, WorldPoint pathLastWalk /** If phase 1 exits on arrival distance while still moving, wait briefly for idle-only (reduces tail churn). */ private static final int POST_SCENE_WALK_IDLE_SECOND_PHASE_MS_MAX = 4_000; + private static final int POST_RECOVERY_MOVEMENT_START_WAIT_MS = 1_200; private static void waitUntilIdleAfterSceneWalk(WorldPoint cancelGoal, int timeoutMs) { waitUntilIdleAfterSceneWalk(cancelGoal, timeoutMs, null, 0); @@ -749,6 +793,7 @@ public static List getSeasonalTransportHandlers() */ public static final class Telemetry { public static final AtomicInteger offPathRecalcCount = new AtomicInteger(); + public static final AtomicInteger offPathRecalcDeferredCount = new AtomicInteger(); public static final AtomicInteger stallRecalcCount = new AtomicInteger(); public static final AtomicInteger partialRetryCount = new AtomicInteger(); public static final AtomicInteger unreachableCount = new AtomicInteger(); @@ -766,6 +811,9 @@ public static final class Telemetry { private static final ConcurrentHashMap doorRejectByCause = new ConcurrentHashMap<>(); private static final AtomicInteger doorRejectSummaryLogSeq = new AtomicInteger(0); private static final int DOOR_REJECT_SUMMARY_LOG_INTERVAL = 40; + private static final ConcurrentHashMap offPathDeferredByReason = new ConcurrentHashMap<>(); + private static final AtomicInteger offPathDeferredSummaryLogSeq = new AtomicInteger(0); + private static final int OFF_PATH_DEFERRED_SUMMARY_LOG_INTERVAL = 20; /** * Rate-limited debug summary of {@link #doorRejectByCause} tallies (noise control on tight door clusters). @@ -805,6 +853,22 @@ public static void recordOffPathRecalc(WorldPoint playerPos, int pathSize) { playerPos, pathSize, offPathRecalcCount.get(), stallRecalcCount.get()); } + public static void recordOffPathRecalcDeferred(String reason, WorldPoint playerPos, + WorldPoint target, int pathSize) { + if (reason == null || reason.isEmpty()) { + reason = "unknown"; + } + offPathRecalcDeferredCount.incrementAndGet(); + offPathDeferredByReason.computeIfAbsent(reason, k -> new AtomicInteger()).incrementAndGet(); + lastReason = "off-path-deferred:" + reason; + lastEventAtMs.set(System.currentTimeMillis()); + if (Rs2LogRateLimit.everyN(offPathDeferredSummaryLogSeq, OFF_PATH_DEFERRED_SUMMARY_LOG_INTERVAL) + && log.isDebugEnabled()) { + log.debug("[WalkerTelemetry] OFFPATH_RECALC_DEFERRED player={} target={} pathSize={} summary={}", + playerPos, target, pathSize, offPathDeferredByReason); + } + } + public static void recordStallRecalc(long sinceMovedMs, WorldPoint playerPos) { stallRecalcCount.incrementAndGet(); lastReason = "stall"; @@ -836,6 +900,7 @@ public static void recordUnreachable(String cause, WorldPoint player, WorldPoint public static void reset() { offPathRecalcCount.set(0); + offPathRecalcDeferredCount.set(0); stallRecalcCount.set(0); partialRetryCount.set(0); unreachableCount.set(0); @@ -845,6 +910,8 @@ public static void reset() { seasonalHandlerMissCount.set(0); doorRejectByCause.clear(); doorRejectSummaryLogSeq.set(0); + offPathDeferredByReason.clear(); + offPathDeferredSummaryLogSeq.set(0); lastEventAtMs.set(0); lastReason = ""; log.info("[WalkerTelemetry] counters reset"); @@ -1054,6 +1121,7 @@ private static WalkerState walkWithStateInternal(WorldPoint target, int distance interimSetAtMs = 0L; interimLastProgressAtMs = 0L; interimLastBestPathIdx = -1; + interimLastDistanceToTarget = Integer.MAX_VALUE; interimLastRetargetAtMs = 0L; lastPartialTransRecalcMs = 0L; idleNudgeLastObservedLocation = playerLocWalk; @@ -1191,9 +1259,10 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part int rawSize = rawPath == null ? -1 : rawPath.size(); int walkSize = path == null ? -1 : path.size(); markStartupPhase("path_snapshot", target, "raw=" + rawSize + " walk=" + walkSize); + final WalkLoopSnapshot walkLoop = WalkLoopSnapshot.capture(); final WorldPoint dst; if (path == null || path.isEmpty()) { - dst = Rs2Player.getWorldLocation(); + dst = walkLoop.playerLoc; } else { dst = path.get(path.size()-1); } @@ -1204,7 +1273,7 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part WebWalkLog.partialSegment(dst, dst.distanceTo(target), target, path.size()); partialPath = true; } else { - Telemetry.recordUnreachable("no-walkable-path", Rs2Player.getWorldLocation(), + Telemetry.recordUnreachable("no-walkable-path", walkLoop.playerLoc, target, dst, path == null ? 0 : path.size(), distance, pathfinder); setTarget(null, "rs2walker:processWalk:no-walkable-path"); return WalkerState.UNREACHABLE; @@ -1218,11 +1287,11 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part // Partial segment: before standing on the segment endpoint, refresh routing from current // position so the continuation is ready (smooth handoff vs dead stop at segment end). if (partialPath) { - WorldPoint playerPt = Rs2Player.getWorldLocation(); + WorldPoint playerPt = walkLoop.playerLoc; if (playerPt != null && dst != null) { int distToDstSeg = playerPt.distanceTo2D(dst); int distToGoal = playerPt.distanceTo2D(target); - int closestEarly = getClosestTileIndex(path); + int closestEarly = walkLoop.closestTileIndex(path); int remainingSteps = closestEarly >= 0 ? (path.size() - 1 - closestEarly) : Integer.MAX_VALUE; final int nearSegmentEndTiles = 12; final int nearSegmentEndSteps = 10; @@ -1316,13 +1385,13 @@ && tryIssueRouteRecoveryClick(rawPath, path, target, "active route idle nudge")) } } - WorldPoint playerLocForIndex = Rs2Player.getWorldLocation(); - int indexOfStartPoint = stabilizeRouteProgressIndex(path, getClosestTileIndex(path), target, playerLocForIndex); + WorldPoint playerLocForIndex = walkLoop.playerLoc; + int indexOfStartPoint = stabilizeRouteProgressIndex(path, walkLoop.closestTileIndex(path), target, playerLocForIndex); indexOfStartPoint = advanceIndexPastRecentTransportEdge(path, indexOfStartPoint, playerLocForIndex); if (indexOfStartPoint == -1) { walkerDiag("getClosestTileIndex=-1 pathSize=%d player=%s pathFirst=%s pathLast=%s", path.size(), - Rs2Player.getWorldLocation(), + playerLocForIndex, path.isEmpty() ? null : path.get(0), path.isEmpty() ? null : path.get(path.size() - 1)); traceProcessWalkExit("closest-index-none", target, processWalkTail); @@ -1331,7 +1400,7 @@ && tryIssueRouteRecoveryClick(rawPath, path, target, "active route idle nudge")) } primeExpectedTransportDestinations(path, indexOfStartPoint); - lastPosition = Rs2Player.getWorldLocation(); + lastPosition = playerLocForIndex; boolean clearedInterimTarget = clearInterimTargetIfReachedOrExpired(lastPosition, path, System.currentTimeMillis()); WorldPoint plImmediate = lastPosition; @@ -1489,21 +1558,21 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { "nearPath=false variance=" + nearPathByVariance); } if (!nearPath && !recentTransportWindow && !nearPathByVariance) { - // Avoid mid-walk recalculation while the player is still moving. recalculatePath() - // cancels the pathfinder and waits up to 10s for a new one — a visible stall. - // isStuckTooLong() will trigger a real recalculation if progress actually halts. - boolean movingOrRecentlyMoved = Rs2Player.isMoving() - || (lastMovedTimeMs > 0 && System.currentTimeMillis() - lastMovedTimeMs < 2000); - if (movingOrRecentlyMoved) { + // Avoid mid-walk recalculation while recent clicks, route progress, or busy state + // indicate the player may still be advancing. isStuckTooLong() will trigger a + // real recovery path once progress actually halts. + String deferReason = currentOffPathRecalcDeferralReason(lastAttemptedMinimapClickAtMs); + if (deferReason != null) { + Telemetry.recordOffPathRecalcDeferred(deferReason, playerForPathCheck, target, path.size()); if (lastTransportHandledAtMs > 0 && System.currentTimeMillis() - lastTransportHandledAtMs <= POST_TRANSPORT_PATH_TMARK_WINDOW_MS) { WebWalkLog.tmark("post_transport_offpath_moving_yield", System.currentTimeMillis() - lastTransportHandledAtMs, target, playerForPathCheck, - "movingRecent=true"); + "defer=" + deferReason); } - exitReason = "off-path-but-moving"; + exitReason = "off-path-deferred:" + deferReason; break; } Telemetry.recordOffPathRecalc(Rs2Player.getWorldLocation(), path.size()); @@ -1543,15 +1612,28 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { && !isDoorInteractionSettling() && !isRecoveryMovementInFlight() && reachableTilesCache.containsKey(currentWorldPoint); - if (skipPostTransportSegmentHandlers) { + boolean skipStartupPreclickSegmentHandlers = shouldSkipStartupPreclickSegmentHandlers( + currentWalkerPhase() == WalkerPhase.STARTUP, + i, + indexOfStartPoint, + recentDoorAttemptNearSegment, + isDoorInteractionSettling(), + isRecoveryMovementInFlight()); + if (skipPostTransportSegmentHandlers || skipStartupPreclickSegmentHandlers) { + if (skipStartupPreclickSegmentHandlers) { + markStartupPhase("preclick_segment_handler_skip", target, + "i=" + i + " reason=startup_preclick_budget"); + } tmarkPostTransport("post_transport_segment_handler_skip", target, - "i=" + i + " reason=no_nearby_planned_transport"); + "i=" + i + " reason=" + (skipPostTransportSegmentHandlers + ? "no_nearby_planned_transport" + : "startup_preclick_budget")); } else { long segmentHandlerStartAt = System.currentTimeMillis(); int rawI = (i < smoothedToRaw.length) ? smoothedToRaw[i] : 0; int rawEnd = rawEndForSmoothedIndex(i, smoothedToRaw, rawPath, path); - if (!isDoorInteractionSettling() && !isRecoveryMovementInFlight()) { + if (!Rs2Player.isMoving() && !isDoorInteractionSettling() && !isRecoveryMovementInFlight()) { doorOrTransportResult = handleDoorsInRawSegment(rawPath, rawI, rawEnd, obstaclePolicy.segmentDoorTimeoutMs(), doorEdgesAttemptedThisTail, reachableTilesCache); @@ -1677,6 +1759,14 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { exitReason = "door-traversal-pending-yield"; break; } + if (shouldYieldForActiveRecoveryInterim(playerLoc, path, System.currentTimeMillis())) { + exitReason = "interim-in-flight"; + break; + } + if (tryRecentDoorAttemptEdgeNudge(playerLoc, target)) { + exitReason = "recent-door-edge-nudge"; + break; + } if (handlePendingDoorNearRawPath(rawPath, obstaclePolicy.unreachableDoorTimeoutMs(), doorEdgesAttemptedThisTail, playerLoc, 2, 14)) { exitReason = "door-handled-unreachable-raw-scan"; @@ -1697,6 +1787,17 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { UNREACHABLE_DOOR_RECOVERY_BACKTRACK_EDGES, UNREACHABLE_DOOR_RECOVERY_LOOKAHEAD_EDGES, HANDLER_RANGE); + if (!gateDoorInteraction + && unresolvedDoorNearRawPath + && handleUnresolvedDoorNearRawPath(rawPath, rawEdgeStart, + obstaclePolicy.unreachableDoorTimeoutMs(), doorEdgesAttemptedThisTail, + playerLoc, + UNREACHABLE_DOOR_RECOVERY_BACKTRACK_EDGES, + UNREACHABLE_DOOR_RECOVERY_LOOKAHEAD_EDGES, + HANDLER_RANGE)) { + exitReason = "door-handled-nearby-route-door"; + break; + } // Fallback: only interact with objects on/adjacent to blocked path edges // within ~15 tiles. Prevents clicking already-open / unrelated doors. final long nowMs = System.currentTimeMillis(); @@ -1726,27 +1827,27 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { // like a human clicking the furthest visible tile. We trust the server path // (no reachability gate on the click); isKnownWalkableOrUnloaded only keeps // us from clicking into a known wall, it is NOT the bounded BFS check. - final int RECOVERY_MINIMAP_REACH_EUCLIDEAN = 13; + final int recoveryMinimapReach = STALL_RECOVERY_MINIMAP_REACH_EUCLIDEAN; int recoverIdx = findForwardReachableRecoveryIndex(path, i, playerLoc, - RECOVERY_MINIMAP_REACH_EUCLIDEAN); + recoveryMinimapReach); if (recoverIdx < 0) { recoverIdx = findFurthestClickableIndex(path, i, playerLoc, wp -> { Set ts = ShortestPathPlugin.getTransports().get(wp); return ts != null && !ts.isEmpty(); }, - RECOVERY_MINIMAP_REACH_EUCLIDEAN); + recoveryMinimapReach); } int minRecoveryIdx = Math.max(indexOfStartPoint, i); recoverIdx = Math.min(Math.max(recoverIdx, minRecoveryIdx), path.size() - 1); WorldPoint recoverTarget = path.get(recoverIdx); if (euclideanSq(recoverTarget, playerLoc) - > RECOVERY_MINIMAP_REACH_EUCLIDEAN * RECOVERY_MINIMAP_REACH_EUCLIDEAN) { + > recoveryMinimapReach * recoveryMinimapReach) { // Furthest in-range path tile still beyond the minimap clip (e.g. a // diagonal segment). Interpolate a point near the minimap edge toward // path[i]; the server routes through whatever blocks line-of-sight. recoverTarget = interpolateClickableTarget(path, i, playerLoc, - path.get(i), RECOVERY_MINIMAP_REACH_EUCLIDEAN - 1, + path.get(i), recoveryMinimapReach - 1, wp -> inInstance || isKnownWalkableOrUnloaded(wp)); } // Don't let recovery park the player on a tile next to an aggressive NPC @@ -1764,9 +1865,24 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { recoverIdx = safeIdx; recoverTarget = path.get(safeIdx); } - boolean clicked = recoverTarget != null - && !recoverTarget.equals(playerLoc) - && Rs2Walker.walkMiniMap(recoverTarget); + int rawAnchorIndex = rawIndexForSmoothedIndex(recoverIdx, smoothedToRaw, rawPath); + WorldPoint rawRecoveryTarget = findFurthestReachableRawPathPoint(rawPath, playerLoc, + recoveryMinimapReach - 1, rawAnchorIndex); + if (rawRecoveryTarget != null + && !rawRecoveryTarget.equals(playerLoc) + && (dangerCfg == null + || !dangerCfg.isAvoidDangerousNpcs() + || !dangerCfg.isDangerousAdjacentTile(WorldPointUtil.packWorldPoint(rawRecoveryTarget)))) { + recoverTarget = rawRecoveryTarget; + } + WorldPoint clickedRecoveryTarget = null; + if (recoverTarget != null && !recoverTarget.equals(playerLoc)) { + recoverTarget = clampToEuclideanRadius(playerLoc, recoverTarget, + recoveryMinimapReach - 1); + clickedRecoveryTarget = clickMiniMapOrFallback(rawPath, recoverTarget, playerLoc, + recoveryMinimapReach - 1, rawPath == null || rawPath.isEmpty(), rawAnchorIndex); + } + boolean clicked = clickedRecoveryTarget != null; // Scene-click fallback only on final-adjacent approach (minimap click may // miss the clip when very close); kept gated on reachability since it is a // last resort, not the primary recovery path. @@ -1777,23 +1893,28 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { && Rs2Tile.isTileReachable(recoverTarget) && walkFastCanvas(recoverTarget)) { clicked = true; + clickedRecoveryTarget = recoverTarget; log.debug("[Walker] unreachable recovery: scene click -> {}", recoverTarget); } log.info("[Walker] unreachable optimistic recovery: clicked={} to={} pathTile={} idx={}", - clicked, recoverTarget, currentWorldPoint, recoverIdx); + clicked, clicked ? clickedRecoveryTarget : recoverTarget, currentWorldPoint, recoverIdx); if (clicked) { markFirstMovementClick("first_recovery_click", target, playerLoc, - "to=" + compactWorldPoint(recoverTarget)); + "to=" + compactWorldPoint(clickedRecoveryTarget)); lastUnreachableRecoveryClickAtMs = System.currentTimeMillis(); // Sticky interim: subsequent iterations travel toward this point via the // interim-in-flight path instead of re-running the (false-negative) // reachability check and re-clicking every tick. - interimTargetWp = recoverTarget; + interimTargetWp = clickedRecoveryTarget; interimTargetIdx = recoverIdx; interimSetAtMs = System.currentTimeMillis(); + interimLastProgressAtMs = interimSetAtMs; + interimLastBestPathIdx = getClosestTileIndex(path, playerLoc); + interimLastDistanceToTarget = distanceToInterimOrMax(clickedRecoveryTarget, playerLoc); + interimLastRetargetAtMs = interimSetAtMs; WorldPoint pathLastRecovery = path.get(path.size() - 1); int finishThRecovery = tightFinishThreshold(target, pathLastRecovery, distance); - waitUntilIdleAfterSceneWalk(target, POST_SCENE_WALK_IDLE_WAIT_MS_MAX, target, + waitForMovementStartAfterRecovery(target, playerLoc, clickedRecoveryTarget, target, finishThRecovery); // Next outer iteration runs checkIfStuck/isStuckTooLong before tile delta — avoid // spurious stall-recalc right after issuing recovery movement. @@ -1826,8 +1947,8 @@ && walkFastCanvas(recoverTarget)) { // Minimap clickable area is a circle, so reach is a Euclidean radius — // cardinal tiles reach ~13, diagonals ~9. Empirically 14 was too // optimistic (clicks at 13.5–13.9 Euclidean missed the clip). - final int MINIMAP_REACH_EUCLIDEAN = NORMAL_MINIMAP_REACH_EUCLIDEAN; WorldPoint playerLoc = Rs2Player.getWorldLocation(); + final int MINIMAP_REACH_EUCLIDEAN = NORMAL_MINIMAP_REACH_EUCLIDEAN; // Checkpoint-style walking: once we set a minimap flag, let the player actually // travel toward it. Do not keep recalculating/clicking new targets mid-run. @@ -1848,6 +1969,7 @@ && walkFastCanvas(recoverTarget)) { interimSetAtMs = 0L; interimLastProgressAtMs = 0L; interimLastBestPathIdx = -1; + interimLastDistanceToTarget = Integer.MAX_VALUE; interimLastRetargetAtMs = 0L; doorOrTransportResult = true; exitReason = "door-handled-during-interim"; @@ -1859,17 +1981,20 @@ && walkFastCanvas(recoverTarget)) { || !Rs2Player.isMoving(), INTERIM_MOVING_POLL_MS); WorldPoint posAfterWait = Rs2Player.getWorldLocation(); + recordInterimDistanceProgress(interimFinal, posAfterWait, System.currentTimeMillis()); if ((posAfterWait != null && posBeforeWait.distanceTo2D(posAfterWait) > 0) || Rs2Player.isMoving()) { lastMovedTimeMs = System.currentTimeMillis(); stuckCount = 0; } - boolean readyForNextClick = posAfterWait != null - && interimFinal.distanceTo2D(posAfterWait) <= interimPreclickTiles(); - if (!readyForNextClick && Rs2Player.isMoving()) { + boolean closeEnoughForNextClick = posAfterWait != null + && interimFinal.distanceTo2D(posAfterWait) <= INTERIM_CLOSE_TILES; + if (!closeEnoughForNextClick && Rs2Player.isMoving()) { exitReason = "interim-in-flight"; walkerDiag("interim-in-flight interim=%s interimDist=%d player=%s moving=true", - interimFinal, interimDist, playerLoc); + interimFinal, + posAfterWait == null ? interimDist : interimFinal.distanceTo2D(posAfterWait), + posAfterWait == null ? playerLoc : posAfterWait); break; } } else { @@ -1881,6 +2006,7 @@ && walkFastCanvas(recoverTarget)) { interimSetAtMs = 0L; interimLastProgressAtMs = 0L; interimLastBestPathIdx = -1; + interimLastDistanceToTarget = Integer.MAX_VALUE; interimLastRetargetAtMs = 0L; } } @@ -1890,34 +2016,21 @@ && walkFastCanvas(recoverTarget)) { interimSetAtMs = 0L; interimLastProgressAtMs = 0L; interimLastBestPathIdx = -1; + interimLastDistanceToTarget = Integer.MAX_VALUE; interimLastRetargetAtMs = 0L; } - int targetIdx = findFurthestClickableIndex(path, i, playerLoc, + int targetIdx = findFurthestForwardClickableIndex(path, i, playerLoc, wp -> { Set ts = ShortestPathPlugin.getTransports().get(wp); return ts != null && !ts.isEmpty(); }, MINIMAP_REACH_EUCLIDEAN); WorldPoint targetWp = path.get(targetIdx); - // Forward waypoint out of minimap reach (e.g., diagonal PathSmoother - // segment at Chebyshev 10 = Euclidean 14.1). Backward-scan returns - // the previous in-reach waypoint, but clicking it walks backward or - // barely advances. Instead, interpolate a point close to the minimap - // edge toward the forward waypoint — the server's walk-here - // pathfinder routes through whatever is blocking line-of-sight - // (door, gate, diagonal offset). Each interpolated click covers - // ~12 tiles, matching a human clicking the furthest visible tile. - if (targetIdx < i) { - targetWp = interpolateClickableTarget( - path, - i, - playerLoc, - targetWp, - MINIMAP_REACH_EUCLIDEAN - 1, - wp -> inInstance || isKnownWalkableOrUnloaded(wp)); - targetIdx = Math.max(indexOfStartPoint, i - 1); - } else if (euclideanSq(targetWp, playerLoc) > MINIMAP_REACH_EUCLIDEAN * MINIMAP_REACH_EUCLIDEAN) { + // If the forward waypoint is outside minimap reach, interpolate a + // visible point in that direction instead of falling back to an + // earlier path tile. + if (euclideanSq(targetWp, playerLoc) > MINIMAP_REACH_EUCLIDEAN * MINIMAP_REACH_EUCLIDEAN) { targetWp = interpolateClickableTarget( path, i, @@ -1934,17 +2047,19 @@ && walkFastCanvas(recoverTarget)) { WorldPoint sticky = interimTargetWp; if (sticky != null && sticky.getPlane() == playerLoc.getPlane()) { int stickyDist = sticky.distanceTo2D(playerLoc); + recordInterimDistanceProgress(sticky, playerLoc, nowMs); if (stickyDist <= INTERIM_CLOSE_TILES || nowMs - interimSetAtMs > INTERIM_MAX_AGE_MS) { interimTargetWp = null; interimTargetIdx = -1; interimSetAtMs = 0L; interimLastProgressAtMs = 0L; interimLastBestPathIdx = -1; + interimLastDistanceToTarget = Integer.MAX_VALUE; interimLastRetargetAtMs = 0L; } else { // U-turn safe progress: track progress along the path index, not Euclidean // distance-to-target (which can increase on U-shaped routes). - int bestIdxNow = getClosestTileIndex(path); + int bestIdxNow = getClosestTileIndex(path, playerLoc); if (bestIdxNow > interimLastBestPathIdx) { interimLastBestPathIdx = bestIdxNow; interimLastProgressAtMs = nowMs; @@ -1969,10 +2084,11 @@ && walkFastCanvas(recoverTarget)) { WorldPoint posBefore = playerLoc; WorldPoint clickTarget = inInstance ? targetWp : getPointWithWallDistance(targetWp); - if (!inInstance && !Rs2Tile.isTileReachable(clickTarget)) { + if (!inInstance) { + int rawAnchorIndex = rawIndexForSmoothedIndex(i, smoothedToRaw, rawPath); WorldPoint rawReachableTarget = findFurthestReachableRawPathPoint(rawPath, playerLoc, - MINIMAP_REACH_EUCLIDEAN - 1); - if (rawReachableTarget != null) { + MINIMAP_REACH_EUCLIDEAN - 1, rawAnchorIndex); + if (!Rs2Tile.isTileReachable(clickTarget) && rawReachableTarget != null) { targetWp = rawReachableTarget; clickTarget = rawReachableTarget; } @@ -1984,6 +2100,7 @@ && walkFastCanvas(recoverTarget)) { exitReason = "door-handled-before-minimap-click"; break; } + clickTarget = clampToEuclideanRadius(playerLoc, clickTarget, MINIMAP_REACH_EUCLIDEAN - 1); long nowBeforeClick = System.currentTimeMillis(); if (lastTransportHandledAtMs > 0 && nowBeforeClick - lastTransportHandledAtMs <= POST_TRANSPORT_PATH_TMARK_WINDOW_MS) { @@ -1994,27 +2111,25 @@ && walkFastCanvas(recoverTarget)) { "to=" + compactWorldPoint(clickTarget)); } markStartupPhase("click_candidate_found", target, "to=" + compactWorldPoint(clickTarget)); - boolean clicked = Rs2Walker.walkMiniMap(clickTarget); - if (!clicked) { - clicked = walkRawPathMiniMapToward(rawPath, clickTarget, playerLoc, MINIMAP_REACH_EUCLIDEAN - 1); - if (!clicked && (rawPath == null || rawPath.isEmpty())) { - clicked = walkMiniMapToward(clickTarget, playerLoc, MINIMAP_REACH_EUCLIDEAN - 1); - } - } + int rawAnchorIndex = rawIndexForSmoothedIndex(i, smoothedToRaw, rawPath); + WorldPoint clickedTarget = clickMiniMapOrFallback(rawPath, clickTarget, playerLoc, + MINIMAP_REACH_EUCLIDEAN - 1, rawPath == null || rawPath.isEmpty(), rawAnchorIndex); + boolean clicked = clickedTarget != null; if (walkCancelledDiag(target, "processWalk:after-minimap-click", processWalkTail)) { return WalkerState.EXIT; } - lastAttemptedMinimapClick = targetWp; + lastAttemptedMinimapClick = clicked ? clickedTarget : clickTarget; lastAttemptedMinimapClickOk = clicked; lastAttemptedMinimapClickAtMs = nowMs; if (clicked) { markFirstMovementClick("first_minimap_click", target, posBefore, - "to=" + compactWorldPoint(clickTarget)); - interimTargetWp = targetWp; + "to=" + compactWorldPoint(clickedTarget)); + interimTargetWp = clickedTarget; interimTargetIdx = targetIdx; interimSetAtMs = nowMs; interimLastProgressAtMs = nowMs; - interimLastBestPathIdx = getClosestTileIndex(path); + interimLastBestPathIdx = getClosestTileIndex(path, posBefore); + interimLastDistanceToTarget = distanceToInterimOrMax(clickedTarget, posBefore); interimLastRetargetAtMs = nowMs; final WorldPoint b = targetWp; @@ -2037,8 +2152,23 @@ && walkFastCanvas(recoverTarget)) { return before.distanceTo2D(now) >= progressCap; }, 1200); WorldPoint afterClickWait = Rs2Player.getWorldLocation(); + boolean routeRetryClicked = false; + if (afterClickWait != null && afterClickWait.equals(before) && !Rs2Player.isMoving()) { + WorldPoint routeRetryTarget = clickMiniMapOrFallback(rawPath, b, before, + MINIMAP_REACH_EUCLIDEAN - 1, false, rawAnchorIndex); + if (routeRetryTarget != null) { + routeRetryClicked = true; + lastAttemptedMinimapClick = routeRetryTarget; + lastAttemptedMinimapClickOk = true; + lastAttemptedMinimapClickAtMs = System.currentTimeMillis(); + interimTargetWp = routeRetryTarget; + interimLastProgressAtMs = lastAttemptedMinimapClickAtMs; + interimLastDistanceToTarget = distanceToInterimOrMax(routeRetryTarget, before); + interimLastRetargetAtMs = lastAttemptedMinimapClickAtMs; + } + } if (afterClickWait != null && afterClickWait.equals(before) && !Rs2Player.isMoving() - && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { + && routeRetryClicked) { sleepUntil(() -> { if (isWalkCancelled(target)) return true; WorldPoint now = Rs2Player.getWorldLocation(); @@ -2079,6 +2209,7 @@ && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { interimSetAtMs = 0L; interimLastProgressAtMs = 0L; interimLastBestPathIdx = -1; + interimLastDistanceToTarget = Integer.MAX_VALUE; interimLastRetargetAtMs = 0L; sleepUntil(() -> isWalkCancelled(target) || !Rs2Player.isMoving(), 1200); if (walkCancelledDiag(target, "processWalk:after-click-failed-wait", processWalkTail)) { @@ -2124,8 +2255,8 @@ && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { } // Only do the final-tile canvas click if we iterated the whole path cleanly. - // Exiting because the player left the path ("off-path-but-moving"/"not-near-path") - // means the player is still walking somewhere else — don't clobber that destination. + // Exiting because the player left the path may still mean movement is active. + // so don't clobber that destination. if (!doorOrTransportResult && "end-of-path".equals(exitReason)) { if (walkCancelledDiag(target, "processWalk:before-final-canvas", processWalkTail)) { return WalkerState.EXIT; @@ -2148,7 +2279,16 @@ && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { if (Rs2Tile.isTileReachable(finalTile) && Rs2Player.getWorldLocation().distanceTo(finalTile) >= finishTh) { final WorldPoint canvasClickWp = finalTile; - if (Rs2Walker.walkFastCanvas(canvasClickWp)) { + WorldPoint finalPlayerLoc = Rs2Player.getWorldLocation(); + boolean finalClick; + if (rawPath != null && !rawPath.isEmpty() && finalPlayerLoc != null) { + int rawAnchorIndex = rawAnchorIndexForPathPosition(rawPath, path, finalPlayerLoc); + finalClick = clickRouteBackedShortWalk(rawPath, canvasClickWp, finalPlayerLoc, + NORMAL_MINIMAP_REACH_EUCLIDEAN - 1, rawAnchorIndex); + } else { + finalClick = Rs2Walker.walkFastCanvas(canvasClickWp); + } + if (finalClick) { waitUntilIdleAfterSceneWalk(target, POST_SCENE_WALK_IDLE_WAIT_MS_MAX, target, finishTh); if (walkCancelledDiag(target, "processWalk:after-final-canvas-wait", processWalkTail)) { return WalkerState.EXIT; @@ -2180,10 +2320,16 @@ && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { setTarget(null, "rs2walker:processWalk:partial-retries-exhausted"); return WalkerState.UNREACHABLE; } else { - if ("off-path-but-moving".equals(exitReason)) { - // Wait for the player to re-enter the path or to stop moving. Prevents a tight - // recursion loop that would spin on isNearPath() while the player is walking. - long offPathWaitMs = 2000L; + if (isOffPathRecalcDeferredExit(exitReason)) { + // Wait briefly for the player to re-enter the path or for the progress signal + // that deferred the recalc to expire. Prevents a tight loop around isNearPath(). + String deferReason = offPathDeferredReasonFromExit(exitReason); + long offPathWaitMs = offPathRecalcDeferredWaitMs(deferReason, + System.currentTimeMillis(), + lastMovedTimeMs, + routeProgressAdvancedAtMs, + lastAttemptedMinimapClickAtMs, + interimLastProgressAtMs); long now = System.currentTimeMillis(); if (lastTransportHandledAtMs > 0 && now - lastTransportHandledAtMs <= POST_TRANSPORT_PATH_TMARK_WINDOW_MS) { @@ -2196,6 +2342,7 @@ && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { } } if (offPathWaitMs > 0) { + final long deferredLastClickAtMs = lastAttemptedMinimapClickAtMs; if (lastTransportHandledAtMs > 0 && System.currentTimeMillis() - lastTransportHandledAtMs <= POST_TRANSPORT_PATH_TMARK_WINDOW_MS) { WebWalkLog.tmark("post_transport_offpath_sleep", @@ -2204,7 +2351,9 @@ && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { Rs2Player.getWorldLocation(), "ms=" + offPathWaitMs); } - sleepUntil(() -> isWalkCancelled(target) || isNearPath() || !Rs2Player.isMoving(), + sleepUntil(() -> isWalkCancelled(target) + || isNearPath() + || currentOffPathRecalcDeferralReason(deferredLastClickAtMs) == null, (int) offPathWaitMs); } if (walkCancelledDiag(target, "processWalk:after-off-path-wait", processWalkTail)) { @@ -2213,7 +2362,9 @@ && walkReachableMiniMapToward(b, before, MINIMAP_REACH_EUCLIDEAN - 1)) { } // Benign yields: outer for-loop increments processWalkTail each iteration; exempt so // long minimap interim waits cannot exhaust MAX_PROCESS_WALK_TAIL_ITERATIONS and EXIT. - if ("interim-in-flight".equals(exitReason) || "off-path-but-moving".equals(exitReason)) { + if ("interim-in-flight".equals(exitReason) + || "recovery-move-in-flight".equals(exitReason) + || isOffPathRecalcDeferredExit(exitReason)) { walkerDiag("tail exempt exitReason=%s tailBefore=%d", exitReason, processWalkTail); processWalkTail--; } @@ -2488,15 +2639,55 @@ private static boolean walkRawPathMiniMapToward(List rawPath, WorldPoint target, WorldPoint playerLoc, int maxEuclidean) { - WorldPoint fallback = findFurthestVisibleReachableRawPathPoint(rawPath, playerLoc, maxEuclidean); + return walkRawPathMiniMapTargetToward(rawPath, target, playerLoc, maxEuclidean, -1) != null; + } + + private static WorldPoint clickMiniMapOrFallback(List rawPath, + WorldPoint target, + WorldPoint playerLoc, + int maxEuclidean, + boolean allowDirectionalFallback) { + return clickMiniMapOrFallback(rawPath, target, playerLoc, maxEuclidean, allowDirectionalFallback, -1); + } + + private static WorldPoint clickMiniMapOrFallback(List rawPath, + WorldPoint target, + WorldPoint playerLoc, + int maxEuclidean, + boolean allowDirectionalFallback, + int rawAnchorIndex) { + if (target == null || playerLoc == null || target.equals(playerLoc)) { + return null; + } + if (walkMiniMap(target)) { + return target; + } + WorldPoint rawFallback = walkRawPathMiniMapTargetToward(rawPath, target, playerLoc, + maxEuclidean, rawAnchorIndex); + if (rawFallback != null) { + return rawFallback; + } + if (allowDirectionalFallback && walkMiniMapToward(target, playerLoc, maxEuclidean)) { + return target; + } + return null; + } + + private static WorldPoint walkRawPathMiniMapTargetToward(List rawPath, + WorldPoint target, + WorldPoint playerLoc, + int maxEuclidean, + int rawAnchorIndex) { + WorldPoint fallback = findFurthestVisibleReachableRawPathPoint(rawPath, playerLoc, + maxEuclidean, rawAnchorIndex); if (fallback == null || fallback.equals(playerLoc) || fallback.equals(target)) { - return false; + return null; } if (walkMiniMap(fallback)) { log.info("[Walker] Minimap click target {} was outside clip; used route fallback {}", target, fallback); - return true; + return fallback; } - return false; + return null; } static boolean walkMiniMapToward(WorldPoint target, WorldPoint playerLoc, int maxEuclidean) { @@ -2559,18 +2750,27 @@ && euclideanSq(tile, target) < currentDistance) .orElse(false); } - private static WorldPoint findFurthestReachableRawPathPoint(List rawPath, - WorldPoint playerLoc, - int maxEuclidean) { + static WorldPoint findFurthestReachableRawPathPoint(List rawPath, + WorldPoint playerLoc, + int maxEuclidean) { + return findFurthestReachableRawPathPoint(rawPath, playerLoc, maxEuclidean, -1); + } + + static WorldPoint findFurthestReachableRawPathPoint(List rawPath, + WorldPoint playerLoc, + int maxEuclidean, + int rawAnchorIndex) { if (rawPath == null || rawPath.isEmpty() || playerLoc == null) { return null; } - int closestRawIndex = getClosestTileIndex(rawPath); + int closestRawIndex = rawPathForwardAnchorIndex(rawPath, playerLoc, rawAnchorIndex); if (closestRawIndex < 0) { return null; } int maxSq = maxEuclidean * maxEuclidean; + int maxRouteSteps = maxEuclidean + 2; + int routeSteps = 0; Set reachable = Rs2Tile.getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean)).keySet(); WorldPoint best = null; for (int rawIndex = closestRawIndex; rawIndex < rawPath.size(); rawIndex++) { @@ -2578,6 +2778,13 @@ private static WorldPoint findFurthestReachableRawPathPoint(List raw if (candidate == null || candidate.getPlane() != playerLoc.getPlane()) { break; } + if (rawIndex > closestRawIndex) { + WorldPoint previous = rawPath.get(rawIndex - 1); + routeSteps += rawPathStepDistance(previous, candidate); + if (routeSteps > maxRouteSteps) { + break; + } + } if (euclideanSq(candidate, playerLoc) > maxSq) { break; } @@ -2588,18 +2795,27 @@ private static WorldPoint findFurthestReachableRawPathPoint(List raw return best; } - private static WorldPoint findFurthestVisibleReachableRawPathPoint(List rawPath, - WorldPoint playerLoc, - int maxEuclidean) { + static WorldPoint findFurthestVisibleReachableRawPathPoint(List rawPath, + WorldPoint playerLoc, + int maxEuclidean) { + return findFurthestVisibleReachableRawPathPoint(rawPath, playerLoc, maxEuclidean, -1); + } + + static WorldPoint findFurthestVisibleReachableRawPathPoint(List rawPath, + WorldPoint playerLoc, + int maxEuclidean, + int rawAnchorIndex) { if (rawPath == null || rawPath.isEmpty() || playerLoc == null) { return null; } - int closestRawIndex = getClosestTileIndex(rawPath); + int closestRawIndex = rawPathForwardAnchorIndex(rawPath, playerLoc, rawAnchorIndex); if (closestRawIndex < 0) { return null; } int maxSq = maxEuclidean * maxEuclidean; + int maxRouteSteps = maxEuclidean + 2; + int routeSteps = 0; Set reachable = Rs2Tile.getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean)).keySet(); WorldPoint best = null; for (int rawIndex = closestRawIndex; rawIndex < rawPath.size(); rawIndex++) { @@ -2607,6 +2823,13 @@ private static WorldPoint findFurthestVisibleReachableRawPathPoint(List closestRawIndex) { + WorldPoint previous = rawPath.get(rawIndex - 1); + routeSteps += rawPathStepDistance(previous, candidate); + if (routeSteps > maxRouteSteps) { + break; + } + } if (euclideanSq(candidate, playerLoc) > maxSq) { break; } @@ -2619,6 +2842,45 @@ && isMiniMapClickable(candidate, 5)) { return best; } + private static int rawPathStepDistance(WorldPoint previous, WorldPoint current) { + if (previous == null || current == null || previous.getPlane() != current.getPlane()) { + return Integer.MAX_VALUE / 4; + } + return Math.max(1, previous.distanceTo2D(current)); + } + + static int rawPathForwardAnchorIndex(List rawPath, WorldPoint playerLoc, int rawAnchorIndex) { + if (rawPath == null || rawPath.isEmpty() || playerLoc == null) { + return -1; + } + if (rawAnchorIndex < 0) { + return getClosestTileIndex(rawPath, playerLoc); + } + + int start = Math.max(0, Math.min(rawAnchorIndex, rawPath.size() - 1)); + int endExclusive = Math.min(rawPath.size(), start + ROUTE_PROGRESS_FORWARD_SEARCH_TILES + 1); + int bestIdx = -1; + int bestDist = Integer.MAX_VALUE; + for (int i = start; i < endExclusive; i++) { + WorldPoint point = rawPath.get(i); + if (point == null) { + continue; + } + if (point.getPlane() != playerLoc.getPlane()) { + break; + } + int dist = point.distanceTo2D(playerLoc); + if (dist < bestDist) { + bestIdx = i; + bestDist = dist; + if (dist == 0) { + break; + } + } + } + return bestIdx >= 0 ? bestIdx : start; + } + private static boolean shouldIssueActiveRouteIdleNudge() { WorldPoint playerLoc = Rs2Player.getWorldLocation(); long now = System.currentTimeMillis(); @@ -2658,7 +2920,7 @@ private static boolean tryIssueRouteContinuationClick(List rawPath, return false; } if (rawPath != null && !rawPath.isEmpty()) { - int rawIdx = getClosestTileIndex(rawPath); + int rawIdx = getClosestTileIndex(rawPath, playerLoc); if (rawIdx >= 0 && hasUnresolvedDoorLikeObjectNearRawPath(rawPath, rawIdx, playerLoc, @@ -2668,7 +2930,7 @@ private static boolean tryIssueRouteContinuationClick(List rawPath, return false; } } - int pathIdx = Math.max(0, getClosestTileIndex(path)); + int pathIdx = Math.max(0, getClosestTileIndex(path, playerLoc)); if (hasUpcomingNearbyTransportStep(path, pathIdx, playerLoc, POST_TRANSPORT_RAW_SCAN_TRANSPORT_LOOKAHEAD_EDGES, POST_TRANSPORT_RAW_SCAN_TRANSPORT_MAX_DIST)) { @@ -2688,15 +2950,18 @@ private static boolean tryIssueRouteMovementClick(List rawPath, if (playerLoc == null || path == null || path.isEmpty()) { return false; } + int targetIdx = stabilizeRouteProgressIndex(path, getClosestTileIndex(path, playerLoc), target, playerLoc); + int[] routeSmoothedToRaw = mapSmoothedToRaw(path, rawPath); + int rawAnchorIndex = rawIndexForSmoothedIndex(targetIdx, routeSmoothedToRaw, rawPath); WorldPoint clickTarget = findFurthestReachableRawPathPoint( rawPath, playerLoc, - maxEuclidean); - int targetIdx = getClosestTileIndex(path); + maxEuclidean, + rawAnchorIndex); if (clickTarget == null) { int startIdx = Math.max(0, targetIdx); - int clickableIdx = findFurthestClickableIndex(path, startIdx, playerLoc, + int clickableIdx = findFurthestForwardClickableIndex(path, startIdx, playerLoc, wp -> { Set ts = ShortestPathPlugin.getTransports().get(wp); return ts != null && !ts.isEmpty(); @@ -2718,28 +2983,34 @@ private static boolean tryIssueRouteMovementClick(List rawPath, } boolean clicked = false; + WorldPoint clickedTarget = null; if (clickTarget != null && !clickTarget.equals(playerLoc)) { - clicked = walkMiniMap(clickTarget) - || walkRawPathMiniMapToward(rawPath, clickTarget, playerLoc, maxEuclidean - 1); - if (!clicked && (rawPath == null || rawPath.isEmpty())) { - clicked = walkMiniMapToward(clickTarget, playerLoc, maxEuclidean - 1); - } + clickTarget = clampToEuclideanRadius(playerLoc, clickTarget, maxEuclidean - 1); + clickedTarget = clickMiniMapOrFallback(rawPath, clickTarget, playerLoc, + maxEuclidean - 1, rawPath == null || rawPath.isEmpty(), rawAnchorIndex); + clicked = clickedTarget != null; + } + if (clicked && "interim close route click".equals(logLabel)) { + log.debug("[Walker] {}: clicked={} to={} player={} idx={}", + logLabel, true, clickedTarget, playerLoc, targetIdx); + } else { + log.info("[Walker] {}: clicked={} to={} player={} idx={}", + logLabel, clicked, clicked ? clickedTarget : clickTarget, playerLoc, targetIdx); } - log.info("[Walker] {}: clicked={} to={} player={} idx={}", - logLabel, clicked, clickTarget, playerLoc, targetIdx); if (!clicked) { return false; } - markFirstMovementClick("stall recovery click".equals(logLabel) ? "stall_recovery_click" : "active_route_idle_nudge", + markFirstMovementClick(routeMovementClickPhase(logLabel), target, playerLoc, - "to=" + compactWorldPoint(clickTarget)); - interimTargetWp = clickTarget; + "to=" + compactWorldPoint(clickedTarget)); + interimTargetWp = clickedTarget; interimTargetIdx = targetIdx; interimSetAtMs = System.currentTimeMillis(); interimLastProgressAtMs = interimSetAtMs; - interimLastBestPathIdx = getClosestTileIndex(path); + interimLastBestPathIdx = getClosestTileIndex(path, playerLoc); + interimLastDistanceToTarget = distanceToInterimOrMax(clickedTarget, playerLoc); interimLastRetargetAtMs = interimSetAtMs; if (markRecoveryCooldown) { lastUnreachableRecoveryClickAtMs = interimSetAtMs; @@ -2755,6 +3026,19 @@ private static boolean tryIssueRouteMovementClick(List rawPath, return true; } + static String routeMovementClickPhase(String logLabel) { + if ("stall recovery click".equals(logLabel)) { + return "stall_recovery_click"; + } + if ("active route idle nudge".equals(logLabel)) { + return "active_route_idle_nudge"; + } + if ("interim close route click".equals(logLabel)) { + return "interim_close_route_click"; + } + return "route_movement_click"; + } + /** * Used in instances like vorkath, jad, nmz * @@ -2782,6 +3066,46 @@ public static boolean walkFastCanvas(WorldPoint worldPoint) { return walkFastCanvas(worldPoint, true); } + private static boolean walkFastCanvasOnScreenOnly(WorldPoint worldPoint, boolean toggleRun) { + LocalPoint localPoint = localPointForWorld(worldPoint); + if (localPoint == null || !Rs2Camera.isTileOnScreen(localPoint)) { + return false; + } + Point canvasPoint = Perspective.localToCanvas( + Microbot.getClient(), + localPoint, + Microbot.getClient().getTopLevelWorldView().getPlane()); + int canvasX = canvasPoint != null ? canvasPoint.getX() : -1; + int canvasY = canvasPoint != null ? canvasPoint.getY() : -1; + if (canvasX < 0 || canvasY < 0) { + return false; + } + + Rs2Player.toggleRunEnergy(toggleRun); + NewMenuEntry entry = new NewMenuEntry() + .param0(canvasX) + .param1(canvasY) + .type(MenuAction.WALK) + .identifier(0) + .itemId(0) + .option("Walk here"); + + Microbot.doInvoke(entry, + new Rectangle(canvasX, canvasY, Microbot.getClient().getCanvasWidth(), Microbot.getClient().getCanvasHeight())); + return true; + } + + private static LocalPoint localPointForWorld(WorldPoint worldPoint) { + if (worldPoint == null) { + return null; + } + LocalPoint localPoint = LocalPoint.fromWorld(Microbot.getClient().getTopLevelWorldView(), worldPoint); + if (Microbot.getClient().getTopLevelWorldView().isInstance() && localPoint == null) { + localPoint = Rs2LocalPoint.fromWorldInstance(worldPoint); + } + return localPoint; + } + public static boolean walkFastCanvas(WorldPoint worldPoint, boolean toggleRun) { if (worldPoint == null) { log.debug("[Walker] walkFastCanvas rejected: null worldPoint"); @@ -3086,32 +3410,38 @@ public static List getTransportsForPath(List path, int in */ public static List getTransportsForPath(List path, int indexOfStartPoint, TransportType prefTransportType, boolean applyFiltering) { List transportList = new ArrayList<>(); + if (path == null || path.isEmpty() || indexOfStartPoint < 0 || indexOfStartPoint >= path.size()) { + return transportList; + } + Map pathFirstIndex = buildPathFirstIndex(path); + WorldPoint playerLoc = Rs2Player.getWorldLocation(); int currentIndex = indexOfStartPoint; // Loop through the path until the end while (currentIndex < path.size()) { WorldPoint currentPoint = path.get(currentIndex); // Get any transports that start at this point (or keyed by this point) - Set transportsAtPoint = ShortestPathPlugin.getTransports() - .getOrDefault(currentPoint, new HashSet<>()); + Set transportsAtPoint = ShortestPathPlugin.getTransports().get(currentPoint); + if (transportsAtPoint == null || transportsAtPoint.isEmpty()) { + currentIndex++; + continue; + } boolean foundTransport = false; // sort by type to prioritize teleportation items first, then other types - transportsAtPoint = transportsAtPoint.stream() - .sorted(Comparator.comparing(Transport::getType, (type1, type2) -> { - // sort teleportation items by preference transport type for the current path point. - - if (type1 == prefTransportType && type2 != prefTransportType) { - return -1; - } - if (type2 == prefTransportType && type1 != prefTransportType) { - return 1; - } - // For all other types, use natural enum ordering - return type1.compareTo(type2); - })) - .collect(Collectors.toCollection(LinkedHashSet::new)); + List orderedTransports = new ArrayList<>(transportsAtPoint); + orderedTransports.sort(Comparator.comparing(Transport::getType, (type1, type2) -> { + // sort teleportation items by preference transport type for the current path point. + if (type1 == prefTransportType && type2 != prefTransportType) { + return -1; + } + if (type2 == prefTransportType && type1 != prefTransportType) { + return 1; + } + // For all other types, use natural enum ordering + return type1.compareTo(type2); + })); // Iterate over each available transport - for (Transport transport : transportsAtPoint) { + for (Transport transport : orderedTransports) { // Special handling for teleportation-like transports (originless) // NOTE: Leagues "Area" teleports are injected as SEASONAL_TRANSPORT with null origin. @@ -3125,8 +3455,8 @@ public static List getTransportsForPath(List path, int in || isLeaguesAreaTeleport) { // For teleportation, we assume origin is null and simply check if the destination exists in the path. - int destIndex = path.indexOf(transport.getDestination()); - if (destIndex != -1) { + Integer destIndex = pathFirstIndex.get(transport.getDestination()); + if (destIndex != null) { transportList.add(transport); // Advance the current index to the destination tile (or at least one forward) currentIndex = destIndex > currentIndex ? destIndex : currentIndex + 1; @@ -3146,19 +3476,20 @@ public static List getTransportsForPath(List path, int in for (WorldPoint origin : originPoints) { // If an origin is defined but the player's plane doesn't match, skip it. - WorldPoint plTransportFilter = Rs2Player.getWorldLocation(); - if (transport.getOrigin() != null && plTransportFilter != null - && plTransportFilter.getPlane() != transport.getOrigin().getPlane()) { + if (transport.getOrigin() != null && playerLoc != null + && playerLoc.getPlane() != transport.getOrigin().getPlane()) { continue; } // For non-teleportation transports, ensure both origin and destination exist in the path // and that the destination comes after the origin. - int indexOfDestination = path.indexOf(transport.getDestination()); + Integer indexOfDestinationValue = pathFirstIndex.get(transport.getDestination()); + int indexOfDestination = indexOfDestinationValue != null ? indexOfDestinationValue : -1; if (transport.getType() != TransportType.TELEPORTATION_ITEM && transport.getType() != TransportType.TELEPORTATION_SPELL && !isLeaguesAreaTeleport) { - int indexOfOrigin = path.indexOf(transport.getOrigin()); + Integer indexOfOriginValue = pathFirstIndex.get(transport.getOrigin()); + int indexOfOrigin = indexOfOriginValue != null ? indexOfOriginValue : -1; if (indexOfOrigin == -1 || indexOfDestination == -1 || indexOfDestination < indexOfOrigin) { continue; } @@ -3192,6 +3523,14 @@ public static List getTransportsForPath(List path, int in return transportList; } + private static Map buildPathFirstIndex(List path) { + Map pathFirstIndex = new HashMap<>(path.size()); + for (int i = 0; i < path.size(); i++) { + pathFirstIndex.putIfAbsent(path.get(i), i); + } + return pathFirstIndex; + } + /** * Applies transport filtering and requirement setup for transport items. * This method filters transports to only include those that require items and @@ -3347,7 +3686,6 @@ private static WalkerState tryDirectShortWalk(WorldPoint target, if (!inInstance && localRouteDetoursFromComputedRoute(rawPath, end, directClickMaxDistance)) { return WalkerState.MOVING; } - long suppressUntil = suppressTryDirectShortWalkUntilMs; if (suppressUntil != 0L && System.currentTimeMillis() < suppressUntil) { log.debug("[Walker] defer tryDirectShortWalk minimap (post door canvas nudge, {}ms window)", @@ -3355,12 +3693,20 @@ private static WalkerState tryDirectShortWalk(WorldPoint target, return WalkerState.MOVING; } - boolean clicked = walkMiniMap(end); - if (!clicked) { - clicked = walkMiniMapToward(end, playerLoc, directClickMaxDistance - 1); - } - if (!clicked) { - clicked = walkFastCanvas(end); + boolean routeBacked = rawPath != null && !rawPath.isEmpty(); + int rawAnchorIndex = routeBacked ? rawAnchorIndexForPathPosition(rawPath, path, playerLoc) : -1; + boolean clicked; + if (routeBacked) { + clicked = clickRouteBackedShortWalk(rawPath, end, playerLoc, + directClickMaxDistance - 1, rawAnchorIndex); + } else { + clicked = walkMiniMap(end); + if (!clicked) { + clicked = walkMiniMapToward(end, playerLoc, directClickMaxDistance - 1); + } + if (!clicked) { + clicked = walkFastCanvas(end); + } } if (!clicked) { return WalkerState.MOVING; @@ -3373,7 +3719,14 @@ private static WalkerState tryDirectShortWalk(WorldPoint target, }, 800); if (!moved) { - clicked = walkFastCanvas(end); + WorldPoint retryPlayerLoc = Rs2Player.getWorldLocation(); + if (routeBacked && retryPlayerLoc != null) { + int retryRawAnchorIndex = rawPathForwardAnchorIndex(rawPath, retryPlayerLoc, rawAnchorIndex); + clicked = clickRouteBackedShortWalk(rawPath, end, retryPlayerLoc, + directClickMaxDistance - 1, retryRawAnchorIndex); + } else { + clicked = walkFastCanvas(end); + } if (!clicked) { return WalkerState.MOVING; } @@ -3403,6 +3756,28 @@ private static WalkerState tryDirectShortWalk(WorldPoint target, return WalkerState.MOVING; } + private static int rawAnchorIndexForPathPosition(List rawPath, + List path, + WorldPoint playerLoc) { + int closestPathIdx = getClosestTileIndex(path, playerLoc); + int[] smoothedToRaw = mapSmoothedToRaw(path, rawPath); + int rawAnchorIndex = rawIndexForSmoothedIndex(closestPathIdx, smoothedToRaw, rawPath); + return rawPathForwardAnchorIndex(rawPath, playerLoc, rawAnchorIndex); + } + + private static boolean clickRouteBackedShortWalk(List rawPath, + WorldPoint end, + WorldPoint playerLoc, + int maxEuclidean, + int rawAnchorIndex) { + WorldPoint clickedTarget = clickMiniMapOrFallback(rawPath, end, playerLoc, + maxEuclidean, false, rawAnchorIndex); + if (clickedTarget != null) { + return true; + } + return walkFastCanvasOnScreenOnly(end, true); + } + private static boolean hasPendingExplicitTransportStepBeforeArrival(List path, WorldPoint target, int distance) { @@ -3441,7 +3816,7 @@ private static boolean localRouteDetoursFromComputedRoute(List rawPa return false; } - int rawStart = getClosestTileIndex(rawPath); + int rawStart = getClosestTileIndex(rawPath, playerLoc); if (rawStart < 0 || rawStart >= rawPath.size() - 1) { return false; } @@ -3481,7 +3856,7 @@ private static boolean hasPendingDoorLikeSceneObjectBeforeDirectClick(List= route.size()) { return false; } @@ -3524,6 +3899,9 @@ private static boolean handlePendingDoorBeforeRouteClick(List rawPat || playerLoc == null || targetPathIdx < fromPathIdx) { return false; } + if (Rs2Player.isMoving()) { + return false; + } int rawStart = rawIndexForSmoothedIndex(fromPathIdx, smoothedToRaw, rawPath); int rawTarget = rawIndexForSmoothedIndex(targetPathIdx, smoothedToRaw, rawPath); @@ -3564,7 +3942,7 @@ private static boolean handlePendingDoorDuringInterim(List rawPath, WorldPoint playerLoc) { if (rawPath == null || rawPath.size() < 2 || playerLoc == null || isDoorInteractionSettling() || isDoorEdgePassSkipCoolingDown() - || isRecoveryMovementInFlight()) { + || isRecoveryMovementInFlight() || Rs2Player.isMoving()) { return false; } @@ -3580,8 +3958,11 @@ private static boolean handlePendingDoorNearRawPath(List rawPath, if (rawPath == null || rawPath.size() < 2 || playerLoc == null) { return false; } + if (Rs2Player.isMoving()) { + return false; + } - int rawStart = getClosestTileIndex(rawPath); + int rawStart = getClosestTileIndex(rawPath, playerLoc); if (rawStart < 0) { return false; } @@ -3613,6 +3994,45 @@ private static boolean handlePendingDoorNearRawPath(List rawPath, return false; } + private static boolean handleUnresolvedDoorNearRawPath(List rawPath, + int rawEdgeStart, + long timeoutMs, + Map attempted, + WorldPoint playerLoc, + int backtrackEdges, + int lookaheadEdges, + int radiusTiles) { + if (rawPath == null || rawPath.size() < 2 || rawEdgeStart < 0 || playerLoc == null || Rs2Player.isMoving()) { + return false; + } + + int start = Math.max(0, rawEdgeStart - Math.max(0, backtrackEdges)); + int endExclusive = Math.min(rawPath.size() - 1, rawEdgeStart + Math.max(1, lookaheadEdges)); + for (int ri = start; ri < endExclusive && ri < rawPath.size() - 1; ri++) { + WorldPoint from = rawPath.get(ri); + WorldPoint to = rawPath.get(ri + 1); + if (from == null || to == null) { + continue; + } + if (from.getPlane() != playerLoc.getPlane() || to.getPlane() != playerLoc.getPlane()) { + break; + } + if (from.distanceTo2D(playerLoc) > radiusTiles && to.distanceTo2D(playerLoc) > radiusTiles) { + continue; + } + if (isCatalogBackedTransportSegment(rawPath, ri) && !isDoorLikeCatalogTransportSegment(rawPath, ri)) { + continue; + } + if (!hasUnresolvedDoorLikeSceneObjectOnSegment(from, to, playerLoc, radiusTiles)) { + continue; + } + if (handleDoorsWithTimeout(rawPath, ri, timeoutMs, attempted, true)) { + return true; + } + } + return false; + } + private static int rawIndexForSmoothedIndex(int smoothedIdx, int[] smoothedToRaw, List rawPath) { if (rawPath == null || rawPath.isEmpty()) { return -1; @@ -3654,7 +4074,7 @@ private static boolean handleNearbyRawPathSceneObjects(List rawPath, return false; } - int rawStart = getClosestTileIndex(rawPath); + int rawStart = getClosestTileIndex(rawPath, playerLoc); if (rawStart < 0) { clearRawScanDoorFocus("raw-start-missing"); return false; @@ -3878,10 +4298,19 @@ private static void addForwardPathIndices(Map forwardIndex, return; } - int closestIndex = IntStream.range(0, path.size()) - .boxed() - .min(Comparator.comparingInt(i -> playerLoc.distanceTo(path.get(i)))) - .orElse(0); + int closestIndex = 0; + int closestDistance = Integer.MAX_VALUE; + for (int i = 0; i < path.size(); i++) { + WorldPoint point = path.get(i); + if (point == null) { + continue; + } + int distance = playerLoc.distanceTo(point); + if (distance < closestDistance) { + closestDistance = distance; + closestIndex = i; + } + } for (int i = closestIndex; i < path.size(); i++) { forwardIndex.putIfAbsent(path.get(i), i); } @@ -3895,6 +4324,9 @@ private static void addForwardPathIndices(Map forwardIndex, private static final long STATIONARY_DOOR_SUPPRESS_MS = 10_000; private static final Map recentDoorAttemptByEdge = new ConcurrentHashMap<>(); private static final long DOOR_ATTEMPT_EDGE_COOLDOWN_MS = 2_500; + private static volatile WorldPoint lastDoorAttemptFrom = null; + private static volatile WorldPoint lastDoorAttemptTo = null; + private static volatile long lastDoorAttemptAtMs = 0L; private static final Map recentCurrentTileTransportByEdge = new ConcurrentHashMap<>(); private static final long CURRENT_TILE_TRANSPORT_EDGE_COOLDOWN_MS = 2_200; private static final long DOOR_INTERACTION_GLOBAL_COOLDOWN_MS = 1_800; @@ -3971,6 +4403,25 @@ static int findFurthestClickableIndex(List path, int startIdx, World return bestIdx; } + static int findFurthestForwardClickableIndex(List path, int startIdx, WorldPoint playerLoc, + java.util.function.Predicate isTransportOrigin, + int maxEuclidean) { + if (path == null || startIdx < 0 || startIdx >= path.size()) return startIdx; + WorldPoint startWp = path.get(startIdx); + if (startWp == null) return startIdx; + final int maxSq = maxEuclidean * maxEuclidean; + + int bestIdx = startIdx; + for (int j = startIdx; j < path.size(); j++) { + WorldPoint candidate = path.get(j); + if (candidate == null || candidate.getPlane() != startWp.getPlane()) break; + if (j > startIdx && isTransportOrigin != null && isTransportOrigin.test(candidate)) break; + if (playerLoc != null && euclideanSq(candidate, playerLoc) > maxSq) break; + bestIdx = j; + } + return bestIdx; + } + private static int findForwardReachableRecoveryIndex(List path, int startIdx, WorldPoint playerLoc, @@ -4064,6 +4515,47 @@ static WorldPoint interpolateClickableTarget(List path, return fallbackWp; } + static WorldPoint clampToEuclideanRadius(WorldPoint playerLoc, WorldPoint target, int maxEuclidean) { + if (playerLoc == null || target == null || target.getPlane() != playerLoc.getPlane() || maxEuclidean <= 0) { + return target; + } + int maxSq = maxEuclidean * maxEuclidean; + if (euclideanSq(playerLoc, target) <= maxSq) { + return target; + } + + int dx = target.getX() - playerLoc.getX(); + int dy = target.getY() - playerLoc.getY(); + double distance = Math.sqrt(dx * dx + dy * dy); + if (distance <= 1) { + return target; + } + + double scale = maxEuclidean / distance; + int stepX = (int) Math.round(dx * scale); + int stepY = (int) Math.round(dy * scale); + if (stepX == 0 && stepY == 0) { + if (Math.abs(dx) >= Math.abs(dy)) { + stepX = Integer.signum(dx); + } else { + stepY = Integer.signum(dy); + } + } + + WorldPoint clamped = new WorldPoint(playerLoc.getX() + stepX, playerLoc.getY() + stepY, playerLoc.getPlane()); + while (!clamped.equals(playerLoc) && euclideanSq(playerLoc, clamped) > maxSq) { + if (Math.abs(stepX) >= Math.abs(stepY) && stepX != 0) { + stepX -= Integer.signum(stepX); + } else if (stepY != 0) { + stepY -= Integer.signum(stepY); + } else { + break; + } + clamped = new WorldPoint(playerLoc.getX() + stepX, playerLoc.getY() + stepY, playerLoc.getPlane()); + } + return clamped.equals(playerLoc) ? target : clamped; + } + private static int euclideanSq(WorldPoint a, WorldPoint b) { int dx = a.getX() - b.getX(); int dy = a.getY() - b.getY(); @@ -4333,6 +4825,11 @@ && isNullOrPlaceholderObjectName(comp.getName())) { compactWorldPoint(probe), compactWorldPoint(fromWp), compactWorldPoint(toWp)); return false; } + if (Rs2Player.isMoving()) { + WebWalkLog.spInfo("door_interact_deferred | reason=moving mode=segment-door probe={} from={} to={}", + compactWorldPoint(probe), compactWorldPoint(fromWp), compactWorldPoint(toWp)); + return false; + } markDoorAttempt(probe, fromWp, toWp); markGlobalDoorInteractionCooldown(); WorldPoint posBefore = Rs2Player.getWorldLocation(); @@ -4477,6 +4974,11 @@ private static boolean tryHandleDoorObject(TileObject object, WorldPoint probe, compactWorldPoint(probe), compactWorldPoint(fromWp), compactWorldPoint(toWp)); return false; } + if (Rs2Player.isMoving()) { + WebWalkLog.spInfo("door_interact_deferred | reason=moving mode=segment-probe probe={} from={} to={}", + compactWorldPoint(probe), compactWorldPoint(fromWp), compactWorldPoint(toWp)); + return false; + } markDoorAttempt(probe, fromWp, toWp); markGlobalDoorInteractionCooldown(); WorldPoint posBefore = Rs2Player.getWorldLocation(); @@ -4760,6 +5262,31 @@ private static boolean tryDoorEdgeCrossNudge(WorldPoint fromWp, WorldPoint toWp, return progressed; } + private static boolean tryRecentDoorAttemptEdgeNudge(WorldPoint playerLoc, WorldPoint target) { + WorldPoint from = lastDoorAttemptFrom; + WorldPoint to = lastDoorAttemptTo; + long attemptedAt = lastDoorAttemptAtMs; + if (playerLoc == null || from == null || to == null || attemptedAt <= 0L) { + return false; + } + long ageMs = System.currentTimeMillis() - attemptedAt; + if (ageMs < 0L || ageMs > POST_DOOR_NUDGE_RECENT_ATTEMPT_MS) { + return false; + } + if (playerLoc.getPlane() != to.getPlane() || playerLoc.distanceTo2D(to) > POST_DOOR_EDGE_NUDGE_MAX_FROM_PLAYER) { + return false; + } + if (Rs2Player.isMoving() || Rs2Player.isAnimating()) { + return false; + } + boolean nudged = tryDoorEdgeCrossNudge(from, to, target); + if (nudged) { + WebWalkLog.tmark("recent_door_edge_nudge", System.currentTimeMillis() - walkSessionStartedAtMs, + target, playerLoc, "from=" + compactWorldPoint(from) + " to=" + compactWorldPoint(to)); + } + return nudged; + } + static boolean isDoorEdgeNudgeResolved(WorldPoint before, WorldPoint after, WorldPoint fromWp, WorldPoint toWp) { if (before == null || after == null || fromWp == null || toWp == null) { return false; @@ -4803,8 +5330,7 @@ static boolean shouldClearInterimTarget(WorldPoint interim, if (playerLoc == null || playerLoc.getPlane() != interim.getPlane()) { return true; } - int preclickTiles = interimPreclickTiles(); - if (playerLoc.distanceTo2D(interim) <= preclickTiles) { + if (playerLoc.distanceTo2D(interim) <= INTERIM_CLOSE_TILES) { return true; } if (lastProgressAtMs > 0L && nowMs - lastProgressAtMs > INTERIM_PROGRESS_TIMEOUT_MS) { @@ -4813,12 +5339,59 @@ static boolean shouldClearInterimTarget(WorldPoint interim, return setAtMs > 0L && nowMs - setAtMs > INTERIM_MAX_AGE_MS; } + static int distanceToInterimOrMax(WorldPoint interim, WorldPoint playerLoc) { + if (interim == null || playerLoc == null || interim.getPlane() != playerLoc.getPlane()) { + return Integer.MAX_VALUE; + } + return playerLoc.distanceTo2D(interim); + } + + private static void recordInterimDistanceProgress(WorldPoint interim, WorldPoint playerLoc, long nowMs) { + int distance = distanceToInterimOrMax(interim, playerLoc); + if (distance < interimLastDistanceToTarget) { + interimLastDistanceToTarget = distance; + interimLastProgressAtMs = nowMs; + } + } + + private static void waitForMovementStartAfterRecovery(WorldPoint cancelGoal, + WorldPoint playerBefore, + WorldPoint interimGoal, + WorldPoint arrivalGoal, + int arrivalMaxChebyshev) { + if (cancelGoal == null || playerBefore == null) { + return; + } + sleepUntil(() -> { + if (isWalkCancelled(cancelGoal)) { + return true; + } + WorldPoint playerNow = Rs2Player.getWorldLocation(); + if (playerNow == null) { + return false; + } + if (!playerNow.equals(playerBefore) || Rs2Player.isMoving()) { + return true; + } + if (interimGoal != null + && interimGoal.getPlane() == playerNow.getPlane() + && playerNow.distanceTo2D(interimGoal) <= INTERIM_CLOSE_TILES) { + return true; + } + return arrivalGoal != null + && arrivalMaxChebyshev >= 0 + && arrivalGoal.getPlane() == playerNow.getPlane() + && playerNow.distanceTo2D(arrivalGoal) <= arrivalMaxChebyshev; + }, POST_RECOVERY_MOVEMENT_START_WAIT_MS); + } + private static boolean clearInterimTargetIfReachedOrExpired(WorldPoint playerLoc, List path, long nowMs) { WorldPoint interim = interimTargetWp; + recordInterimDistanceProgress(interim, playerLoc, nowMs); if (interim != null && path != null && !path.isEmpty()) { - int bestIdxNow = getClosestTileIndex(path); + int bestIdxNow = getClosestTileIndex(path, playerLoc); if (bestIdxNow > interimLastBestPathIdx) { interimLastBestPathIdx = bestIdxNow; interimLastProgressAtMs = nowMs; @@ -4830,7 +5403,7 @@ private static boolean clearInterimTargetIfReachedOrExpired(WorldPoint playerLoc String reason; if (playerLoc == null || interim == null || playerLoc.getPlane() != interim.getPlane()) { reason = "invalid"; - } else if (playerLoc.distanceTo2D(interim) <= interimPreclickTiles()) { + } else if (playerLoc.distanceTo2D(interim) <= INTERIM_CLOSE_TILES) { reason = "close"; } else if (interimLastProgressAtMs > 0L && nowMs - interimLastProgressAtMs > INTERIM_PROGRESS_TIMEOUT_MS) { reason = "stale-progress"; @@ -4841,16 +5414,72 @@ private static boolean clearInterimTargetIfReachedOrExpired(WorldPoint playerLoc return true; } + private static boolean shouldYieldForActiveRecoveryInterim(WorldPoint playerLoc, + List path, + long nowMs) { + WorldPoint interim = interimTargetWp; + if (interim == null) { + return false; + } + recordInterimDistanceProgress(interim, playerLoc, nowMs); + if (playerLoc != null && path != null && !path.isEmpty()) { + int bestIdxNow = getClosestTileIndex(path, playerLoc); + if (bestIdxNow > interimLastBestPathIdx) { + interimLastBestPathIdx = bestIdxNow; + interimLastProgressAtMs = nowMs; + } + } + return shouldYieldForActiveRecoveryInterim(interim, + playerLoc, + interimSetAtMs, + interimLastProgressAtMs, + nowMs, + lastMovedTimeMs, + lastUnreachableRecoveryClickAtMs, + Rs2Player.isMoving()); + } + + static boolean shouldYieldForActiveRecoveryInterim(WorldPoint interim, + WorldPoint playerLoc, + long setAtMs, + long lastProgressAtMs, + long nowMs, + long lastMovedAtMs, + long lastRecoveryClickAtMs, + boolean playerMoving) { + if (interim == null) { + return false; + } + if (shouldClearInterimTarget(interim, playerLoc, setAtMs, lastProgressAtMs, nowMs)) { + return false; + } + if (playerMoving) { + return true; + } + if (isRecentEvent(nowMs, lastProgressAtMs, INTERIM_PROGRESS_TIMEOUT_MS)) { + return true; + } + if (isRecentEvent(nowMs, lastMovedAtMs, RECOVERY_MOVEMENT_IN_FLIGHT_MS)) { + return true; + } + return isRecentEvent(nowMs, lastRecoveryClickAtMs, RECOVERY_MOVEMENT_IN_FLIGHT_MS); + } + private static void clearInterimTarget(String reason) { WorldPoint old = interimTargetWp; if (old != null) { - WebWalkLog.spInfo("interim_clear | reason={} interim={}", reason, compactWorldPoint(old)); + if ("close".equals(reason)) { + WebWalkLog.spDebug("interim_clear | reason={} interim={}", reason, compactWorldPoint(old)); + } else { + WebWalkLog.spInfo("interim_clear | reason={} interim={}", reason, compactWorldPoint(old)); + } } interimTargetWp = null; interimTargetIdx = -1; interimSetAtMs = 0L; interimLastProgressAtMs = 0L; interimLastBestPathIdx = -1; + interimLastDistanceToTarget = Integer.MAX_VALUE; interimLastRetargetAtMs = 0L; } @@ -4899,6 +5528,11 @@ private static void markGlobalDoorInteractionCooldown() { private static void markDoorAttempt(WorldPoint doorTile, WorldPoint fromWp, WorldPoint toWp) { Rs2DoorHandler.markDoorAttempt(recentDoorAttemptByEdge, doorTile, fromWp, toWp); + if (fromWp != null && toWp != null) { + lastDoorAttemptFrom = fromWp; + lastDoorAttemptTo = toWp; + lastDoorAttemptAtMs = System.currentTimeMillis(); + } } private static boolean shouldThrottleCurrentTileTransportAttempt(WorldPoint fromWp, WorldPoint toWp) { @@ -5190,6 +5824,9 @@ static boolean shouldBlacklistDoorAfterWrongTraversal(WorldPoint start, WorldPoi if (start.getPlane() != end.getPlane()) { return true; } + if (!startedNearDoorEdge(start, fromWp, toWp)) { + return false; + } int moved = start.distanceTo2D(end); if (moved < 3) { return false; @@ -5207,6 +5844,20 @@ static boolean shouldBlacklistDoorAfterWrongTraversal(WorldPoint start, WorldPoi return endFrom >= startFrom + 2; } + private static boolean startedNearDoorEdge(WorldPoint start, WorldPoint fromWp, WorldPoint toWp) { + if (start == null) { + return false; + } + final int maxDoorStartDistance = 3; + boolean nearFrom = fromWp != null + && fromWp.getPlane() == start.getPlane() + && start.distanceTo2D(fromWp) <= maxDoorStartDistance; + boolean nearTo = toWp != null + && toWp.getPlane() == start.getPlane() + && start.distanceTo2D(toWp) <= maxDoorStartDistance; + return nearFrom || nearTo; + } + private static boolean movedAcrossInteractedObject(WorldPoint start, WorldPoint end, WorldPoint objectLoc) { int startRelX = Integer.compare(start.getX(), objectLoc.getX()); int endRelX = Integer.compare(end.getX(), objectLoc.getX()); @@ -6474,40 +7125,72 @@ private static boolean searchNeighborPoint(int orientation, WorldPoint point, Wo * @return closest tile index */ public static int getClosestTileIndex(List path) { + WorldPoint playerLoc = Rs2Player.getWorldLocation(); + return getClosestTileIndex(path, playerLoc, getClosestIndexReachableTiles(playerLoc)); + } - var tiles = Rs2Tile.getReachableTilesFromTile(Rs2Player.getWorldLocation(), 20); + static int getClosestTileIndex(List path, WorldPoint playerLoc) { + return getClosestTileIndex(path, playerLoc, getClosestIndexReachableTiles(playerLoc)); + } - /** - * Exception to handle objects that handle long animations or walk - * ignore colission if we did not find a valid tile to walk on - * this is to ensure we stay on the path even if we are on a agility obstacle - */ - if (tiles.keySet().isEmpty()) { - tiles = Rs2Tile.getReachableTilesFromTileIgnoreCollision(Rs2Player.getWorldLocation(), 20); + static int getClosestTileIndex(List path, + WorldPoint playerLoc, + Map reachableTiles) { + if (path == null || path.isEmpty() || playerLoc == null) { + return -1; } - final HashMap _tiles = tiles; - WorldPoint startPoint = path.stream() - .min(Comparator.comparingInt(a -> _tiles.getOrDefault(a, Integer.MAX_VALUE))) - .orElse(null); + int bestReachableIndex = -1; + int bestReachableDistance = Integer.MAX_VALUE; + if (reachableTiles != null && !reachableTiles.isEmpty()) { + for (int i = 0; i < path.size(); i++) { + WorldPoint point = path.get(i); + if (point == null) { + continue; + } + int reachableDistance = reachableTiles.getOrDefault(point, Integer.MAX_VALUE); + if (reachableDistance < bestReachableDistance) { + bestReachableDistance = reachableDistance; + bestReachableIndex = i; + if (reachableDistance == 0) { + break; + } + } + } + } - /** - * Check if the startPoint is null or no matching tile is found - * If either condition is true, proceed to find the closest index in the path list. - */ - if (startPoint == null || _tiles.getOrDefault(startPoint, Integer.MAX_VALUE) == Integer.MAX_VALUE) { - Optional closestIndexOptional = IntStream.range(0, path.size()) - .boxed() - .min(Comparator.comparingInt(i -> Rs2Player.getWorldLocation().distanceTo(path.get(i)))); - if (closestIndexOptional.isPresent()) { - return closestIndexOptional.get(); + if (bestReachableIndex >= 0 && bestReachableDistance != Integer.MAX_VALUE) { + return bestReachableIndex; + } + + int closestIndex = -1; + int closestDistance = Integer.MAX_VALUE; + for (int i = 0; i < path.size(); i++) { + WorldPoint point = path.get(i); + if (point == null) { + continue; + } + int distance = playerLoc.distanceTo(point); + if (distance < closestDistance) { + closestDistance = distance; + closestIndex = i; } } + return closestIndex; + } - return IntStream.range(0, path.size()) - .filter(i -> path.get(i).equals(startPoint)) - .findFirst() - .orElse(-1); + private static HashMap getClosestIndexReachableTiles(WorldPoint playerLoc) { + if (playerLoc == null) { + return new HashMap<>(); + } + HashMap tiles = Rs2Tile.getReachableTilesFromTile(playerLoc, 20); + + // If an animation/shortcut puts the player on a collision-odd tile, keep route progress + // anchored by distance instead of repeatedly recalculating an empty reachable set. + if (tiles.isEmpty()) { + tiles = Rs2Tile.getReachableTilesFromTileIgnoreCollision(playerLoc, 20); + } + return tiles; } static int stabilizeRouteProgressIndex(List path, int closestIdx, WorldPoint target, WorldPoint playerLoc) { @@ -6529,10 +7212,14 @@ static int stabilizeRouteProgressIndex(List path, int closestIdx, Wo routeProgressPathEnd = pathEnd; routeProgressPathSize = path.size(); routeProgressIdx = closestIdx; + routeProgressAdvancedAtMs = System.currentTimeMillis(); return closestIdx; } if (routeProgressIdx < 0 || closestIdx >= routeProgressIdx) { + if (closestIdx > routeProgressIdx) { + recordRouteProgressAdvanced(); + } routeProgressIdx = closestIdx; return closestIdx; } @@ -6541,6 +7228,7 @@ static int stabilizeRouteProgressIndex(List path, int closestIdx, Wo if (forwardIdx >= routeProgressIdx) { if (forwardIdx > routeProgressIdx) { routeProgressIdx = forwardIdx; + recordRouteProgressAdvanced(); } return routeProgressIdx; } @@ -6601,6 +7289,14 @@ private static void resetRouteProgress() { routeProgressPathStart = null; routeProgressPathEnd = null; routeProgressPathSize = -1; + routeProgressAdvancedAtMs = 0L; + } + + private static void recordRouteProgressAdvanced() { + long now = System.currentTimeMillis(); + routeProgressAdvancedAtMs = now; + lastMovedTimeMs = now; + stuckCount = 0; } private static boolean isRecentTransportEdgeWindow() { @@ -7618,7 +8314,8 @@ private static boolean hasPrecomputedContinuationFromTransport(Transport transpo if (walkPath == null || walkPath.size() < 2) { return false; } - int closest = getClosestTileIndex(walkPath); + WorldPoint playerLoc = Rs2Player.getWorldLocation(); + int closest = getClosestTileIndex(walkPath, playerLoc); if (closest < 0) { return false; } @@ -8150,7 +8847,7 @@ private static boolean isNearPathByVariance(List path, WorldPoint pl if (path == null || path.isEmpty() || playerLoc == null) { return false; } - int closestIdx = getClosestTileIndex(path); + int closestIdx = getClosestTileIndex(path, playerLoc); if (closestIdx < 0 || closestIdx >= path.size()) { return false; } @@ -8160,6 +8857,104 @@ private static boolean isNearPathByVariance(List path, WorldPoint pl && closest.distanceTo2D(playerLoc) <= PATH_VARIANCE_TOLERANCE_CHEBYSHEV; } + static String offPathRecalcDeferralReason(boolean playerMoving, + boolean playerAnimating, + boolean playerInteracting, + boolean doorSettling, + boolean transportSettling, + boolean interimActive, + long nowMs, + long lastMovedAtMs, + long routeProgressAtMs, + long minimapClickAtMs, + long interimProgressAtMs) { + if (doorSettling) { + return "door-settling"; + } + if (transportSettling) { + return "transport-settling"; + } + if (playerMoving) { + return "moving"; + } + if (playerAnimating) { + return "animating"; + } + if (playerInteracting) { + return "interacting"; + } + if (isRecentEvent(nowMs, routeProgressAtMs, OFF_PATH_RECALC_ROUTE_PROGRESS_GRACE_MS)) { + return "route-progress"; + } + if (isRecentEvent(nowMs, minimapClickAtMs, OFF_PATH_RECALC_MINIMAP_CLICK_GRACE_MS)) { + return "recent-click"; + } + if (interimActive && isRecentEvent(nowMs, interimProgressAtMs, INTERIM_PROGRESS_TIMEOUT_MS)) { + return "interim-progress"; + } + if (isRecentEvent(nowMs, lastMovedAtMs, OFF_PATH_RECALC_RECENT_MOVEMENT_MS)) { + return "recent-movement"; + } + return null; + } + + private static String currentOffPathRecalcDeferralReason(long minimapClickAtMs) { + return offPathRecalcDeferralReason( + Rs2Player.isMoving(), + Rs2Player.isAnimating(), + Rs2Player.isInteracting(), + isDoorInteractionSettling(), + isTransportInteractionSettling(), + interimTargetWp != null, + System.currentTimeMillis(), + lastMovedTimeMs, + routeProgressAdvancedAtMs, + minimapClickAtMs, + interimLastProgressAtMs); + } + + static int offPathRecalcDeferredWaitMs(String reason, + long nowMs, + long lastMovedAtMs, + long routeProgressAtMs, + long minimapClickAtMs, + long interimProgressAtMs) { + long remainingMs = OFF_PATH_RECALC_DEFER_WAIT_MAX_MS; + if ("route-progress".equals(reason)) { + remainingMs = remainingRecentEventMs(nowMs, routeProgressAtMs, OFF_PATH_RECALC_ROUTE_PROGRESS_GRACE_MS); + } else if ("recent-click".equals(reason)) { + remainingMs = remainingRecentEventMs(nowMs, minimapClickAtMs, OFF_PATH_RECALC_MINIMAP_CLICK_GRACE_MS); + } else if ("interim-progress".equals(reason)) { + remainingMs = remainingRecentEventMs(nowMs, interimProgressAtMs, INTERIM_PROGRESS_TIMEOUT_MS); + } else if ("recent-movement".equals(reason)) { + remainingMs = remainingRecentEventMs(nowMs, lastMovedAtMs, OFF_PATH_RECALC_RECENT_MOVEMENT_MS); + } + return (int) Math.max(OFF_PATH_RECALC_DEFER_WAIT_MIN_MS, + Math.min(OFF_PATH_RECALC_DEFER_WAIT_MAX_MS, remainingMs)); + } + + private static boolean isOffPathRecalcDeferredExit(String exitReason) { + return exitReason != null && exitReason.startsWith("off-path-deferred:"); + } + + private static String offPathDeferredReasonFromExit(String exitReason) { + if (!isOffPathRecalcDeferredExit(exitReason)) { + return ""; + } + return exitReason.substring("off-path-deferred:".length()); + } + + private static boolean isRecentEvent(long nowMs, long eventAtMs, long graceMs) { + return eventAtMs > 0L && nowMs >= eventAtMs && nowMs - eventAtMs < graceMs; + } + + private static long remainingRecentEventMs(long nowMs, long eventAtMs, long graceMs) { + if (!isRecentEvent(nowMs, eventAtMs, graceMs)) { + return OFF_PATH_RECALC_DEFER_WAIT_MIN_MS; + } + return graceMs - (nowMs - eventAtMs); + } + private static boolean hasUpcomingNearbyTransportStep(List path, int startIdx, WorldPoint playerLoc, @@ -8279,6 +9074,11 @@ private static boolean isStuckTooLong() { return false; } + long routeProgressAt = routeProgressAdvancedAtMs; + if (routeProgressAt > 0L && System.currentTimeMillis() - routeProgressAt < ROUTE_PROGRESS_STALL_GRACE_MS) { + return false; + } + return lastMovedTimeMs > 0 && System.currentTimeMillis() - lastMovedTimeMs > stallThresholdMs(); } @@ -8959,33 +9759,160 @@ private static boolean handleCharterShip(Transport transport) { log.info("Charter Ship NPC: " + npcName + " - " + (npc != null ? npc.getId() : "not found")); if (Rs2Npc.canWalkTo(npc, 20) && Rs2Npc.interact(npc, transport.getAction())) { Rs2Player.waitForWalking(); - sleepUntil(() -> Rs2Widget.isWidgetVisible(885, 4)); - List destinationWidgets = Arrays.stream(Rs2Widget.getWidget(885, 4).getDynamicChildren()) - .filter(w -> w.getActions() != null) - .collect(Collectors.toList()); + if (!sleepUntil(() -> Rs2Widget.isWidgetVisible(885, 4), 5000)) { + return false; + } - if (destinationWidgets.isEmpty()) return false; + Widget destinationWidget = findCharterDestinationWidget(transport.getDisplayInfo()); + if (!invokeCharterDestinationWidget(destinationWidget, transport.getDisplayInfo())) { + return false; + } + confirmCharterTravelIfPrompted(); + return true; + } + return false; + } - String destinationText = transport.getDisplayInfo(); + private static Widget findCharterDestinationWidget(String destinationText) { + return Microbot.getClientThread().runOnClientThreadOptional(() -> { + Widget root = Microbot.getClient().getWidget(885, 4); + if (root == null || root.isHidden()) { + return null; + } - Widget destinationWidget = Rs2Widget.findWidget(destinationText, destinationWidgets); - if (destinationWidget == null) return false; + Widget textMatch = findCharterDestinationTextWidget(root, destinationText); + if (textMatch == null) { + return null; + } - boolean isWidgetVisible = Microbot.getClientThread().runOnClientThreadOptional(() -> !destinationWidget.isHidden()).orElse(false); + Widget clickable = findClickableCharterWidget(textMatch, root); + return clickable != null ? clickable : textMatch; + }).orElse(null); + } - NewMenuEntry destinationMenuEntry = new NewMenuEntry() - .option(destinationText) - .target("") - .identifier(1) - .type(MenuAction.CC_OP) - .param0(destinationWidget.getIndex()) - .param1(destinationWidget.getId()) - .forceLeftClick(false); + private static Widget findCharterDestinationTextWidget(Widget widget, String destinationText) { + if (widget == null || widget.isHidden()) { + return null; + } + if (charterWidgetMatchesDestination(widget, destinationText)) { + return widget; + } - Microbot.doInvoke(destinationMenuEntry, new Rectangle(1, 1)); + Widget[] staticChildren = widget.getStaticChildren(); + Widget found = findCharterDestinationTextWidget(staticChildren, destinationText); + if (found != null) { + return found; + } + + Widget[] dynamicChildren = widget.getDynamicChildren(); + found = findCharterDestinationTextWidget(dynamicChildren, destinationText); + if (found != null) { + return found; + } + + return findCharterDestinationTextWidget(widget.getNestedChildren(), destinationText); + } + + private static Widget findCharterDestinationTextWidget(Widget[] widgets, String destinationText) { + if (widgets == null) { + return null; + } + for (Widget widget : widgets) { + Widget found = findCharterDestinationTextWidget(widget, destinationText); + if (found != null) { + return found; + } + } + return null; + } + + private static boolean charterWidgetMatchesDestination(Widget widget, String destinationText) { + String needle = normalizeCharterWidgetText(destinationText); + if (needle.isEmpty()) { + return false; + } + if (normalizeCharterWidgetText(widget.getText()).contains(needle) + || normalizeCharterWidgetText(widget.getName()).contains(needle)) { return true; } - return false; + String[] actions = widget.getActions(); + if (actions == null) { + return false; + } + return Arrays.stream(actions) + .filter(Objects::nonNull) + .map(Rs2Walker::normalizeCharterWidgetText) + .anyMatch(action -> action.contains(needle)); + } + + private static String normalizeCharterWidgetText(String text) { + if (text == null || text.isEmpty()) { + return ""; + } + return Rs2UiHelper.stripTagsToSpace(text) + .trim() + .toLowerCase(Locale.ROOT) + .replaceAll("\\s+", " "); + } + + private static Widget findClickableCharterWidget(Widget widget, Widget root) { + Widget current = widget; + while (current != null) { + if (hasWidgetActions(current)) { + return current; + } + if (current == root) { + return null; + } + current = current.getParent(); + } + return null; + } + + private static boolean hasWidgetActions(Widget widget) { + String[] actions = widget.getActions(); + return actions != null && Arrays.stream(actions).anyMatch(action -> action != null && !action.isEmpty()); + } + + private static boolean invokeCharterDestinationWidget(Widget widget, String destinationText) { + if (widget == null) { + return false; + } + + String option = getFirstWidgetAction(widget); + if (option == null || option.isBlank()) { + option = destinationText; + } + + NewMenuEntry destinationMenuEntry = new NewMenuEntry() + .option(option) + .target("") + .identifier(1) + .type(MenuAction.CC_OP) + .param0(widget.getIndex()) + .param1(widget.getId()) + .forceLeftClick(false); + + Rectangle bounds = widget.getBounds(); + Microbot.doInvoke(destinationMenuEntry, bounds != null ? bounds : Rs2UiHelper.getDefaultRectangle()); + return true; + } + + private static String getFirstWidgetAction(Widget widget) { + String[] actions = widget.getActions(); + if (actions == null) { + return null; + } + return Arrays.stream(actions) + .filter(action -> action != null && !action.isEmpty()) + .findFirst() + .orElse(null); + } + + private static void confirmCharterTravelIfPrompted() { + if (sleepUntil(Rs2Dialogue::hasSelectAnOption, 2000)) { + Rs2Dialogue.clickOption("Yes", true); + } } /** * interact with interfaces like spirit tree etc... diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java index cec154d812..63d7d7c4d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java @@ -22,7 +22,7 @@ public static void routeClearMissingReason(String threadName) { LOG.warn("[WebWalk] clear | reason= 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={}", @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index 31c84b2018..b0f01f0ac5 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -11,8 +11,10 @@ import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -238,6 +240,30 @@ public void rankSidestep_preservesAllTilesIncludingEquidistant() { assertTrue(ranked.contains(north)); } + @Test + public void getClosestTileIndex_usesReachableDistanceWhenAvailable() { + WorldPoint player = new WorldPoint(3200, 3200, 0); + WorldPoint farByWorldDistance = new WorldPoint(3210, 3200, 0); + WorldPoint nearReachable = new WorldPoint(3220, 3200, 0); + List path = Arrays.asList(farByWorldDistance, nearReachable); + Map reachable = new HashMap<>(); + reachable.put(farByWorldDistance, 8); + reachable.put(nearReachable, 3); + + assertEquals(1, Rs2Walker.getClosestTileIndex(path, player, reachable)); + } + + @Test + public void getClosestTileIndex_fallsBackToWorldDistanceWhenNoReachablePathTile() { + WorldPoint player = new WorldPoint(3200, 3200, 0); + List path = Arrays.asList( + new WorldPoint(3210, 3200, 0), + new WorldPoint(3202, 3200, 0), + new WorldPoint(3220, 3200, 0)); + + assertEquals(1, Rs2Walker.getClosestTileIndex(path, player, Collections.emptyMap())); + } + // --------------------------------------------------------------------------- // #21 — Minimap forward-scan // --------------------------------------------------------------------------- @@ -356,7 +382,7 @@ public void findFurthest_nullPredicate_treatsAsNoTransport() { } @Test - public void stabilizeRouteProgressIndex_doesNotJumpBackToEarlierSwitchbackBranch() { + public void stabilizeRouteProgressIndex_doesNotJumpBackToEarlierNearbyBranch() { WorldPoint target = new WorldPoint(3200, 3201, 0); List path = Arrays.asList( new WorldPoint(3200, 3200, 0), @@ -376,7 +402,7 @@ public void stabilizeRouteProgressIndex_doesNotJumpBackToEarlierSwitchbackBranch } @Test - public void findForwardRecoveryIndex_prefersLaterReachableSwitchbackBranch() { + public void findForwardRecoveryIndex_prefersLaterReachableBranch() { WorldPoint player = new WorldPoint(1000, 1000, 0); List path = Arrays.asList( new WorldPoint(998, 1000, 0), @@ -396,7 +422,7 @@ public void findForwardRecoveryIndex_prefersLaterReachableSwitchbackBranch() { } @Test - public void findFurthestClickableIndex_canReturnEarlierSwitchbackBranch() { + public void findFurthestClickableIndex_canReturnEarlierNearbyBranch() { WorldPoint player = new WorldPoint(1000, 1000, 0); List path = Arrays.asList( new WorldPoint(998, 1000, 0), @@ -410,6 +436,83 @@ public void findFurthestClickableIndex_canReturnEarlierSwitchbackBranch() { assertEquals("generic fallback is allowed to backtrack; recovery clamps this at the call site", 2, idx); } + @Test + public void findFurthestForwardClickableIndex_doesNotBacktrackToEarlierNearbyBranch() { + WorldPoint player = new WorldPoint(1000, 1000, 0); + List path = Arrays.asList( + new WorldPoint(998, 1000, 0), + new WorldPoint(999, 1000, 0), + new WorldPoint(1000, 1001, 0), + new WorldPoint(1015, 1000, 0), + new WorldPoint(1016, 1001, 0)); + + int idx = Rs2Walker.findFurthestForwardClickableIndex(path, 3, player, wp -> false, 13); + + assertEquals("normal route following should interpolate toward the forward tile, not backtrack", 3, idx); + } + + @Test + public void findFurthestForwardClickableIndex_stopsBeforeTransportOrigin() { + WorldPoint player = new WorldPoint(3200, 3200, 0); + WorldPoint transportOrigin = new WorldPoint(3203, 3200, 0); + List path = Arrays.asList( + new WorldPoint(3201, 3200, 0), + new WorldPoint(3202, 3200, 0), + transportOrigin, + new WorldPoint(3204, 3200, 0)); + + int idx = Rs2Walker.findFurthestForwardClickableIndex(path, 0, player, transportOrigin::equals, 13); + + assertEquals("route clicks must not skip a planned transport origin", 1, idx); + } + + @Test + public void offPathRecalcDeferralReason_prefersSettlingAndBusyState() { + long now = 10_000L; + + assertEquals("door-settling", Rs2Walker.offPathRecalcDeferralReason( + true, false, false, true, false, false, + now, 0L, 0L, 0L, 0L)); + assertEquals("transport-settling", Rs2Walker.offPathRecalcDeferralReason( + true, false, false, false, true, false, + now, 0L, 0L, 0L, 0L)); + assertEquals("moving", Rs2Walker.offPathRecalcDeferralReason( + true, false, false, false, false, false, + now, 0L, 0L, 0L, 0L)); + } + + @Test + public void offPathRecalcDeferralReason_recentProgressDefersAfterMovementStops() { + long now = 10_000L; + + assertEquals("route-progress", Rs2Walker.offPathRecalcDeferralReason( + false, false, false, false, false, false, + now, 0L, 8_000L, 0L, 0L)); + assertEquals("recent-click", Rs2Walker.offPathRecalcDeferralReason( + false, false, false, false, false, false, + now, 0L, 0L, 8_000L, 0L)); + assertEquals("interim-progress", Rs2Walker.offPathRecalcDeferralReason( + false, false, false, false, false, true, + now, 0L, 0L, 0L, 8_000L)); + } + + @Test + public void offPathRecalcDeferralReason_allowsRecalcWhenSignalsExpired() { + long now = 10_000L; + + assertEquals(null, Rs2Walker.offPathRecalcDeferralReason( + false, false, false, false, false, false, + now, 7_000L, 6_000L, 7_000L, 7_000L)); + } + + @Test + public void offPathRecalcDeferredWaitMs_isBounded() { + assertEquals(1200, Rs2Walker.offPathRecalcDeferredWaitMs( + "route-progress", 10_000L, 0L, 9_700L, 0L, 0L)); + assertEquals(250, Rs2Walker.offPathRecalcDeferredWaitMs( + "route-progress", 10_000L, 0L, 6_600L, 0L, 0L)); + } + @Test public void interpolateClickableTarget_usesInterpolatedPointWhenUsable() { WorldPoint player = new WorldPoint(3200, 3200, 0); @@ -453,6 +556,26 @@ public void interpolateClickableTarget_shortensOutOfReachForwardWaypoint() { new WorldPoint(3212, 3200, 0), target); } + @Test + public void clampToEuclideanRadius_shortensDiagonalTargetInsideCircle() { + WorldPoint player = new WorldPoint(2875, 3418, 0); + WorldPoint target = new WorldPoint(2886, 3428, 0); + + WorldPoint clamped = Rs2Walker.clampToEuclideanRadius(player, target, 10); + + assertTrue(clamped.distanceTo2D(player) <= 10); + assertTrue(clamped.getX() > player.getX()); + assertTrue(clamped.getY() > player.getY()); + } + + @Test + public void clampToEuclideanRadius_keepsInRangeTarget() { + WorldPoint player = new WorldPoint(3200, 3200, 0); + WorldPoint target = new WorldPoint(3206, 3203, 0); + + assertEquals(target, Rs2Walker.clampToEuclideanRadius(player, target, 10)); + } + // --------------------------------------------------------------------------- // Raw-path wall-door segment probing // --------------------------------------------------------------------------- @@ -525,6 +648,23 @@ public void shouldClearInterimTarget_closeToCheckpoint_returnsTrue() { 2_000L)); } + @Test + public void shouldClearInterimTarget_preclickDistanceStillKeepsCheckpoint() { + assertFalse(Rs2Walker.shouldClearInterimTarget( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2884, 3396, 0), + 1_000L, + 1_500L, + 2_000L)); + } + + @Test + public void distanceToInterimOrMax_samePlaneReturnsDistance() { + assertEquals(8, Rs2Walker.distanceToInterimOrMax( + new WorldPoint(2850, 3506, 0), + new WorldPoint(2849, 3498, 0))); + } + @Test public void shouldClearInterimTarget_expiredCheckpoint_returnsTrue() { assertTrue(Rs2Walker.shouldClearInterimTarget( @@ -555,10 +695,124 @@ public void shouldClearInterimTarget_activeFarCheckpoint_returnsFalse() { 5_000L)); } + @Test + public void shouldYieldForActiveRecoveryInterim_recentProgress_returnsTrue() { + assertTrue(Rs2Walker.shouldYieldForActiveRecoveryInterim( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2884, 3396, 0), + 1_000L, + 2_500L, + 3_000L, + 0L, + 0L, + false)); + } + + @Test + public void shouldYieldForActiveRecoveryInterim_staleProgress_returnsFalse() { + assertFalse(Rs2Walker.shouldYieldForActiveRecoveryInterim( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2880, 3396, 0), + 1_000L, + 1_500L, + 5_000L, + 0L, + 0L, + false)); + } + + @Test + public void shouldYieldForActiveRecoveryInterim_recentRecoveryClick_returnsTrue() { + assertTrue(Rs2Walker.shouldYieldForActiveRecoveryInterim( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2880, 3396, 0), + 1_000L, + 0L, + 3_000L, + 0L, + 2_000L, + false)); + } + @Test public void interimPreclickTiles_runHandsOffEarlierThanWalk() { assertEquals(6, Rs2Walker.interimPreclickTiles(false)); - assertEquals(11, Rs2Walker.interimPreclickTiles(true)); + assertEquals(8, Rs2Walker.interimPreclickTiles(true)); + } + + @Test + public void routeMovementClickPhase_labelsContinuationSeparatelyFromRecovery() { + assertEquals("stall_recovery_click", Rs2Walker.routeMovementClickPhase("stall recovery click")); + assertEquals("active_route_idle_nudge", Rs2Walker.routeMovementClickPhase("active route idle nudge")); + assertEquals("interim_close_route_click", Rs2Walker.routeMovementClickPhase("interim close route click")); + assertEquals("route_movement_click", Rs2Walker.routeMovementClickPhase("other")); + } + + @Test + public void shouldSkipStartupPreclickSegmentHandlers_skipsBeyondStartupLookahead() { + assertTrue(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( + true, + 8, + 5, + false, + false, + false)); + } + + @Test + public void shouldSkipStartupPreclickSegmentHandlers_keepsImmediateAndDoorRecoveryEdges() { + assertFalse(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( + true, + 7, + 5, + false, + false, + false)); + assertFalse(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( + true, + 8, + 5, + true, + false, + false)); + assertFalse(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( + false, + 8, + 5, + false, + false, + false)); + } + + @Test + public void rawPathForwardAnchorIndex_keepsFallbackAheadOfAnchor() { + List rawPath = Arrays.asList( + new WorldPoint(3200, 3200, 0), + new WorldPoint(3201, 3200, 0), + new WorldPoint(3202, 3200, 0), + new WorldPoint(3203, 3200, 0), + new WorldPoint(3204, 3200, 0), + new WorldPoint(3205, 3200, 0), + new WorldPoint(3206, 3200, 0), + new WorldPoint(3207, 3200, 0), + new WorldPoint(3208, 3200, 0), + new WorldPoint(3209, 3200, 0), + new WorldPoint(3210, 3200, 0), + new WorldPoint(3210, 3201, 0), + new WorldPoint(3210, 3202, 0), + new WorldPoint(3210, 3203, 0), + new WorldPoint(3210, 3204, 0), + new WorldPoint(3209, 3204, 0), + new WorldPoint(3208, 3204, 0), + new WorldPoint(3207, 3204, 0), + new WorldPoint(3206, 3204, 0), + new WorldPoint(3205, 3204, 0), + new WorldPoint(3204, 3204, 0)); + WorldPoint playerOnReturnBranch = rawPath.get(20); + + assertEquals("forward anchor must keep raw fallback on the current return branch", + 20, + Rs2Walker.rawPathForwardAnchorIndex(rawPath, playerOnReturnBranch, 14)); } @Test @@ -600,6 +854,16 @@ public void shouldBlacklistDoorAfterWrongTraversal_teleportAway_returnsTrue() { new WorldPoint(1988, 5569, 0))); } + @Test + public void shouldBlacklistDoorAfterWrongTraversal_startedFarFromDoor_returnsFalse() { + assertFalse("movement from an earlier minimap click must not blacklist a valid gate", + Rs2Walker.shouldBlacklistDoorAfterWrongTraversal( + new WorldPoint(3270, 3320, 0), + new WorldPoint(3275, 3325, 0), + new WorldPoint(3262, 3322, 0), + new WorldPoint(3261, 3321, 0))); + } + @Test public void shouldBlacklistDoorAfterWrongTraversal_progressTowardEdge_returnsFalse() { assertFalse(Rs2Walker.shouldBlacklistDoorAfterWrongTraversal( @@ -768,6 +1032,18 @@ public void telemetry_counterIsIndependentOfOtherReasons() { assertEquals(1, Rs2Walker.Telemetry.partialRetryCount.get()); } + @Test + public void telemetry_recordOffPathRecalcDeferred_setsReasonButDoesNotCountAsRecalc() { + Rs2Walker.Telemetry.recordOffPathRecalcDeferred("route-progress", + new WorldPoint(3200, 3200, 0), + new WorldPoint(3210, 3210, 0), + 20); + + assertEquals(1, Rs2Walker.Telemetry.offPathRecalcDeferredCount.get()); + assertEquals("off-path-deferred:route-progress", Rs2Walker.Telemetry.lastReason); + assertEquals(0, Rs2Walker.Telemetry.totalRecalcs()); + } + @Test public void telemetry_reset_clearsUnreachable() { Rs2Walker.Telemetry.recordUnreachable("no-walkable-path", From 51af3342a22275218604fbfd035eede7e3583d77 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Sat, 18 Jul 2026 14:14:48 +0100 Subject: [PATCH 02/48] changed client-thread-guardrail-baseline.txt cold start - hopefuly fixed Mid-route Stalling rs2 walker now accepts adjacent same-plane transport/objct landing --- docs/entity-guides/movement.md | 4 +- .../microbot/util/walker/Rs2Walker.java | 45 ++++++++---- .../util/walker/Rs2WalkerUnitTest.java | 70 ++++++++++++++++--- .../client-thread-guardrail-baseline.txt | 69 ++++++++++-------- 4 files changed, 136 insertions(+), 52 deletions(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 2ed25f0c5d..123d6eadef 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -290,7 +290,7 @@ After a handled transport, avoid expensive path-adjacent or raw transport scans For long-route minimap walking, let the next checkpoint selection happen before the current minimap target is fully consumed. Waiting until the player is only a few tiles from the interim makes the walker visibly stop before issuing the next click; handing off at a moderate remaining distance keeps movement continuous without rapid re-clicking. If an interim clears as close and no nearby route door/transport is pending, issue the next route-aligned continuation click immediately instead of waiting for idle-nudge recovery. Stale-progress checks must also count distance progress toward the actual interim checkpoint, not only smoothed path index progress; sparse smoothed paths can otherwise clear valid raw-path checkpoints as stale while the player is still walking toward them. -Before the first movement click, only scan a small number of immediate route edges for doors or blockers. A door several segments ahead can be handled after the first minimap click moves the player toward it; spending startup time scanning every nearby raw segment creates a visible cold start. +Before the first movement click, avoid timeout-backed speculative segment scans for doors, blockers, rockfalls, or transports. Let the first minimap click move the player toward the route; actual visible doors can still be handled by the dedicated pre-click route-door guard, and steady-state handling can resolve later obstacles once movement has started. Spending startup time scanning every nearby raw segment creates a visible cold start. Continuation clicks that keep an active route moving should be tail-exempt like `interim-in-flight`; otherwise very long routes can exhaust `MAX_PROCESS_WALK_TAIL_ITERATIONS` while still making progress and trigger an unnecessary auto-retry. @@ -298,7 +298,7 @@ Sticky interim targets should also clear when route-index progress goes stale. I When a route-following minimap click is outside the minimap clip, fallback clicks must stay on the raw path. This includes the "clicked but no movement yet" retry after a route click and route-backed direct short-walks near the final destination. A generic "reachable tile closer to target" fallback can select a tile far away from the route in open areas, especially near fences and the final destination. Raw fallback must be anchored from the stabilized route index, not a fresh nearest-raw-tile lookup, or the walker can snap backward to an already-travelled branch. -For adjacent same-plane shortcuts, do not treat any movement away from the origin as success. Some shortcuts, such as stepping stones, can fail and place the player on a fallback tile; once the player is settled away from the expected destination, stop the landing wait and replan from the actual tile. +For adjacent same-plane shortcuts, do not treat any movement away from the origin as success. Some shortcuts, such as stepping stones, can fail and place the player on a fallback tile; once the player is settled away from the expected destination, stop the landing wait and replan from the actual tile. If the player is settled within one tile of the expected destination and is no longer on the origin, accept the landing instead of waiting for an exact tile that server pathing may not choose. ## 14. Keep optimistic recovery clicks route-backed and paced diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 68df3dceea..9de5153b3a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -156,8 +156,6 @@ public static WorldPoint getCurrentTarget() { private static final int PATHFINDER_DONE_POLL_WAIT_MS = 1200; private static final int PATHFINDER_DONE_RETRY_SLEEP_MIN_MS = 120; private static final int PATHFINDER_DONE_RETRY_SLEEP_MAX_MS = 220; - private static final long STARTUP_FIRST_CLICK_BUDGET_MS = 2200L; - private static final int STARTUP_PRECLICK_DOOR_SCAN_LOOKAHEAD_EDGES = 2; private static final int POST_DOOR_FAST_CLICK_MAX_EUCLIDEAN = 13; private static final int POST_DOOR_EDGE_NUDGE_MAX_FROM_PLAYER = 3; private static final int POST_DOOR_EDGE_NUDGE_WAIT_MS = 1200; @@ -433,13 +431,7 @@ private static WalkerPhase currentWalkerPhase() { if (firstMovementClickMarked) { return WalkerPhase.STEADY; } - long startedAt = walkSessionStartedAtMs; - if (startedAt <= 0) { - return WalkerPhase.STEADY; - } - return (System.currentTimeMillis() - startedAt) <= STARTUP_FIRST_CLICK_BUDGET_MS - ? WalkerPhase.STARTUP - : WalkerPhase.STEADY; + return WalkerPhase.STARTUP; } private static ObstaclePolicy obstaclePolicyForCurrentPhase() { @@ -460,7 +452,7 @@ static boolean shouldSkipStartupPreclickSegmentHandlers(boolean startupBeforeFir if (recentDoorAttemptNearSegment || doorSettling || recoveryInFlight) { return false; } - return segmentIdx > routeStartIdx + STARTUP_PRECLICK_DOOR_SCAN_LOOKAHEAD_EDGES; + return true; } /** @@ -1622,13 +1614,13 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { if (skipPostTransportSegmentHandlers || skipStartupPreclickSegmentHandlers) { if (skipStartupPreclickSegmentHandlers) { markStartupPhase("preclick_segment_handler_skip", target, - "i=" + i + " reason=startup_preclick_budget"); + "i=" + i + " reason=startup_before_first_click"); } tmarkPostTransport("post_transport_segment_handler_skip", target, "i=" + i + " reason=" + (skipPostTransportSegmentHandlers ? "no_nearby_planned_transport" - : "startup_preclick_budget")); + : "startup_before_first_click")); } else { long segmentHandlerStartAt = System.currentTimeMillis(); int rawI = (i < smoothedToRaw.length) ? smoothedToRaw[i] : 0; @@ -7932,6 +7924,7 @@ private static boolean waitForPostHandleObjectLanding(Transport transport, int maxInclusive) { long waitStartedAt = System.currentTimeMillis(); AtomicBoolean settledAwayFromAdjacentDestination = new AtomicBoolean(false); + AtomicBoolean settledNearAdjacentDestination = new AtomicBoolean(false); boolean completed = sleepUntil(() -> { if (isPlayerWithinChebyshevInclusive(destWait, maxInclusive)) { return true; @@ -7945,6 +7938,10 @@ private static boolean waitForPostHandleObjectLanding(Transport transport, || Rs2Player.isMoving() || Rs2Player.isAnimating()) { return false; } + if (isSettledNearAdjacentSamePlaneLanding(transport, playerLoc, destWait, maxInclusive)) { + settledNearAdjacentDestination.set(true); + return true; + } WorldPoint origin = transport == null ? null : transport.getOrigin(); boolean settledAwayFromOrigin = origin != null && playerLoc.distanceTo2D(origin) > 1; if (playerLoc.distanceTo2D(destWait) > Math.max(1, maxInclusive) @@ -7955,6 +7952,11 @@ private static boolean waitForPostHandleObjectLanding(Transport transport, return false; }, POST_HANDLE_OBJECT_LANDING_WAIT_MS); + if (settledNearAdjacentDestination.get()) { + WebWalkLog.spInfo("post-handleObject adjacent landing accepted | dest={} at={}", + compactWorldPoint(destWait), compactWorldPoint(Rs2Player.getWorldLocation())); + return true; + } if (settledAwayFromAdjacentDestination.get()) { WebWalkLog.spInfo("post-handleObject adjacent landing failed | dest={} at={}", compactWorldPoint(destWait), compactWorldPoint(Rs2Player.getWorldLocation())); @@ -7963,6 +7965,25 @@ private static boolean waitForPostHandleObjectLanding(Transport transport, return completed; } + static boolean isSettledNearAdjacentSamePlaneLanding(Transport transport, + WorldPoint playerLoc, + WorldPoint destWait, + int maxInclusive) { + if (!isAdjacentSamePlaneTransport(transport) + || playerLoc == null + || destWait == null + || playerLoc.getPlane() != destWait.getPlane()) { + return false; + } + WorldPoint origin = transport.getOrigin(); + if (origin == null || playerLoc.equals(origin)) { + return false; + } + int destinationDistance = playerLoc.distanceTo2D(destWait); + return destinationDistance <= Math.max(1, maxInclusive) + && playerLoc.distanceTo2D(origin) > 0; + } + /** * Handles the transportation process specifically for instances of PohTransport. * Any Transport param that reaches this is assumed to be a PohTransport. diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index b0f01f0ac5..5de440bd1e 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -116,6 +116,63 @@ public void shouldRecalculatePathAfterTransport_skipsAdjacentSamePlaneTransport( assertFalse(Rs2Walker.shouldRecalculatePathAfterTransport(door)); } + @Test + public void isSettledNearAdjacentSamePlaneLanding_acceptsNearDestinationOffOrigin() { + Transport door = new Transport( + new WorldPoint(3152, 3363, 0), + new WorldPoint(3153, 3363, 0), + "Door", + TransportType.TRANSPORT, + false, + "Open", + "Door", + 136); + + assertTrue(Rs2Walker.isSettledNearAdjacentSamePlaneLanding( + door, + new WorldPoint(3154, 3363, 0), + new WorldPoint(3153, 3363, 0), + 0)); + } + + @Test + public void isSettledNearAdjacentSamePlaneLanding_rejectsOriginTile() { + Transport door = new Transport( + new WorldPoint(3152, 3363, 0), + new WorldPoint(3153, 3363, 0), + "Door", + TransportType.TRANSPORT, + false, + "Open", + "Door", + 136); + + assertFalse(Rs2Walker.isSettledNearAdjacentSamePlaneLanding( + door, + new WorldPoint(3152, 3363, 0), + new WorldPoint(3153, 3363, 0), + 0)); + } + + @Test + public void isSettledNearAdjacentSamePlaneLanding_rejectsTilesTooFarFromDestination() { + Transport door = new Transport( + new WorldPoint(3152, 3363, 0), + new WorldPoint(3153, 3363, 0), + "Door", + TransportType.TRANSPORT, + false, + "Open", + "Door", + 136); + + assertFalse(Rs2Walker.isSettledNearAdjacentSamePlaneLanding( + door, + new WorldPoint(3155, 3363, 0), + new WorldPoint(3153, 3363, 0), + 0)); + } + @Test public void shouldRecalculatePathAfterTransport_includesLongDistanceTransport() { Transport ship = new Transport( @@ -749,10 +806,10 @@ public void routeMovementClickPhase_labelsContinuationSeparatelyFromRecovery() { } @Test - public void shouldSkipStartupPreclickSegmentHandlers_skipsBeyondStartupLookahead() { + public void shouldSkipStartupPreclickSegmentHandlers_skipsBeforeFirstMovementClick() { assertTrue(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( true, - 8, + 5, 5, false, false, @@ -760,14 +817,7 @@ public void shouldSkipStartupPreclickSegmentHandlers_skipsBeyondStartupLookahead } @Test - public void shouldSkipStartupPreclickSegmentHandlers_keepsImmediateAndDoorRecoveryEdges() { - assertFalse(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( - true, - 7, - 5, - false, - false, - false)); + public void shouldSkipStartupPreclickSegmentHandlers_keepsDoorRecoveryAndSteadyEdges() { assertFalse(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( true, 8, diff --git a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt index 3395d9f6e9..a2605ab88d 100644 --- a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt +++ b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt @@ -720,10 +720,18 @@ net.runelite.client.plugins.microbot.util.walker.Rs2MiniMap#worldToMinimap(World net.runelite.client.plugins.microbot.util.walker.Rs2MiniMap#worldToMinimap(WorldPoint): Point -> net.runelite.api.WorldView#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2MiniMap#worldToMinimap(WorldPoint): Point -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#adjacentSamePlaneTransportSuppressionPoints(Transport, TileObject): Set -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#charterWidgetMatchesDestination(Widget, String): boolean -> net.runelite.api.widgets.Widget#getActions(): String[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#charterWidgetMatchesDestination(Widget, String): boolean -> net.runelite.api.widgets.Widget#getName(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#charterWidgetMatchesDestination(Widget, String): boolean -> net.runelite.api.widgets.Widget#getText(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#closeWorldMap(): boolean -> net.runelite.api.widgets.Widget#getBounds(): Rectangle net.runelite.client.plugins.microbot.util.walker.Rs2Walker#distanceToRegion(int, int): int -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#distanceToRegion(int, int): int -> net.runelite.api.WorldView#getPlane(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#doorObjectStillHasAction(TileObject, WorldPoint, WorldPoint, WorldPoint, List, String): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#findCharterDestinationTextWidget(Widget, String): Widget -> net.runelite.api.widgets.Widget#getDynamicChildren(): Widget[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#findCharterDestinationTextWidget(Widget, String): Widget -> net.runelite.api.widgets.Widget#getStaticChildren(): Widget[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#findCharterDestinationTextWidget(Widget, String): Widget -> net.runelite.api.widgets.Widget#isHidden(): boolean +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#findClickableCharterWidget(Widget, Widget): Widget -> net.runelite.api.widgets.Widget#getParent(): Widget +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getFirstWidgetAction(Widget): String -> net.runelite.api.widgets.Widget#getActions(): String[] net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.CollisionData#getFlags(): int[][] net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.WorldView#getCollisionMaps(): CollisionData[] @@ -735,9 +743,6 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getTile(WorldPoint): net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getTile(WorldPoint): Tile -> net.runelite.api.WorldView#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getTile(WorldPoint): Tile -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getTransportsForPath(List, int, TransportType, boolean): List -> net.runelite.api.Client#getTopLevelWorldView(): WorldView -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#handleCharterShip(Transport): boolean -> net.runelite.api.widgets.Widget#getDynamicChildren(): Widget[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#handleCharterShip(Transport): boolean -> net.runelite.api.widgets.Widget#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#handleCharterShip(Transport): boolean -> net.runelite.api.widgets.Widget#getIndex(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#handleDoors(List, int, boolean): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#handleDoors(List, int, boolean): boolean -> net.runelite.api.ObjectComposition#getImpostorIds(): int[] net.runelite.client.plugins.microbot.util.walker.Rs2Walker#handleDoors(List, int, boolean): boolean -> net.runelite.api.ObjectComposition#getName(): String @@ -771,7 +776,11 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#hasDoorCandidateOnRaw net.runelite.client.plugins.microbot.util.walker.Rs2Walker#hasDoorCandidateOnRawSegment(List, int): boolean -> net.runelite.api.WorldView#getScene(): Scene net.runelite.client.plugins.microbot.util.walker.Rs2Walker#hasLineOfSightBetween(WorldPoint, WorldPoint): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#hasLineOfSightBetween(WorldPoint, WorldPoint): boolean -> net.runelite.api.coords.WorldArea#hasLineOfSightTo(WorldView, WorldArea): boolean +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#hasWidgetActions(Widget): boolean -> net.runelite.api.widgets.Widget#getActions(): String[] net.runelite.client.plugins.microbot.util.walker.Rs2Walker#interactingActorNearWalkablePath(): boolean -> net.runelite.api.Actor#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#invokeCharterDestinationWidget(Widget, String): boolean -> net.runelite.api.widgets.Widget#getBounds(): Rectangle +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#invokeCharterDestinationWidget(Widget, String): boolean -> net.runelite.api.widgets.Widget#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#invokeCharterDestinationWidget(Widget, String): boolean -> net.runelite.api.widgets.Widget#getIndex(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isCatalogTransportObject(TileObject): boolean -> net.runelite.api.TileObject#getId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isCatalogTransportObject(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isCloseToRegion(int, int, int): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView @@ -788,33 +797,35 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObj net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.ObjectComposition#getName(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$42(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$43(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleCharterShip$181(Widget): boolean -> net.runelite.api.widgets.Widget#getActions(): String[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$40(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$41(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$187(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$158(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$160(String): boolean -> net.runelite.api.widgets.Widget#getText(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$136(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$142(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$142(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$143(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$143(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$22(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$116(int, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$116(int, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$118(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$119(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$121(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$123(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$124(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$150(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$151(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$40(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$41(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$38(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$39(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$185(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$154(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$156(String): boolean -> net.runelite.api.widgets.Widget#getText(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$132(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$138(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$138(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$139(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$139(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$21(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$112(int, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$112(int, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$114(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$115(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$116(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$117(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$119(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$146(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$147(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$2(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$3(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$69(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$68(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.WorldView#isInstance(): boolean +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#markNearbyDoorFamilyOpened(TileObject, WorldPoint, String, int): void -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#maybeCanvasNudgeAfterDoor(WorldPoint, int, List): void -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#maybeCanvasNudgeAfterDoor(WorldPoint, int, List): void -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint @@ -848,6 +859,8 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastCanvas(WorldP net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastCanvas(WorldPoint, boolean): boolean -> net.runelite.api.WorldView#getPlane(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastCanvas(WorldPoint, boolean): boolean -> net.runelite.api.WorldView#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastCanvas(WorldPoint, boolean): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastCanvasOnScreenOnly(WorldPoint, boolean): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastCanvasOnScreenOnly(WorldPoint, boolean): boolean -> net.runelite.api.WorldView#getPlane(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastLocal(LocalPoint): void -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastLocal(LocalPoint): void -> net.runelite.api.WorldView#getPlane(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkNextToInstance(GameObject): void -> net.runelite.api.Client#getTopLevelWorldView(): WorldView From 82b537720efb5e5e7ed1314df8e977e617c02d76 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Sun, 19 Jul 2026 15:28:45 +0100 Subject: [PATCH 03/48] summary for all current new commits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds a per-loop `WalkLoopSnapshot` so route progress decisions reuse a stable player location and reachable-tile snapshot during each walker loop. - Reworks closest-path-index and route-progress tracking to prefer reachable distance when available, fall back safely when reachability is empty, and preserve forward progress on routes that double back near earlier branches. - Keeps primary minimap clicks, direct short-walk fallback, and unreachable recovery anchored to the raw shortest-path route before using smoothed waypoint nudges or generic fallbacks. - Adds raw-route target selection helpers with candidate predicates so recovery and continuation clicks stay on known walkable/unloaded route tiles. - Defers off-path recalculation while movement, interaction, animation, door/transport settling, recent clicks, route progress, or interim checkpoint progress indicate the player is still advancing. - Adds sticky interim checkpoint tracking and early `interim-in-flight` yields before broad scans, current-tile transport checks, direct short-walk attempts, and path segment scans. - Hints route progress after clicked-ahead checkpoints so later route anchoring does not snap back to nearby already-travelled branches. - Improves startup behavior by skipping speculative timeout-backed obstacle scans before the first movement click, while still allowing immediate planned transport steps to dispatch. - Suppresses active route idle nudges and stall recovery clicks when the current route segment is an explicit transport edge. - Tightens door/gate handling so wrong-traversal blacklisting only happens when the player started near the attempted door edge. - Accepts adjacent same-plane transport/object landings when the player settles near the expected destination instead of requiring the exact destination tile. - Improves charter ship handling by recursively resolving destination widgets, invoking the clickable widget/action, and confirming travel prompts when needed. - Updates `ShortestPathPlugin` route cleanup, pathfinder inventory quantity checks, WebWalk logging volume, movement docs, unit coverage, and the client-thread guardrail baseline. • Rs2Walker.java: immediate planned transports now suppress idle/stall recovery, so first-step teleports like Home Teleport should fire before pointless movement clicks. • Rs2Walker.java: active interim route clicks now yield before broad scans, reducing stop-start spam. • Rs2Walker.java: normal route clicks prefer raw shortest-path tiles instead of side/fallback tiles. • Rs2Walker.java: public walker entrypoints now reject client-thread calls before lock waits or player/tile reads. • Rs2WalkerUnitTest.java: added focused tests for route anchoring, raw-route click selection, interim yielding, and immediate-transport idle nudge suppression. • movement.md: documented the new walker gotchas Implemented the Al Kharid toll gate fix. What changed: • Added Pay-toll(10gp) transports for all four gate tiles in transports.tsv. • Added quest-free Open gate transports for Prince Ali Rescue completion. • Replaced the old quest-only tile restriction with blocked edge rules, so non-quest accounts can route through if they have 10 coins. • Walker now treats paid TRANSPORT rows as currency transports for item/banking checks. • Added special handling for Al Kharid toll gate confirmation: it uses Pay-toll(10gp) and clicks Yes, okay / Yes if prompted. I did not add the “talk to guard” fallback yet; this handles the cleaner object interaction path first. --- docs/entity-guides/movement.md | 91 +++- .../microbot/util/walker/Rs2Walker.java | 446 ++++++++++++++---- .../banking/Rs2WalkerBankingPlanner.java | 6 +- .../microbot/shortestpath/blocked_edges.tsv | 2 + .../microbot/shortestpath/restrictions.tsv | 8 +- .../microbot/shortestpath/transports.tsv | 8 + .../shortestpath/ShortestPathCoreTest.java | 72 +++ .../util/walker/Rs2WalkerUnitTest.java | 161 +++++++ 8 files changed, 684 insertions(+), 110 deletions(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 123d6eadef..235384a743 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -237,9 +237,9 @@ if (isStuckTooLong()) { For long open routes, retarget before the player fully stops when they are already close to the interim checkpoint, and keep normal minimap clicks slightly inside the observed minimap edge. This reduces visible stop/start pauses and outside-clip fallback clicks without reintroducing rapid click thrash. -## 12. Do not let optimistic recovery override unresolved door blockers +## 12. Do not let local recovery override unresolved door blockers -Unreachable-tile recovery is useful for outdoor false negatives, but in tight rooms it can fight the door resolver. If a route edge still has a door-like scene object on or adjacent to the raw path, suppress broad minimap recovery and let the door scanners retry after their normal cooldowns. Do not permanently blacklist a path-adjacent fallback door just because one attempt traversed the wrong way; in small door clusters the same object may be the correct blocker again once the player has moved to the other side. +Local-reachability recovery is useful for outdoor false negatives, but in tight rooms it can fight the door resolver. If a route edge still has a door-like scene object on or adjacent to the raw path, suppress broad minimap recovery and let the door scanners retry after their normal cooldowns. Do not permanently blacklist a path-adjacent fallback door just because one attempt traversed the wrong way; in small door clusters the same object may be the correct blocker again once the player has moved to the other side. **Why this matters:** In POH-style tight rooms with several doors close together, a fallback door click can move the player away from the intended route. If that door tile is session-blacklisted and optimistic recovery keeps clicking route tiles beyond the blocker, the walker loops around the room until a user manually opens the final door. @@ -257,7 +257,7 @@ clickOptimisticRecoveryTarget(); **Where this applies:** `Rs2Walker.processWalk` unreachable-tile handling, `tryResolvePathAdjacentBlocker`, and any fallback that issues minimap recovery clicks after door/path-adjacent scans fail. -**Defensive check:** Reproduce a route through a small room with three nearby doors and a POH portal. The walker should retry the route-door blocker and avoid repeated `unreachable optimistic recovery` loops around the room; it should not need the user to manually open the final door. +**Defensive check:** Reproduce a route through a small room with three nearby doors and a POH portal. The walker should retry the route-door blocker and avoid repeated `route-backed local recovery click` loops around the room; it should not need the user to manually open the final door. ## 13. Stall recalculation must also issue fresh movement @@ -300,9 +300,9 @@ When a route-following minimap click is outside the minimap clip, fallback click For adjacent same-plane shortcuts, do not treat any movement away from the origin as success. Some shortcuts, such as stepping stones, can fail and place the player on a fallback tile; once the player is settled away from the expected destination, stop the landing wait and replan from the actual tile. If the player is settled within one tile of the expected destination and is no longer on the origin, accept the landing instead of waiting for an exact tile that server pathing may not choose. -## 14. Keep optimistic recovery clicks route-backed and paced +## 14. Keep local recovery clicks route-backed and paced -Unreachable-tile recovery is a fallback for bounded reachability false negatives, not a license to pick an arbitrary minimap point. Recovery clicks should use the same route-backed raw-path fallback as normal route movement, then store the actual clicked target as the sticky interim checkpoint. After issuing the click, wait only for movement to start or the checkpoint/goal to be reached; do not wait for a full idle cycle before returning to the walk loop. +Local-reachability recovery is a fallback for bounded reachability false negatives, not a license to pick an arbitrary minimap point. Recovery clicks should use the same route-backed raw-path fallback as normal route movement, then store the actual clicked target as the sticky interim checkpoint. After issuing the click, wait only for movement to start or the checkpoint/goal to be reached; do not wait for a full idle cycle before returning to the walk loop. **Why this matters:** Bounded local reachability can report a valid route tile as unreachable even though the server pathfinder can still walk toward it. Arbitrary or repeated recovery clicks can pull the player away from the planned route and create visible stop-start movement. @@ -318,8 +318,85 @@ if (clickedTarget != null) { } ``` -**Where this applies:** `Rs2Walker.processWalk` unreachable-smoothed-tile recovery, route-backed direct short-walks, and any fallback that runs after local reachability says a route tile is not currently reachable. +**Where this applies:** `Rs2Walker.processWalk` local-reachability recovery, route-backed direct short-walks, and any fallback that runs after local reachability says a route tile is not currently reachable. -**Defensive check:** Exercise a long outdoor route and a route with gates or transports. Recovery logs should select route-backed points, and there should be no long idle pause between `unreachable optimistic recovery` and the next route-aligned movement. +**Defensive check:** Exercise a long outdoor route and a route with gates or transports. Recovery logs should select route-backed points, and there should be no long idle pause between `route-backed local recovery click` and the next route-aligned movement. After recovery sets a sticky interim target, do not issue another optimistic recovery while that interim is still active and movement/progress is fresh. Yield as `interim-in-flight` or another tail-exempt movement state until the checkpoint is close, stale, or expired. Otherwise the walker can loop through several recovery clicks while the player is already moving, especially when local reachability reports the next smoothed tile as unreachable. + +## 15. Keep primary route clicks on the raw route + +When a shortest-path raw route exists, choose the next minimap target from that raw route before applying smoothed-waypoint wall-distance nudges, bounded reachability shortcuts, or generic directional fallbacks. Sideways reachable tiles can be valid server walk targets while still being the wrong side of a fence, gate, or corridor corner. Generic fallback is only appropriate when no route-backed raw point is available. + +**Why this matters:** Tight routes near gates and fences can fail when the walker clicks a tile left or right of the drawn route line. The game then chooses its own path around the obstacle, which fights the planned door/transport handlers and produces stop-start recovery. + +**Pattern to follow:** + +```java +WorldPoint rawTarget = findFurthestRawPathPointMatching(rawPath, playerLoc, reach, rawAnchor, + Rs2Walker::isKnownWalkableOrUnloaded); +WorldPoint clickTarget = rawTarget != null ? rawTarget : getPointWithWallDistance(smoothedTarget); +``` + +**Where this applies:** `Rs2Walker.processWalk`, recovery clicks after false unreachable reports, route continuation clicks, direct short-walk fallbacks, and any minimap click helper used while a shortest-path raw route exists. + +**Defensive check:** Unit-test raw-route target selection with a route that doubles back near an earlier branch; the selected tile must stay at or ahead of the anchored raw route index. + +## 16. Yield before scans while an interim route click is in flight + +Sticky interim targets only reduce click thrash if they are checked before broad route scans. When a fresh interim checkpoint is still far away and the player is moving or has very recent checkpoint progress, yield before raw-scene scans, current-tile transport scans, direct short-walk attempts, and path segment scans. Resume normal route work once the checkpoint is close, stale, expired, on another plane, or movement has genuinely stopped. + +**Why this matters:** Long post-transport routes can otherwise run several no-op scans and select several small follow-up clicks while the previous minimap flag is still carrying the player. That looks like stop-start walking and burns tail iterations even though the route is making progress. + +**Pattern to follow:** + +```java +if (shouldYieldForActiveRouteInterim(playerLoc, path, nowMs)) { + exitReason = "interim-in-flight"; + continue; +} +``` + +**Where this applies:** `Rs2Walker.processWalk` before broad raw-scene handling, current-tile transport handling, direct short-walk handling, and the main path loop. + +**Defensive check:** Start a long route immediately after a transport. While the player is still moving toward the active minimap checkpoint, the walker should log a tail-exempt `interim-in-flight` yield instead of repeated `post_transport_path_selected` clicks for nearby path indices. + +## 17. Dispatch immediate planned transports before idle nudges + +When the current route index is an explicit shortest-path transport edge, let the segment transport handler run even during startup, before route idle nudges or stall recovery clicks. Keep startup door/rockfall probes skipped, but do not postpone teleports, ships, ladders, or other catalog-backed route transports that start at the player's current segment. + +**Why this matters:** Originless spell/item teleports can be the first edge in a route. If startup logic suppresses the segment handler and idle recovery runs first, the walker can sit on the origin, spam no-op route nudges, trigger stall recovery, and only then cast the teleport. + +**Pattern to follow:** + +```java +boolean immediateTransport = hasImmediatePlannedTransportStep(path, routeStartIdx, playerLoc); +if (shouldRunActiveRouteIdleNudge(idleNudgeDue, immediateTransport)) { + tryIssueRouteRecoveryClick(rawPath, path, target, "active route idle nudge"); +} +``` + +**Where this applies:** `Rs2Walker.processWalk` startup handling, active route idle nudges, stall recovery clicks, and segment transport dispatch. + +**Defensive check:** Start a route whose first planned edge is Home Teleport. Logs should show `transport_handoff_enter` for `TELEPORTATION_SPELL` without several `active route idle nudge: clicked=false` entries first. + +## 18. Model conditional paid gates as transports plus blocked edges + +When a gate can be crossed by either a quest unlock or a currency payment, do not model the gate tiles as quest-only restrictions. A tile restriction cannot express "quest complete OR pay coins", and it can prevent the walker from reaching the paid transport origin. Model each crossing as explicit paid/free transports and add a blocked edge override so normal walking cannot bypass the unavailable transport. + +**Why this matters:** The Lumbridge-to-Al Kharid toll gate can be opened freely after Prince Ali Rescue or paid through with 10 coins. A quest-only restriction blocks the paid route for accounts without the quest, while no edge block can let the pathfinder walk through the gate without paying. + +**Pattern to follow:** + +```java +// Wrong: restrict both sides of the gate to one quest state. +3267 3227 0 Prince Ali Rescue + +// Right: transport data decides availability; blocked_edges prevents free walking. +3267 3227 0 3268 3227 0 Pay-toll(10gp);Gate;2786 ... 10 Coins +3267 3227 0 3268 3227 0 Open;Gate;2786 ... Prince Ali Rescue +``` + +**Where this applies:** `transports.tsv`, `blocked_edges.tsv`, `restrictions.tsv`, `PathfinderConfig`, and `Rs2Walker.handleTransports`. + +**Defensive check:** Add resource tests that assert both paid and quest-free transports load, the gate tiles are not quest-only restricted, and the gate edge is blocked without a usable transport. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 9de5153b3a..9afa31c64c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -48,6 +48,7 @@ import net.runelite.client.plugins.microbot.util.leaguetransport.SeasonalTransportHandlers; import net.runelite.client.plugins.microbot.util.logging.Rs2LogRateLimit; import java.util.function.BooleanSupplier; +import java.util.function.Predicate; import org.slf4j.event.Level; import net.runelite.client.plugins.microbot.util.poh.PohTeleports; import net.runelite.client.plugins.microbot.util.poh.PohTransport; @@ -206,6 +207,16 @@ public static WorldPoint getCurrentTarget() { private static volatile long routeProgressAdvancedAtMs = 0L; private static final java.util.Deque expectedTransportDestinations = new ArrayDeque<>(); private static final Set startupPhasesLogged = ConcurrentHashMap.newKeySet(); + private static final Set AL_KHARID_TOLL_GATE_OBJECT_IDS = Set.of( + net.runelite.api.ObjectID.CITY_GATE_2786, + net.runelite.api.ObjectID.CITY_GATE_2787, + net.runelite.api.ObjectID.CITY_GATE_2788, + net.runelite.api.ObjectID.CITY_GATE_2789); + private static final Set AL_KHARID_TOLL_GATE_POINTS = Set.of( + new WorldPoint(3267, 3227, 0), + new WorldPoint(3267, 3228, 0), + new WorldPoint(3268, 3227, 0), + new WorldPoint(3268, 3228, 0)); /** * Max Chebyshev "radius" for Quetzal / near-destination checks — guards use {@code distanceTo2D < OFFSET}. @@ -434,6 +445,15 @@ private static WalkerPhase currentWalkerPhase() { return WalkerPhase.STARTUP; } + private static boolean isClientThread() { + Client client = Microbot.getClient(); + return client != null && client.isClientThread(); + } + + private static int reachedDistanceOrDefault() { + return config != null ? config.reachedDistance() : 10; + } + private static ObstaclePolicy obstaclePolicyForCurrentPhase() { return currentWalkerPhase() == WalkerPhase.STARTUP ? STARTUP_OBSTACLE_POLICY @@ -455,6 +475,11 @@ static boolean shouldSkipStartupPreclickSegmentHandlers(boolean startupBeforeFir return true; } + static boolean shouldRunActiveRouteIdleNudge(boolean idleNudgeDue, + boolean immediateRouteTransportPending) { + return idleNudgeDue && !immediateRouteTransportPending; + } + /** * Same-plane Chebyshev distance from player to {@code dest} strictly less than {@code maxChebyshevExclusive}. * Requires matching {@link WorldPoint#getPlane()} before using {@link WorldPoint#distanceTo2D} — that method only @@ -921,7 +946,7 @@ public static int totalRecalcs() { ); public static boolean walkTo(int x, int y, int plane) { - return walkTo(x, y, plane, config.reachedDistance()); + return walkTo(x, y, plane, reachedDistanceOrDefault()); } /** @@ -937,7 +962,7 @@ public static boolean walkTo(int x, int y, int plane, int distance) { * result is {@code false}, same as any non-arrival outcome. */ public static boolean walkTo(WorldPoint target) { - return walkWithState(target, config.reachedDistance()) == WalkerState.ARRIVED; + return walkWithState(target, reachedDistanceOrDefault()) == WalkerState.ARRIVED; } /** @@ -991,6 +1016,10 @@ public static WalkerState walkWithState(WorldPoint target, int distance) { log.warn("[Walker] walk rejected: null target"); return WalkerState.EXIT; } + if (isClientThread()) { + log.warn("Please do not call the walker from the main thread"); + return WalkerState.EXIT; + } if (!walkerLock.tryLock()) { log.warn("[Walker] concurrent walk request detected, waiting for in-flight walk (held by {}); new target={}", Thread.currentThread().getName(), target); @@ -1031,6 +1060,11 @@ public static WalkerState walkWithStateTry(WorldPoint target, int distance, long log.warn("[Walker] walk rejected: null target"); return WalkerState.EXIT; } + if (isClientThread()) + { + log.warn("Please do not call the walker from the main thread"); + return WalkerState.EXIT; + } if (lockWaitMs < 0) { throw new IllegalArgumentException("lockWaitMs must be >= 0"); @@ -1080,6 +1114,10 @@ public static WalkerState walkWithStateTry(WorldPoint target, int distance, long */ private static WalkerState walkWithStateInternal(WorldPoint target, int distance) { Objects.requireNonNull(target, "walk target"); + if (isClientThread()) { + log.warn("Please do not call the walker from the main thread"); + return WalkerState.EXIT; + } WorldPoint playerLocWalk = Rs2Player.getWorldLocation(); if (playerLocWalk == null) { return WalkerState.MOVING; @@ -1120,11 +1158,6 @@ private static WalkerState walkWithStateInternal(WorldPoint target, int distance idleNudgeStationarySinceMs = System.currentTimeMillis(); lastActiveRouteIdleNudgeAtMs = 0L; - if (Microbot.getClient().isClientThread()) { - log.warn("Please do not call the walker from the main thread"); - return WalkerState.EXIT; - } - closeWorldMap(); if (Rs2Bank.isOpen()) { Rs2Bank.closeBank(); @@ -1138,7 +1171,7 @@ private static WalkerState walkWithStateInternal(WorldPoint target, int distance * @return */ public static WalkerState walkWithState(WorldPoint target) { - return walkWithState(target, config.reachedDistance()); + return walkWithState(target, reachedDistanceOrDefault()); } /** @@ -1306,6 +1339,9 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part } } + int earlyRouteStartIdx = stabilizeRouteProgressIndex(path, walkLoop.closestTileIndex(path), target, walkLoop.playerLoc); + boolean immediateRouteTransportPending = hasImmediatePlannedTransportStep(path, earlyRouteStartIdx, walkLoop.playerLoc); + // Do not clear walk target while a sticky minimap interim is active — breaks // isWalkCancelled and forces EXIT while the flag is still carrying the player. // Partial paths end at an intermediate waypoint (dst still far from {@code target}); @@ -1349,18 +1385,25 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part lastMovedTimeMs = System.currentTimeMillis(); stuckCount = 0; clearInterimTarget("stall-recalc"); - setTarget(target); - if (!Rs2Player.isMoving() && !Rs2Player.isAnimating() && !Rs2Player.isInteracting()) { + if (immediateRouteTransportPending) { + WebWalkLog.spDebug("stall_recovery_suppressed | reason=immediate-route-transport idx={}", earlyRouteStartIdx); + } else if (!Rs2Player.isMoving() && !Rs2Player.isAnimating() && !Rs2Player.isInteracting()) { + setTarget(target); tryIssueRouteRecoveryClick(rawPath, path, target, "stall recovery click"); + continue; + } else { + setTarget(target); + continue; } - continue; } - if (shouldIssueActiveRouteIdleNudge - && tryIssueRouteRecoveryClick(rawPath, path, target, "active route idle nudge")) { - lastAttemptedMinimapClick = null; - lastAttemptedMinimapClickOk = false; - lastAttemptedMinimapClickAtMs = 0L; - continue; + if (shouldRunActiveRouteIdleNudge(shouldIssueActiveRouteIdleNudge, immediateRouteTransportPending)) { + if (tryIssueRouteRecoveryClick(rawPath, path, target, "active route idle nudge")) { + lastAttemptedMinimapClick = null; + lastAttemptedMinimapClickOk = false; + lastAttemptedMinimapClickAtMs = 0L; + continue; + } + lastActiveRouteIdleNudgeAtMs = System.currentTimeMillis(); } if (stuckCount > 10) { var reachable = Rs2Tile.getReachableTilesFromTile(Rs2Player.getWorldLocation(), 5).keySet(); @@ -1462,6 +1505,31 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { Map doorEdgesAttemptedThisTail = new HashMap<>(); ObstaclePolicy startupPolicy = obstaclePolicyForCurrentPhase(); + WorldPoint activeInterimPlayer = Rs2Player.getWorldLocation(); + long activeInterimNowMs = System.currentTimeMillis(); + if (!Rs2Player.isInteracting() + && !Rs2Player.isAnimating() + && !isDoorInteractionSettling() + && !isTransportInteractionSettling() + && (target == null + || activeInterimPlayer == null + || activeInterimPlayer.distanceTo(target) > immediateFinishTh) + && shouldYieldForActiveRouteInterim(activeInterimPlayer, path, activeInterimNowMs)) { + exitReason = "interim-in-flight"; + WebWalkLog.earlyExit(exitReason, + activeInterimPlayer, + target, + path.get(path.size() - 1), + indexOfStartPoint, + path.size()); + walkerDiag("tail exempt exitReason=%s tailBefore=%d early=true interim=%s", + exitReason, + processWalkTail, + interimTargetWp); + processWalkTail--; + continue; + } + boolean postTransportWindow = lastTransportHandledAtMs > 0 && System.currentTimeMillis() - lastTransportHandledAtMs <= POST_TRANSPORT_PATH_TMARK_WINDOW_MS; boolean allowRawSceneScan = startupPolicy.allowBroadRawHandlers() && rawPath != null && path != null; @@ -1597,6 +1665,8 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { boolean upcomingNearbyTransport = hasUpcomingNearbyTransportStep(path, i, playerNearSeg, POST_TRANSPORT_RAW_SCAN_TRANSPORT_LOOKAHEAD_EDGES, POST_TRANSPORT_RAW_SCAN_TRANSPORT_MAX_DIST); + boolean startupBeforeFirstClick = currentWalkerPhase() == WalkerPhase.STARTUP; + boolean immediateSegmentTransportStep = hasImmediatePlannedTransportStep(path, i, playerNearSeg); boolean recentDoorAttemptNearSegment = hasRecentDoorAttemptNearIndex(path, i); boolean skipPostTransportSegmentHandlers = recentTransportWindow && !upcomingNearbyTransport @@ -1604,8 +1674,9 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { && !isDoorInteractionSettling() && !isRecoveryMovementInFlight() && reachableTilesCache.containsKey(currentWorldPoint); - boolean skipStartupPreclickSegmentHandlers = shouldSkipStartupPreclickSegmentHandlers( - currentWalkerPhase() == WalkerPhase.STARTUP, + boolean skipStartupPreclickSegmentHandlers = !immediateSegmentTransportStep + && shouldSkipStartupPreclickSegmentHandlers( + startupBeforeFirstClick, i, indexOfStartPoint, recentDoorAttemptNearSegment, @@ -1625,7 +1696,9 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { long segmentHandlerStartAt = System.currentTimeMillis(); int rawI = (i < smoothedToRaw.length) ? smoothedToRaw[i] : 0; int rawEnd = rawEndForSmoothedIndex(i, smoothedToRaw, rawPath, path); - if (!Rs2Player.isMoving() && !isDoorInteractionSettling() && !isRecoveryMovementInFlight()) { + boolean startupImmediateTransportOnly = startupBeforeFirstClick && immediateSegmentTransportStep; + if (!startupImmediateTransportOnly + && !Rs2Player.isMoving() && !isDoorInteractionSettling() && !isRecoveryMovementInFlight()) { doorOrTransportResult = handleDoorsInRawSegment(rawPath, rawI, rawEnd, obstaclePolicy.segmentDoorTimeoutMs(), doorEdgesAttemptedThisTail, reachableTilesCache); @@ -1641,7 +1714,8 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { boolean allowPathAdjacentProbe = !recentTransportWindow || upcomingNearbyTransport || recentDoorAttemptNearSegment; - if (!Rs2Player.isMoving() && obstaclePolicy.allowPathAdjacentProbe() + if (!startupImmediateTransportOnly + && !Rs2Player.isMoving() && obstaclePolicy.allowPathAdjacentProbe() && allowPathAdjacentProbe) { if (tryHandleBlockingPathObjectsWithTimeout(rawPath, rawI, 5, 10, obstaclePolicy.pathAdjacentProbeTimeoutMs(), doorEdgesAttemptedThisTail)) { @@ -1652,8 +1726,10 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { } } - doorOrTransportResult = handleRockfallInRawSegment(rawPath, rawI, rawEnd, - reachableTilesCache); + if (!startupImmediateTransportOnly) { + doorOrTransportResult = handleRockfallInRawSegment(rawPath, rawI, rawEnd, + reachableTilesCache); + } if (doorOrTransportResult) { tmarkPostTransport("post_transport_segment_handler", target, "stage=rockfall handled=true i=" + i + " ms=" + (System.currentTimeMillis() - segmentHandlerStartAt)); @@ -1661,7 +1737,9 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { break; } - boolean allowSegmentTransportScan = !recentTransportWindow || upcomingNearbyTransport; + boolean allowSegmentTransportScan = !recentTransportWindow + || upcomingNearbyTransport + || immediateSegmentTransportStep; if ((PohTeleports.isInHouse() || !inInstance) && allowSegmentTransportScan) { doorOrTransportResult = handleTransportsInRawSegment(rawPath, rawI, rawEnd); } @@ -1697,7 +1775,7 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { if (playerLoc != null) { int unreachableDist = currentWorldPoint.distanceTo2D(playerLoc); if (unreachableDist <= HANDLER_RANGE + 2) { - log.info("[Walker] unreachable path tile near player: tile={} idx={}/{} player={} target={}", + log.info("[Walker] local reachability miss near player; checking blockers/recovery: tile={} idx={}/{} player={} target={}", currentWorldPoint, i, path.size(), playerLoc, target); int edgeIdx = Math.max(indexOfStartPoint, i - 1); @@ -1761,13 +1839,13 @@ && tryIssueRouteContinuationClick(rawPath, path, target)) { } if (handlePendingDoorNearRawPath(rawPath, obstaclePolicy.unreachableDoorTimeoutMs(), doorEdgesAttemptedThisTail, playerLoc, 2, 14)) { - exitReason = "door-handled-unreachable-raw-scan"; + exitReason = "door-handled-local-reachability-raw-scan"; break; } if (handleDoorsInRawSegment(rawPath, rawEdgeStart, rawEdgeEnd, obstaclePolicy.unreachableDoorTimeoutMs(), doorEdgesAttemptedThisTail, null)) { - exitReason = "door-handled-unreachable"; + exitReason = "door-handled-local-reachability"; break; } if (isRecoveryMovementInFlight()) { @@ -1858,8 +1936,12 @@ && handleUnresolvedDoorNearRawPath(rawPath, rawEdgeStart, recoverTarget = path.get(safeIdx); } int rawAnchorIndex = rawIndexForSmoothedIndex(recoverIdx, smoothedToRaw, rawPath); - WorldPoint rawRecoveryTarget = findFurthestReachableRawPathPoint(rawPath, playerLoc, - recoveryMinimapReach - 1, rawAnchorIndex); + WorldPoint rawRecoveryTarget = inInstance ? null : findFurthestRawPathPointMatching( + rawPath, + playerLoc, + recoveryMinimapReach - 1, + rawAnchorIndex, + Rs2Walker::isKnownWalkableOrUnloaded); if (rawRecoveryTarget != null && !rawRecoveryTarget.equals(playerLoc) && (dangerCfg == null @@ -1888,11 +1970,14 @@ && walkFastCanvas(recoverTarget)) { clickedRecoveryTarget = recoverTarget; log.debug("[Walker] unreachable recovery: scene click -> {}", recoverTarget); } - log.info("[Walker] unreachable optimistic recovery: clicked={} to={} pathTile={} idx={}", + log.info("[Walker] route-backed local recovery click: clicked={} to={} pathTile={} idx={}", clicked, clicked ? clickedRecoveryTarget : recoverTarget, currentWorldPoint, recoverIdx); if (clicked) { - markFirstMovementClick("first_recovery_click", target, playerLoc, + markFirstMovementClick("first_local_recovery_click", target, playerLoc, "to=" + compactWorldPoint(clickedRecoveryTarget)); + hintRouteProgressIndex(path, + Math.min(recoverIdx, i + INTERIM_CLOSE_TILES), + target); lastUnreachableRecoveryClickAtMs = System.currentTimeMillis(); // Sticky interim: subsequent iterations travel toward this point via the // interim-in-flight path instead of re-running the (false-negative) @@ -1912,10 +1997,10 @@ && walkFastCanvas(recoverTarget)) { // spurious stall-recalc right after issuing recovery movement. lastMovedTimeMs = System.currentTimeMillis(); stuckCount = 0; - exitReason = "unreachable-recovery-click"; + exitReason = "local-recovery-click"; break; } - exitReason = "tile-unreachable-near-player"; + exitReason = "local-reachability-miss-no-click"; break; } } @@ -2075,9 +2160,21 @@ && walkFastCanvas(recoverTarget)) { } WorldPoint posBefore = playerLoc; - WorldPoint clickTarget = inInstance ? targetWp : getPointWithWallDistance(targetWp); - if (!inInstance) { - int rawAnchorIndex = rawIndexForSmoothedIndex(i, smoothedToRaw, rawPath); + int rawAnchorIndex = rawIndexForSmoothedIndex(i, smoothedToRaw, rawPath); + WorldPoint rawRouteTarget = inInstance ? null : findFurthestRawPathPointMatching( + rawPath, + playerLoc, + MINIMAP_REACH_EUCLIDEAN - 1, + rawAnchorIndex, + Rs2Walker::isKnownWalkableOrUnloaded); + WorldPoint clickTarget; + if (rawRouteTarget != null && !rawRouteTarget.equals(playerLoc)) { + targetWp = rawRouteTarget; + clickTarget = rawRouteTarget; + } else { + clickTarget = inInstance ? targetWp : getPointWithWallDistance(targetWp); + } + if (!inInstance && rawRouteTarget == null) { WorldPoint rawReachableTarget = findFurthestReachableRawPathPoint(rawPath, playerLoc, MINIMAP_REACH_EUCLIDEAN - 1, rawAnchorIndex); if (!Rs2Tile.isTileReachable(clickTarget) && rawReachableTarget != null) { @@ -2103,7 +2200,6 @@ && walkFastCanvas(recoverTarget)) { "to=" + compactWorldPoint(clickTarget)); } markStartupPhase("click_candidate_found", target, "to=" + compactWorldPoint(clickTarget)); - int rawAnchorIndex = rawIndexForSmoothedIndex(i, smoothedToRaw, rawPath); WorldPoint clickedTarget = clickMiniMapOrFallback(rawPath, clickTarget, playerLoc, MINIMAP_REACH_EUCLIDEAN - 1, rawPath == null || rawPath.isEmpty(), rawAnchorIndex); boolean clicked = clickedTarget != null; @@ -2116,6 +2212,9 @@ && walkFastCanvas(recoverTarget)) { if (clicked) { markFirstMovementClick("first_minimap_click", target, posBefore, "to=" + compactWorldPoint(clickedTarget)); + hintRouteProgressIndex(path, + Math.min(targetIdx, i + INTERIM_CLOSE_TILES), + target); interimTargetWp = clickedTarget; interimTargetIdx = targetIdx; interimSetAtMs = nowMs; @@ -2150,6 +2249,9 @@ && walkFastCanvas(recoverTarget)) { MINIMAP_REACH_EUCLIDEAN - 1, false, rawAnchorIndex); if (routeRetryTarget != null) { routeRetryClicked = true; + hintRouteProgressIndex(path, + Math.min(targetIdx, i + INTERIM_CLOSE_TILES), + target); lastAttemptedMinimapClick = routeRetryTarget; lastAttemptedMinimapClickOk = true; lastAttemptedMinimapClickAtMs = System.currentTimeMillis(); @@ -2670,7 +2772,7 @@ private static WorldPoint walkRawPathMiniMapTargetToward(List rawPat WorldPoint playerLoc, int maxEuclidean, int rawAnchorIndex) { - WorldPoint fallback = findFurthestVisibleReachableRawPathPoint(rawPath, playerLoc, + WorldPoint fallback = findFurthestVisibleKnownRawPathPoint(rawPath, playerLoc, maxEuclidean, rawAnchorIndex); if (fallback == null || fallback.equals(playerLoc) || fallback.equals(target)) { return null; @@ -2752,6 +2854,18 @@ static WorldPoint findFurthestReachableRawPathPoint(List rawPath, WorldPoint playerLoc, int maxEuclidean, int rawAnchorIndex) { + Set reachable = playerLoc == null + ? Collections.emptySet() + : Rs2Tile.getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean)).keySet(); + return findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, + reachable::contains); + } + + static WorldPoint findFurthestRawPathPointMatching(List rawPath, + WorldPoint playerLoc, + int maxEuclidean, + int rawAnchorIndex, + Predicate isCandidate) { if (rawPath == null || rawPath.isEmpty() || playerLoc == null) { return null; } @@ -2763,7 +2877,6 @@ static WorldPoint findFurthestReachableRawPathPoint(List rawPath, int maxSq = maxEuclidean * maxEuclidean; int maxRouteSteps = maxEuclidean + 2; int routeSteps = 0; - Set reachable = Rs2Tile.getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean)).keySet(); WorldPoint best = null; for (int rawIndex = closestRawIndex; rawIndex < rawPath.size(); rawIndex++) { WorldPoint candidate = rawPath.get(rawIndex); @@ -2780,58 +2893,31 @@ static WorldPoint findFurthestReachableRawPathPoint(List rawPath, if (euclideanSq(candidate, playerLoc) > maxSq) { break; } - if (reachable.contains(candidate)) { + if (!candidate.equals(playerLoc) && (isCandidate == null || isCandidate.test(candidate))) { best = candidate; } } return best; } - static WorldPoint findFurthestVisibleReachableRawPathPoint(List rawPath, - WorldPoint playerLoc, - int maxEuclidean) { - return findFurthestVisibleReachableRawPathPoint(rawPath, playerLoc, maxEuclidean, -1); + static WorldPoint findFurthestVisibleKnownRawPathPoint(List rawPath, + WorldPoint playerLoc, + int maxEuclidean) { + return findFurthestVisibleKnownRawPathPoint(rawPath, playerLoc, maxEuclidean, -1); } - static WorldPoint findFurthestVisibleReachableRawPathPoint(List rawPath, - WorldPoint playerLoc, - int maxEuclidean, - int rawAnchorIndex) { + static WorldPoint findFurthestVisibleKnownRawPathPoint(List rawPath, + WorldPoint playerLoc, + int maxEuclidean, + int rawAnchorIndex) { if (rawPath == null || rawPath.isEmpty() || playerLoc == null) { return null; } - int closestRawIndex = rawPathForwardAnchorIndex(rawPath, playerLoc, rawAnchorIndex); - if (closestRawIndex < 0) { - return null; - } - int maxSq = maxEuclidean * maxEuclidean; - int maxRouteSteps = maxEuclidean + 2; - int routeSteps = 0; - Set reachable = Rs2Tile.getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean)).keySet(); - WorldPoint best = null; - for (int rawIndex = closestRawIndex; rawIndex < rawPath.size(); rawIndex++) { - WorldPoint candidate = rawPath.get(rawIndex); - if (candidate == null || candidate.getPlane() != playerLoc.getPlane()) { - break; - } - if (rawIndex > closestRawIndex) { - WorldPoint previous = rawPath.get(rawIndex - 1); - routeSteps += rawPathStepDistance(previous, candidate); - if (routeSteps > maxRouteSteps) { - break; - } - } - if (euclideanSq(candidate, playerLoc) > maxSq) { - break; - } - if (!candidate.equals(playerLoc) - && reachable.contains(candidate) - && isMiniMapClickable(candidate, 5)) { - best = candidate; - } - } - return best; + return findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, + candidate -> !candidate.equals(playerLoc) + && isKnownWalkableOrUnloaded(candidate) + && isMiniMapClickable(candidate, 5)); } private static int rawPathStepDistance(WorldPoint previous, WorldPoint current) { @@ -2943,16 +3029,17 @@ private static boolean tryIssueRouteMovementClick(List rawPath, return false; } int targetIdx = stabilizeRouteProgressIndex(path, getClosestTileIndex(path, playerLoc), target, playerLoc); + int startIdx = Math.max(0, targetIdx); int[] routeSmoothedToRaw = mapSmoothedToRaw(path, rawPath); int rawAnchorIndex = rawIndexForSmoothedIndex(targetIdx, routeSmoothedToRaw, rawPath); - WorldPoint clickTarget = findFurthestReachableRawPathPoint( + WorldPoint clickTarget = findFurthestRawPathPointMatching( rawPath, playerLoc, maxEuclidean, - rawAnchorIndex); + rawAnchorIndex, + Rs2Walker::isKnownWalkableOrUnloaded); if (clickTarget == null) { - int startIdx = Math.max(0, targetIdx); int clickableIdx = findFurthestForwardClickableIndex(path, startIdx, playerLoc, wp -> { Set ts = ShortestPathPlugin.getTransports().get(wp); @@ -2997,6 +3084,9 @@ private static boolean tryIssueRouteMovementClick(List rawPath, target, playerLoc, "to=" + compactWorldPoint(clickedTarget)); + hintRouteProgressIndex(path, + Math.min(targetIdx, startIdx + INTERIM_CLOSE_TILES), + target); interimTargetWp = clickedTarget; interimTargetIdx = targetIdx; interimSetAtMs = System.currentTimeMillis(); @@ -3538,6 +3628,7 @@ private static List applyTransportFiltering(List transport t.getType() == TransportType.BOAT || t.getType() == TransportType.CHARTER_SHIP || t.getType() == TransportType.SHIP || t.getType() == TransportType.MINECART || t.getType() == TransportType.MAGIC_CARPET || t.getType() == TransportType.SPIRIT_TREE || + (t.getType() == TransportType.TRANSPORT && t.getCurrencyAmount() > 0) || (t.getType() == TransportType.SEASONAL_TRANSPORT && Rs2LeaguesTransport.isLeaguesActive() && t.getDisplayInfo() != null @@ -5431,6 +5522,31 @@ private static boolean shouldYieldForActiveRecoveryInterim(WorldPoint playerLoc, Rs2Player.isMoving()); } + private static boolean shouldYieldForActiveRouteInterim(WorldPoint playerLoc, + List path, + long nowMs) { + WorldPoint interim = interimTargetWp; + if (interim == null) { + return false; + } + recordInterimDistanceProgress(interim, playerLoc, nowMs); + if (playerLoc != null && path != null && !path.isEmpty()) { + int bestIdxNow = getClosestTileIndex(path, playerLoc); + if (bestIdxNow > interimLastBestPathIdx) { + interimLastBestPathIdx = bestIdxNow; + interimLastProgressAtMs = nowMs; + } + } + return shouldDeferRouteWorkForActiveInterim(interim, + playerLoc, + interimSetAtMs, + interimLastProgressAtMs, + nowMs, + lastMovedTimeMs, + Rs2Player.isMoving(), + INTERIM_CLOSE_TILES); + } + static boolean shouldYieldForActiveRecoveryInterim(WorldPoint interim, WorldPoint playerLoc, long setAtMs, @@ -5445,16 +5561,46 @@ static boolean shouldYieldForActiveRecoveryInterim(WorldPoint interim, if (shouldClearInterimTarget(interim, playerLoc, setAtMs, lastProgressAtMs, nowMs)) { return false; } - if (playerMoving) { + if (shouldDeferRouteWorkForActiveInterim(interim, + playerLoc, + setAtMs, + lastProgressAtMs, + nowMs, + lastMovedAtMs, + playerMoving, + INTERIM_CLOSE_TILES)) { return true; } - if (isRecentEvent(nowMs, lastProgressAtMs, INTERIM_PROGRESS_TIMEOUT_MS)) { + return isRecentEvent(nowMs, lastRecoveryClickAtMs, RECOVERY_MOVEMENT_IN_FLIGHT_MS); + } + + static boolean shouldDeferRouteWorkForActiveInterim(WorldPoint interim, + WorldPoint playerLoc, + long setAtMs, + long lastProgressAtMs, + long nowMs, + long lastMovedAtMs, + boolean playerMoving, + int handoffTiles) { + if (interim == null) { + return false; + } + if (shouldClearInterimTarget(interim, playerLoc, setAtMs, lastProgressAtMs, nowMs)) { + return false; + } + if (playerLoc == null || playerLoc.getPlane() != interim.getPlane()) { + return false; + } + if (playerLoc.distanceTo2D(interim) <= Math.max(0, handoffTiles)) { + return false; + } + if (playerMoving) { return true; } - if (isRecentEvent(nowMs, lastMovedAtMs, RECOVERY_MOVEMENT_IN_FLIGHT_MS)) { + if (isRecentEvent(nowMs, lastProgressAtMs, INTERIM_PROGRESS_TIMEOUT_MS)) { return true; } - return isRecentEvent(nowMs, lastRecoveryClickAtMs, RECOVERY_MOVEMENT_IN_FLIGHT_MS); + return isRecentEvent(nowMs, lastMovedAtMs, RECOVERY_MOVEMENT_IN_FLIGHT_MS); } private static void clearInterimTarget(String reason) { @@ -5584,6 +5730,20 @@ private static boolean hasExplicitTransportStep(List path, int index return matchesDirectedTransportCatalogEdge(path.get(index), path.get(index + 1)); } + private static boolean hasImmediatePlannedTransportStep(List path, + int routeStartIdx, + WorldPoint playerLoc) { + if (path == null || routeStartIdx < 0 || routeStartIdx >= path.size() - 1 || playerLoc == null) { + return false; + } + WorldPoint origin = path.get(routeStartIdx); + if (origin == null || origin.getPlane() != playerLoc.getPlane() + || origin.distanceTo2D(playerLoc) > HANDLER_RANGE) { + return false; + } + return hasExplicitTransportStep(path, routeStartIdx); + } + /** * Whether this path edge is covered by a transport catalog row (same coordinates loaded from TSV into * {@link ShortestPathPlugin#getTransports()}). Includes strict origin-destination steps (including @@ -7227,6 +7387,35 @@ static int stabilizeRouteProgressIndex(List path, int closestIdx, Wo return routeProgressIdx; } + static void hintRouteProgressIndex(List path, int hintedIdx, WorldPoint target) { + if (path == null || path.isEmpty() || hintedIdx < 0 || hintedIdx >= path.size()) { + return; + } + + WorldPoint pathStart = path.get(0); + WorldPoint pathEnd = path.get(path.size() - 1); + boolean routeChanged = routeProgressTarget == null + || !routeProgressTarget.equals(target) + || routeProgressPathSize != path.size() + || !Objects.equals(routeProgressPathStart, pathStart) + || !Objects.equals(routeProgressPathEnd, pathEnd) + || routeProgressIdx >= path.size(); + if (routeChanged) { + routeProgressTarget = target; + routeProgressPathStart = pathStart; + routeProgressPathEnd = pathEnd; + routeProgressPathSize = path.size(); + routeProgressIdx = hintedIdx; + recordRouteProgressAdvanced(); + return; + } + + if (hintedIdx > routeProgressIdx) { + routeProgressIdx = hintedIdx; + recordRouteProgressAdvanced(); + } + } + static int advanceIndexPastRecentTransportEdge(List path, int index, WorldPoint playerLoc) { if (path == null || path.isEmpty() || index < 0 || index >= path.size() || !isRecentTransportEdgeWindow()) { @@ -7497,7 +7686,10 @@ && recentlyOpenedStationaryDoorOnSegment(path.get(indexOfStartPoint), path.get(i pathFirstIndex.putIfAbsent(path.get(idx), idx); } - for (Transport transport : transports) { + List orderedTransports = new ArrayList<>(transports); + orderedTransports.sort(Comparator.comparingInt(Rs2Walker::transportHandlingPreference)); + + for (Transport transport : orderedTransports) { Collection worldPointCollections; //in some cases the getOrigin is null, for teleports that start the player location if (transport.getOrigin() == null) { @@ -7821,8 +8013,10 @@ && recentlyOpenedStationaryDoorOnSegment(path.get(indexOfStartPoint), path.get(i final boolean allowClosedVariant = "Climb-down".equalsIgnoreCase(transportAction) || "Climb down".equalsIgnoreCase(transportAction); + final boolean allowAlKharidTollGateVariant = isAlKharidTollGateObjectId(transportObjectId); List objects = Rs2GameObject.getAll(o -> { if (o.getId() == transportObjectId) return true; + if (allowAlKharidTollGateVariant && isAlKharidTollGateObjectId(o.getId())) return true; Integer legacyClosed = OPEN_TO_CLOSED_MAPPINGS.get(transportObjectId); if (legacyClosed != null && o.getId() == legacyClosed) return true; if (!allowClosedVariant) return false; @@ -8384,6 +8578,61 @@ static Set adjacentSamePlaneTransportSuppressionPoints(Transport tra return points; } + private static int transportHandlingPreference(Transport transport) { + if (isAlKharidTollGateTransport(transport) && transport.getCurrencyAmount() > 0) { + return 1; + } + return 0; + } + + private static boolean isAlKharidTollGateTransport(Transport transport, TileObject tileObject) { + return isAlKharidTollGateTransport(transport) + && tileObject != null + && isAlKharidTollGateObjectId(tileObject.getId()); + } + + private static boolean isAlKharidTollGateTransport(Transport transport) { + return transport != null + && isAlKharidTollGateObjectId(transport.getObjectId()) + && AL_KHARID_TOLL_GATE_POINTS.contains(transport.getOrigin()) + && AL_KHARID_TOLL_GATE_POINTS.contains(transport.getDestination()); + } + + private static boolean isAlKharidTollGateObjectId(int objectId) { + return AL_KHARID_TOLL_GATE_OBJECT_IDS.contains(objectId); + } + + private static boolean isPayTollAction(String action) { + return action != null && action.toLowerCase(Locale.ROOT).startsWith("pay-toll"); + } + + private static boolean handleAlKharidTollGate(Transport transport) { + if (Rs2Player.isMoving()) { + Rs2Player.waitForWalking(); + } + + boolean confirmed = false; + if (sleepUntil(Rs2Dialogue::hasSelectAnOption, 2500)) { + confirmed = Rs2Dialogue.clickOption("Yes, okay", "Yes"); + } + + boolean reachedDestination = sleepUntil(() -> { + WorldPoint now = Rs2Player.getWorldLocation(); + WorldPoint destination = transport.getDestination(); + return now != null + && destination != null + && now.getPlane() == destination.getPlane() + && now.distanceTo2D(destination) <= 1; + }, POST_HANDLE_OBJECT_LANDING_WAIT_MS); + if (!confirmed && !reachedDestination) { + WebWalkLog.spWarn( + "Al Kharid toll gate confirmation unresolved dest={} at={}", + compactWorldPoint(transport.getDestination()), + compactWorldPoint(Rs2Player.getWorldLocation())); + } + return true; + } + private static boolean handleObjectExceptions(Transport transport, TileObject tileObject) { for (Map.Entry entry : OPEN_TO_CLOSED_MAPPINGS.entrySet()) { final int closedTrapdoorId = entry.getKey(); @@ -8415,6 +8664,10 @@ private static boolean handleObjectExceptions(Transport transport, TileObject ti } } + if (isAlKharidTollGateTransport(transport, tileObject) && isPayTollAction(transport.getAction())) { + return handleAlKharidTollGate(transport); + } + //Al kharid broken wall will animate once and then stop and then animate again if (tileObject.getId() == ObjectID.KHARID_POSHWALL_TOPLESS || tileObject.getId() == ObjectID.KHARID_BIGWINDOW) { Rs2Player.waitForAnimation(); @@ -8623,7 +8876,7 @@ private static boolean handleTeleportItem(Transport transport) { for (Integer itemId : itemIds) { if (Rs2Walker.currentTarget == null) break; // reachedDistance <= 0: do not treat as "already at destination" (legacy: raw distance < 0 never true). - int reachRd = config.reachedDistance(); + int reachRd = reachedDistanceOrDefault(); if (reachRd > 0 && isPlayerWithinChebyshevOf(transport.getDestination(), reachRd)) { break; } @@ -9107,14 +9360,16 @@ private static boolean isStuckTooLong() { * @param start */ public void setStart(WorldPoint start) { - if (ShortestPathPlugin.getPathfinder() == null) { + Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + if (pathfinder == null) { return; } + Set targets = pathfinder.getTargets(); ShortestPathPlugin.setStartPointSet(true); - if (Microbot.getClient().isClientThread()) { - Microbot.getClientThread().runOnSeperateThread(() -> restartPathfinding(start, ShortestPathPlugin.getPathfinder().getTargets())); + if (isClientThread()) { + Microbot.getClientThread().runOnSeperateThread(() -> restartPathfinding(start, targets)); } else { - restartPathfinding(start, ShortestPathPlugin.getPathfinder().getTargets()); + restartPathfinding(start, targets); } } @@ -10404,7 +10659,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) { @@ -10454,7 +10710,7 @@ public static boolean walkWithBankedTransports(WorldPoint target) { return walkWithBankedTransports(target, false); } public static boolean walkWithBankedTransports(WorldPoint target, boolean forceBanking) { - int d = config != null ? config.reachedDistance() : 10; + int d = reachedDistanceOrDefault(); return walkWithBankedTransportsAndState(target, d, forceBanking) == WalkerState.ARRIVED; } public static boolean walkWithBankedTransports(WorldPoint target, int distance, boolean forceBanking){ @@ -10475,7 +10731,7 @@ public static WalkerState walkWithBankedTransportsAndState(WorldPoint target, in log.warn("Cannot travel to null target location"); return WalkerState.EXIT; } - if (Microbot.getClient().isClientThread()) { + if (isClientThread()) { log.error("Please do not call the walker from the main thread"); return WalkerState.EXIT; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java index 64f3c61a2e..287a41bba8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java @@ -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() @@ -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) { diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/blocked_edges.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/blocked_edges.tsv index 49bc9a2141..4b6822e52d 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/blocked_edges.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/blocked_edges.tsv @@ -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 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/restrictions.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/restrictions.tsv index 539c6d881f..c66bd5a99f 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/restrictions.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/restrictions.tsv @@ -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 @@ -236,4 +232,4 @@ 2432 3118 0 2431 3118 0 2385 3068 0 -2385 3069 0 \ No newline at end of file +2385 3069 0 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv index 28fc583725..da52a59975 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv @@ -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 diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathCoreTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathCoreTest.java index 4adaf188ef..2bbc7972bc 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathCoreTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathCoreTest.java @@ -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; @@ -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() { @@ -193,6 +198,52 @@ public void testTransportLoadingDoesNotThrow() { assertTrue("Should load at least 100 transport origins", transports.size() > 100); } + @Test + public void testAlKharidTollGateTransportsLoaded() { + HashMap> 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 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 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> transports = Transport.loadAllFromResources(); @@ -259,6 +310,27 @@ && new WorldPoint(3221, 3218, 0).equals(t.getDestination())) return lumbridgeHomeTeleport.get(); } + private static void assertTollGateTransport(HashMap> transports, + WorldPoint origin, WorldPoint destination, String action, int currencyAmount, boolean princeAliRequired) { + Optional 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> transports = Transport.loadAllFromResources(); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index 5de440bd1e..b117cae7f6 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; @@ -458,6 +459,26 @@ public void stabilizeRouteProgressIndex_doesNotJumpBackToEarlierNearbyBranch() { assertEquals(6, Rs2Walker.stabilizeRouteProgressIndex(path, 6, target, new WorldPoint(3201, 3201, 0))); } + @Test + public void hintRouteProgressIndex_keepsProgressAnchoredAheadOfEarlierBranch() { + WorldPoint target = new WorldPoint(3200, 3201, 0); + List path = Arrays.asList( + new WorldPoint(3200, 3200, 0), + new WorldPoint(3201, 3200, 0), + new WorldPoint(3202, 3200, 0), + new WorldPoint(3203, 3200, 0), + new WorldPoint(3203, 3201, 0), + new WorldPoint(3202, 3201, 0), + new WorldPoint(3201, 3201, 0), + target); + + Rs2Walker.hintRouteProgressIndex(path, 5, target); + + assertEquals("a clicked-ahead route checkpoint should not snap back to a nearby earlier branch", + 5, + Rs2Walker.stabilizeRouteProgressIndex(path, 2, target, new WorldPoint(3202, 3201, 0))); + } + @Test public void findForwardRecoveryIndex_prefersLaterReachableBranch() { WorldPoint player = new WorldPoint(1000, 1000, 0); @@ -508,6 +529,87 @@ public void findFurthestForwardClickableIndex_doesNotBacktrackToEarlierNearbyBra assertEquals("normal route following should interpolate toward the forward tile, not backtrack", 3, idx); } + @Test + public void findFurthestRawPathPointMatching_keepsPrimaryClickOnForwardRawRoute() { + WorldPoint player = new WorldPoint(1000, 1000, 0); + List rawPath = Arrays.asList( + new WorldPoint(998, 1000, 0), + new WorldPoint(999, 1000, 0), + new WorldPoint(1000, 1001, 0), + new WorldPoint(1010, 1000, 0), + new WorldPoint(1009, 1000, 0), + new WorldPoint(1008, 1000, 0)); + + WorldPoint target = Rs2Walker.findFurthestRawPathPointMatching( + rawPath, + player, + 13, + 3, + wp -> true); + + assertEquals("raw-route selection must not snap back to an earlier nearby branch", + new WorldPoint(1008, 1000, 0), target); + } + + @Test + public void findFurthestRawPathPointMatching_honorsCandidatePredicate() { + WorldPoint player = new WorldPoint(3200, 3200, 0); + WorldPoint blocked = new WorldPoint(3203, 3200, 0); + WorldPoint allowed = new WorldPoint(3202, 3200, 0); + List rawPath = Arrays.asList( + new WorldPoint(3200, 3200, 0), + new WorldPoint(3201, 3200, 0), + allowed, + blocked); + + WorldPoint target = Rs2Walker.findFurthestRawPathPointMatching( + rawPath, + player, + 13, + 0, + wp -> !wp.equals(blocked)); + + assertEquals("primary raw-route target must be the furthest acceptable raw tile", + allowed, target); + } + + @Test + public void findFurthestRawPathPointMatching_doesNotReturnCurrentTile() { + WorldPoint player = new WorldPoint(3200, 3200, 0); + List rawPath = Arrays.asList( + player, + new WorldPoint(3215, 3200, 0)); + + WorldPoint target = Rs2Walker.findFurthestRawPathPointMatching( + rawPath, + player, + 10, + 0, + wp -> true); + + assertNull("same-tile route targets are no-op clicks, not recovery candidates", target); + } + + @Test + public void findFurthestRawPathPointMatching_stopsBeforeRouteStepBudgetIsExceeded() { + WorldPoint player = new WorldPoint(3200, 3200, 0); + List rawPath = Arrays.asList( + new WorldPoint(3200, 3200, 0), + new WorldPoint(3205, 3200, 0), + new WorldPoint(3210, 3200, 0), + new WorldPoint(3216, 3200, 0)); + + WorldPoint target = Rs2Walker.findFurthestRawPathPointMatching( + rawPath, + player, + 13, + 0, + wp -> true); + + assertEquals("route step budget keeps one minimap click from spanning too far ahead", + new WorldPoint(3210, 3200, 0), target); + } + @Test public void findFurthestForwardClickableIndex_stopsBeforeTransportOrigin() { WorldPoint player = new WorldPoint(3200, 3200, 0); @@ -791,6 +893,58 @@ public void shouldYieldForActiveRecoveryInterim_recentRecoveryClick_returnsTrue( false)); } + @Test + public void shouldDeferRouteWorkForActiveInterim_movingFarCheckpoint_returnsTrue() { + assertTrue(Rs2Walker.shouldDeferRouteWorkForActiveInterim( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2880, 3396, 0), + 1_000L, + 4_500L, + 5_000L, + 0L, + true, + 5)); + } + + @Test + public void shouldDeferRouteWorkForActiveInterim_recentProgressStoppedFar_returnsTrue() { + assertTrue(Rs2Walker.shouldDeferRouteWorkForActiveInterim( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2880, 3396, 0), + 1_000L, + 4_900L, + 5_000L, + 0L, + false, + 5)); + } + + @Test + public void shouldDeferRouteWorkForActiveInterim_closeCheckpoint_returnsFalse() { + assertFalse(Rs2Walker.shouldDeferRouteWorkForActiveInterim( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2886, 3396, 0), + 1_000L, + 4_500L, + 5_000L, + 0L, + true, + 5)); + } + + @Test + public void shouldDeferRouteWorkForActiveInterim_staleStoppedCheckpoint_returnsFalse() { + assertFalse(Rs2Walker.shouldDeferRouteWorkForActiveInterim( + new WorldPoint(2890, 3396, 0), + new WorldPoint(2880, 3396, 0), + 1_000L, + 1_500L, + 5_000L, + 0L, + false, + 5)); + } + @Test public void interimPreclickTiles_runHandsOffEarlierThanWalk() { assertEquals(6, Rs2Walker.interimPreclickTiles(false)); @@ -805,6 +959,13 @@ public void routeMovementClickPhase_labelsContinuationSeparatelyFromRecovery() { assertEquals("route_movement_click", Rs2Walker.routeMovementClickPhase("other")); } + @Test + public void shouldRunActiveRouteIdleNudge_waitsForImmediateTransport() { + assertFalse(Rs2Walker.shouldRunActiveRouteIdleNudge(true, true)); + assertTrue(Rs2Walker.shouldRunActiveRouteIdleNudge(true, false)); + assertFalse(Rs2Walker.shouldRunActiveRouteIdleNudge(false, false)); + } + @Test public void shouldSkipStartupPreclickSegmentHandlers_skipsBeforeFirstMovementClick() { assertTrue(Rs2Walker.shouldSkipStartupPreclickSegmentHandlers( From 6c78e87328cb1c8d17642696df9006dd1a2e5b7e Mon Sep 17 00:00:00 2001 From: infuse21 Date: Sun, 19 Jul 2026 17:08:16 +0100 Subject: [PATCH 04/48] Updated questhelper to upstream Zoinkwiz/quest-helper commit ae1f441248b9742c1eaa667b18052785eb6ed058 (4.16.1) and marked the sync as successful in .quest-helper-sync. Kept the Microbot-specific integration intact: hidden always-on plugin wiring, QuestScript, config toggles, custom quest logic, resource path fixes, and the agent start hook. I also restored compatibility accessors needed by the automation runner and preserved precise farming patch coordinates where they matched older local data. --- .../microbot/questhelper/.quest-helper-sync | 24 +- .../questhelper/QuestHelperConfig.java | 69 +- .../questhelper/QuestHelperPlugin.java | 81 +- .../bank/banktab/QuestBankTab.java | 10 +- .../bank/banktab/QuestBankTabInterface.java | 4 - .../banktab/QuestHelperBankTagService.java | 18 +- .../questhelper/bikeshedder/BikeShedder.java | 352 ------ .../collections/ItemCollections.java | 59 + .../collections/KeyringCollection.java | 32 +- .../collections/TeleportCollections.java | 2 +- .../questhelper/config/ConfigKeys.java | 71 -- .../LeagueFiltering.java} | 49 +- .../domain/QuetzalDestination.java | 44 + .../ardougne/ArdougneEasy.java | 7 +- .../ardougne/ArdougneElite.java | 8 +- .../ardougne/ArdougneHard.java | 2 +- .../ardougne/ArdougneMedium.java | 6 +- .../achievementdiaries/desert/DesertEasy.java | 2 +- .../desert/DesertElite.java | 2 +- .../falador/FaladorEasy.java | 2 +- .../falador/FaladorElite.java | 6 +- .../fremennik/FremennikElite.java | 6 +- .../fremennik/FremennikMedium.java | 11 +- .../kandarin/KandarinEasy.java | 38 +- .../kandarin/KandarinElite.java | 2 +- .../kandarin/KandarinHard.java | 2 +- .../kandarin/KandarinMedium.java | 10 +- .../karamja/KaramjaElite.java | 12 +- .../karamja/KaramjaMedium.java | 11 +- .../kourend/KourendEasy.java | 6 +- .../kourend/KourendMedium.java | 2 +- .../lumbridgeanddraynor/LumbridgeEasy.java | 10 +- .../lumbridgeanddraynor/LumbridgeElite.java | 6 +- .../morytania/MorytaniaEasy.java | 8 +- .../morytania/MorytaniaElite.java | 6 +- .../morytania/MorytaniaMedium.java | 2 +- .../varrock/VarrockMedium.java | 6 +- .../westernprovinces/WesternMedium.java | 3 +- .../wilderness/WildernessEasy.java | 6 +- .../charting/ChartingConditionalStep.java | 1 - .../activities/charting/ChartingHelper.java | 24 +- .../charting/ChartingSeaSection.java | 1 - .../charting/ChartingTaskDefinition.java | 3 +- .../charting/ChartingTasksData.java | 11 +- .../steps/ChartingCaveTelescopeStep.java | 2 +- .../charting/steps/ChartingCrateStep.java | 5 +- .../charting/steps/ChartingCurrentStep.java | 6 +- .../steps/ChartingGenericObjectStep.java | 3 + .../steps/ChartingPuzzleWrapStep.java | 1 - .../charting/steps/ChartingTaskNpcStep.java | 2 +- .../steps/ChartingTaskObjectStep.java | 1 - .../charting/steps/ChartingTaskStep.java | 1 - .../charting/steps/ChartingWeatherStep.java | 1 + .../AlfredGrimhandsBarcrawl.java | 239 ++-- .../barbariantraining/BarbarianTraining.java | 515 +++----- .../miniquests/daddyshome/DaddysHome.java | 16 +- .../miniquests/enchantedkey/EnchantedKey.java | 2 +- .../enchantedkey/EnchantedKeyDigStep.java | 3 +- .../lairoftarnrazorlor/TarnRoute.java | 6 +- .../themagearenai/TheMageArenaI.java | 3 +- .../miniquests/themagearenaii/MA2Locator.java | 31 +- .../themagearenaii/MageArenaBossStep.java | 312 ++++- .../themagearenaii/MageArenaSolver.java | 2 + .../MageArenaSpawnLocation.java | 5 +- .../themagearenaii/TheMageArenaII.java | 34 +- .../miniquests/valetotems/ValeTotems.java | 17 +- .../farmruns/FarmingConfigChangeHandler.java | 1 - .../mischelpers/farmruns/FarmingPatch.java | 33 +- .../mischelpers/farmruns/FarmingRegion.java | 50 +- .../mischelpers/farmruns/FarmingUtils.java | 2 + .../mischelpers/farmruns/FarmingWorld.java | 603 ++++------ .../helpers/mischelpers/farmruns/HerbRun.java | 43 +- .../farmruns/PatchImplementation.java | 41 +- .../mischelpers/farmruns/PaymentTracker.java | 5 +- .../helpers/mischelpers/farmruns/TreeRun.java | 637 +++++++--- .../mischelpers/knightswaves/KnightWaves.java | 6 +- .../StrongholdOfSecurity.java | 20 +- .../APorcineOfInterest.java | 183 ++- .../quests/bearyoursoul/BearYourSoul.java | 2 +- .../belowicemountain/BelowIceMountain.java | 21 +- .../BeneathCursedSands.java | 7 +- .../helpers/quests/biohazard/Biohazard.java | 19 +- .../BlackKnightFortress.java | 20 +- .../childrenofthesun/ChildrenOfTheSun.java | 18 +- .../clientofkourend/ClientOfKourend.java | 12 +- .../helpers/quests/clocktower/ClockTower.java | 22 +- .../quests/cooksassistant/CooksAssistant.java | 20 +- .../CreatureOfFenkenstrain.java | 4 +- .../quests/currentaffairs/CurrentAffairs.java | 22 +- .../quests/deathontheisle/DeathOnTheIsle.java | 21 +- .../DeathToTheDorgeshuun.java | 6 +- .../quests/demonslayer/DemonSlayer.java | 20 +- .../quests/demonslayer/IncantationStep.java | 3 +- .../quests/deserttreasure/DesertTreasure.java | 4 +- .../deserttreasureii/DesertTreasureII.java | 4 +- .../deserttreasureii/PerseriyaSteps.java | 10 +- .../deserttreasureii/WhispererSteps.java | 2 +- .../quests/deviousminds/DeviousMinds.java | 5 +- .../quests/doricsquest/DoricsQuest.java | 86 +- .../quests/dragonslayer/DragonSlayer.java | 6 +- .../quests/druidicritual/DruidicRitual.java | 12 +- .../quests/dwarfcannon/DwarfCannon.java | 23 +- .../ElementalWorkshopI.java | 8 +- .../ElementalWorkshopII.java | 32 +- .../quests/enakhraslament/EnakhrasLament.java | 13 +- .../EnlightenedJourney.java | 2 +- .../helpers/quests/fairytalei/FairytaleI.java | 1 + .../quests/fairytaleii/FairytaleII.java | 18 +- .../helpers/quests/fightarena/FightArena.java | 12 +- .../forgettabletale/ForgettableTale.java | 7 +- .../GardenOfTranquillity.java | 4 +- .../quests/gertrudescat/GertrudesCat.java | 19 +- .../quests/ghostsahoy/DyeShipSteps.java | 31 +- .../goblindiplomacy/GoblinDiplomacy.java | 203 ++-- .../helpers/quests/grimtales/GrimTales.java | 3 +- .../quests/hauntedmine/HauntedMine.java | 8 +- .../helpers/quests/hazeelcult/HazeelCult.java | 19 +- .../quests/heroesquest/HeroesQuest.java | 4 +- .../helpers/quests/holygrail/HolyGrail.java | 21 +- .../helpers/quests/impcatcher/ImpCatcher.java | 15 +- .../quests/junglepotion/JunglePotion.java | 313 +++-- .../landofthegoblins/LandOfTheGoblins.java | 5 +- .../helpers/quests/lostcity/LostCity.java | 278 +++-- .../quests/makinghistory/MakingHistory.java | 2 +- .../quests/merlinscrystal/MerlinsCrystal.java | 21 +- .../misthalinmystery/MisthalinMystery.java | 22 +- .../quests/monkeymadnessi/MonkeyMadnessI.java | 2 +- .../monkeymadnessii/AgilityDungeonSteps.java | 10 +- .../quests/monksfriend/MonksFriend.java | 26 +- .../mountaindaughter/MountainDaughter.java | 6 +- .../mourningsendparti/MourningsEndPartI.java | 2 +- .../MourningsEndPartII.java | 2 +- .../quests/murdermystery/MurderMystery.java | 23 +- .../MyArmsBigAdventure.java | 2 +- .../quests/naturespirit/NatureSpirit.java | 407 ++++--- .../observatoryquest/ObservatoryQuest.java | 23 +- .../observatoryquest/StarSignAnswer.java | 92 -- .../quests/onesmallfavour/OneSmallFavour.java | 1062 +++++++++++------ .../quests/pandemonium/Pandemonium.java | 463 ++++--- .../piratestreasure/PiratesTreasure.java | 16 +- .../piratestreasure/RumSmugglingStep.java | 16 +- .../helpers/quests/plaguecity/PlagueCity.java | 18 +- .../quests/priestinperil/PriestInPeril.java | 467 +++++--- .../princealirescue/PrinceAliRescue.java | 73 +- .../quests/pryingtimes/PryingTimes.java | 20 +- .../quests/ragandboneman/RagAndBoneManII.java | 8 +- .../quests/ratcatchers/RatCatchers.java | 6 +- .../quests/recipefordisaster/RFDDwarf.java | 2 +- .../recipefordisaster/RFDPiratePete.java | 7 +- .../recipefordisaster/RFDSkrachUglogwee.java | 2 +- .../quests/recruitmentdrive/DoorPuzzle.java | 90 +- .../recruitmentdrive/LadyTableStep.java | 111 +- .../recruitmentdrive/MissCheeversStep.java | 384 ++++++ .../recruitmentdrive/MsCheevesSetup.java | 384 ------ .../MsHynnAnswerDialogQuizStep.java | 67 +- .../recruitmentdrive/RecruitmentDrive.java | 683 ++++++----- .../recruitmentdrive/SirRenItchoodStep.java | 58 +- .../quests/romeoandjuliet/RomeoAndJuliet.java | 14 +- .../quests/runemysteries/RuneMysteries.java | 12 +- .../scorpioncatcher/ScorpionCatcher.java | 361 +++--- .../helpers/quests/scrambled/EggSolver.java | 7 +- .../helpers/quests/scrambled/Scrambled.java | 17 +- .../helpers/quests/seaslug/SeaSlug.java | 317 +++-- .../shadowofthestorm/IncantationStep.java | 26 +- .../quests/shadowofthestorm/SearchKilns.java | 91 -- .../shadowofthestorm/ShadowOfTheStorm.java | 468 +++++--- .../shadowsofcustodia/ShadowsOfCustodia.java | 18 +- .../quests/sheepherder/SheepHerder.java | 20 +- .../quests/sheepshearer/SheepShearer.java | 26 +- .../ShieldOfArravBlackArmGang.java | 6 +- .../quests/shilovillage/ShiloVillage.java | 534 +++++---- .../sinsofthefather/DoorPuzzleStep.java | 85 +- .../helpers/quests/swansong/FishMonkfish.java | 6 +- .../taibwowannaitrio/TaiBwoWannaiTrio.java | 2 +- .../quests/templeofikov/TempleOfIkov.java | 33 +- .../thecurseofarrav/TheCurseOfArrav.java | 1 + .../helpers/quests/thedigsite/TheDigSite.java | 638 ++++++---- .../quests/thefinaldawn/TheFinalDawn.java | 17 +- .../quests/theforsakentower/JugPuzzle.java | 3 +- .../thefremennikisles/TheFremennikIsles.java | 2 +- .../TheFremennikTrials.java | 8 +- .../helpers/quests/thegolem/TheGolem.java | 20 +- .../TheHeartOfDarkness.java | 18 +- .../quests/theidesofmilk/TheIdesOfMilk.java | 316 +++++ .../theknightssword/TheKnightsSword.java | 269 +++-- .../quests/thelosttribe/TheLostTribe.java | 437 ++++--- .../ThePathOfGlouphrie.java | 4 +- .../thepathofglouphrie/YewnocksPuzzle.java | 51 +- .../sections/TheWarpedDepths.java | 2 + .../helpers/quests/theredreef/TheRedReef.java | 559 +++++++++ .../therestlessghost/TheRestlessGhost.java | 12 +- .../quests/theslugmenace/PuzzleStep.java | 2 +- .../quests/thetouristtrap/TheTouristTrap.java | 2 +- .../ThroneOfMiscellania.java | 15 +- .../quests/toweroflife/PuzzleSolver.java | 22 +- .../treegnomevillage/TreeGnomeVillage.java | 19 +- .../quests/tribaltotem/PuzzleStep.java | 71 +- .../quests/tribaltotem/TribalTotem.java | 5 +- .../trollstronghold/TrollStronghold.java | 6 +- .../quests/troubledtortugans/RepairTown.java | 3 +- .../troubledtortugans/TroubledTortugans.java | 21 +- .../quests/vampyreslayer/VampyreSlayer.java | 242 ++-- .../helpers/quests/wanted/Wanted.java | 6 +- .../helpers/quests/watchtower/Watchtower.java | 8 +- .../quests/waterfallquest/WaterfallQuest.java | 16 +- .../quests/whatliesbelow/WhatLiesBelow.java | 3 +- .../whileguthixsleeps/WhileGuthixSleeps.java | 2 +- .../quests/witchshouse/WitchsHouse.java | 21 +- .../quests/witchspotion/WitchsPotion.java | 9 +- .../quests/xmarksthespot/XMarksTheSpot.java | 10 +- .../managers/ItemAndLastUpdated.java | 27 + .../managers/NewVersionManager.java | 2 +- .../managers/QuestContainerManager.java | 5 +- .../questhelper/managers/QuestManager.java | 3 + .../managers/QuestMenuHandler.java | 3 +- .../overlays/QuestHelperMinimapOverlay.java | 5 + .../overlays/QuestHelperOverlay.java | 1 + .../QuestHelperWorldArrowOverlay.java | 5 + .../overlays/QuestHelperWorldLineOverlay.java | 5 + .../overlays/QuestHelperWorldOverlay.java | 19 +- .../questhelper/panel/JGenerator.java | 4 +- .../panel/ManualStepSkipStore.java | 112 ++ .../questhelper/panel/PanelDetails.java | 7 +- .../questhelper/panel/QuestHelperPanel.java | 275 ++++- .../questhelper/panel/QuestOverviewPanel.java | 42 +- .../panel/QuestRequirementsPanel.java | 7 +- .../questhelper/panel/QuestRewardsPanel.java | 2 +- .../questhelper/panel/QuestStepPanel.java | 448 ------- .../panel/TopLevelPanelDetails.java | 1 - .../questorders/IronmanOptimalQuestGuide.java | 5 +- .../panel/questorders/OptimalQuestGuide.java | 5 +- .../panel/questorders/ReleaseDate.java | 5 +- .../AbstractQuestSection.java | 2 +- .../queststepsection/QuestSectionSection.java | 14 +- .../queststepsection/QuestStepPanel.java | 279 ++++- .../regionfiltering/RegionFilterPanel.java | 193 +++ .../playerquests/bikeshedder/BikeShedder.java | 173 ++- .../playerquests/cookshelper/CooksHelper.java | 255 ---- .../questhelper/questhelpers/QuestHelper.java | 69 +- .../questinfo/ExternalQuestResources.java | 2 + .../questinfo/LeagueQuestRegions.java | 294 +++++ .../questhelper/questinfo/LeagueRegion.java | 53 + .../questinfo/QuestHelperQuest.java | 13 +- .../questhelper/questinfo/QuestVarbits.java | 4 +- .../requirements/AbstractRequirement.java | 2 +- .../requirements/ChatMessageRequirement.java | 2 +- .../questhelper/requirements/Requirement.java | 2 +- .../requirements/StepIsActiveRequirement.java | 4 +- .../conditional/ConditionForStep.java | 1 + .../requirements/conditional/Conditions.java | 1 + .../conditional/ObjectCondition.java | 2 +- .../requirements/item/ItemRequirement.java | 9 +- .../requirements/item/ItemRequirements.java | 2 +- .../requirements/item/KeyringRequirement.java | 99 +- .../requirements/item/TrackedContainers.java | 1 + .../requirements/npc/DialogRequirement.java | 38 +- .../npc/NoFollowerRequirement.java | 3 +- .../requirements/npc/NpcRequirement.java | 8 +- .../requirements/player/Boosts.java | 4 +- .../player/FreeInventorySlotRequirement.java | 1 + .../player/FreePortTaskSlotsRequirement.java | 5 +- .../player/ShipInPortRequirement.java | 5 +- .../sailing/HasBoatResistanceRequirement.java | 2 +- .../requirements/util/InventorySlots.java | 2 +- .../requirements/util/ItemSlots.java | 75 +- .../questhelper/requirements/util/Port.java | 62 +- .../requirements/var/VarbitRequirement.java | 3 +- .../requirements/zone/ZoneRequirement.java | 12 +- .../questhelper/runeliteobjects/Cheerer.java | 18 +- .../runeliteobjects/GlobalFakeObjects.java | 9 + .../ExtendedRuneliteObject.java | 2 +- .../RuneliteObjectManager.java | 17 +- .../AchievementDiaryStepManager.java | 32 +- .../BarbarianTrainingStateTracker.java | 341 ------ .../statemanagement/PlayerStateManager.java | 106 +- .../questhelper/steps/BoardShipStep.java | 1 - .../questhelper/steps/ConditionalStep.java | 66 +- .../questhelper/steps/DetailedQuestStep.java | 50 +- .../microbot/questhelper/steps/DigStep.java | 10 +- .../microbot/questhelper/steps/EmoteStep.java | 14 +- .../questhelper/steps/NpcEmoteStep.java | 2 +- .../microbot/questhelper/steps/NpcStep.java | 19 +- .../questhelper/steps/ObjectStep.java | 36 +- .../questhelper/steps/PortTaskStep.java | 2 - .../questhelper/steps/PuzzleStep.java | 2 +- .../questhelper/steps/PuzzleWrapperStep.java | 3 +- .../microbot/questhelper/steps/QuestStep.java | 102 +- .../questhelper/steps/WidgetStep.java | 4 +- .../questhelper/steps/WorldEntityStep.java | 159 +++ .../steps/choice/DialogChoiceStep.java | 2 +- .../steps/choice/WidgetChoiceStep.java | 4 +- .../questhelper/steps/emote/QuestEmote.java | 4 +- .../steps/overlay/DirectionArrow.java | 4 +- .../questhelper/steps/tools/DefinedPoint.java | 1 - .../steps/tools/QuestPerspective.java | 93 +- .../steps/widget/WidgetHighlight.java | 19 + .../microbot/questhelper/util/Utils.java | 3 +- 297 files changed, 11166 insertions(+), 7356 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bikeshedder/BikeShedder.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/ConfigKeys.java rename runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/{requirements/RegionHintArrowRequirement.java => config/LeagueFiltering.java} (56%) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/domain/QuetzalDestination.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/StarSignAnswer.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MissCheeversStep.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsCheevesSetup.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/SearchKilns.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theidesofmilk/TheIdesOfMilk.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theredreef/TheRedReef.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/ManualStepSkipStore.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestStepPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/regionfiltering/RegionFilterPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/cookshelper/CooksHelper.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueQuestRegions.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueRegion.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/BarbarianTrainingStateTracker.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WorldEntityStep.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync index 98091843fe..8c8874920d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/.quest-helper-sync @@ -8,16 +8,22 @@ # Use the quest-helper update scripts to manage synchronization. # Current sync position - this is the last external commit that has been integrated -5539626281a502ba8c44fe59b8b57bce32fe4f16 +ae1f441248b9742c1eaa667b18052785eb6ed058 # Sync metadata (for script reference) -# External repo HEAD at last check: 5539626281a502ba8c44fe59b8b57bce32fe4f16 -# Last sync date: 2025-08-29 -# Sync method: automated script with manual package transformation -# Integration branch: quest-helper-update-20250829_063754 -# Local commit: cb416ef02a (quest-helper: polish Enakhras Lament) +# External repo HEAD at last check: ae1f441248b9742c1eaa667b18052785eb6ed058 +# Last sync date: 2026-07-19 +# Sync method: upstream source mirror with manual package transformation and Microbot hook preservation +# Integration branch: local workspace +# Local commit: pending # Sync history log: +# 2026-07-19 - Complete sync to upstream ae1f4412 (Quest Helper 4.16.1 source) +# - Mirrored upstream src/main/java and src/main/resources into the Microbot package +# - Preserved Microbot QuestScript, custom quest logic, config toggles, and agent-server start hook +# - Package transformation: com.questhelper -> net.runelite.client.plugins.microbot.questhelper +# - Status: SUCCESS +# # 2025-08-29 07:14:46 - Applied commit 55396262 (Polish enahkras lament #2294) # - Enhanced EnakhrasLament.java with better code organization # - Fixed Shadow Room brazier puzzle sequence and locations @@ -43,9 +49,9 @@ # - Status: INITIALIZED # Integration status -# Current external version: 4.10.0+ +# Current external version: 4.16.1 # Integration health: HEALTHY -# Last validation: 2025-08-29 +# Last validation: 2026-07-19 # Compilation status: SUCCESS # Package transformation: COMPLETE -# Sync file location: CORRECT (moved from project root) \ No newline at end of file +# Sync file location: CORRECT (moved from project root) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java index 78c6ae488c..22715fc5bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperConfig.java @@ -46,6 +46,8 @@ public interface QuestHelperConfig extends Config String QUEST_HELPER_GROUP = "questhelper"; String QUEST_BACKGROUND_GROUP = "questhelpervars"; String QUEST_HELPER_SIDEBAR_ORDER_KEY_START = "quest-sidebar-order-"; + /** Per-helper persisted manual step skips (JSON map of stable slot id to true). */ + String QUEST_HELPER_MANUAL_SKIPS_KEY_PREFIX = "manual-step-skips-"; enum QuestOrdering implements Comparator { @@ -237,32 +239,33 @@ enum InventoryItemHighlightStyle } @ConfigSection( - position = 0, - name = "Microbot", - description = "Microbot Options", - closedByDefault = false + position = 0, + name = "Microbot", + description = "Microbot Options", + closedByDefault = false ) String microbotSection = "microbotSection"; - @ConfigItem( - keyName = "TurnOn", - name = "Enable QuestHelper", - description = "Enable the quest helper that will automatically help with quests.", - section = microbotSection + keyName = "TurnOn", + name = "Enable QuestHelper", + description = "Enable the quest helper that will automatically help with quests.", + section = microbotSection ) - default boolean startStopQuestHelper() { + default boolean startStopQuestHelper() + { return true; } @ConfigItem( - keyName = "obtainMissingItems", - name = "Obtain Missing Items", - description = "Controls whether the quest helper automatically obtains missing items from the bank and Grand Exchange. 'Ask' will prompt you the first time items are needed.", - section = microbotSection, - position = 1 + keyName = "obtainMissingItems", + name = "Obtain Missing Items", + description = "Controls whether the quest helper automatically obtains missing items from the bank and Grand Exchange. 'Ask' will prompt you the first time items are needed.", + section = microbotSection, + position = 1 ) - default ObtainMissingItemsOption obtainMissingItems() { + default ObtainMissingItemsOption obtainMissingItems() + { return ObtainMissingItemsOption.ASK; } @@ -332,14 +335,15 @@ public String toString() } @ConfigItem( - keyName = "valeTotemsWoodType", - name = "Vale Totems wood type", - description = "Which wood type the quester should gather for the Vale Totems miniquest. " + - "Must match the wood you used to build the totem. " + - "Leave on 'Ask me' to be prompted the first time the quest runs.", - section = microbotSection + keyName = "valeTotemsWoodType", + name = "Vale Totems wood type", + description = "Which wood type the quester should gather for the Vale Totems miniquest. " + + "Must match the wood you used to build the totem. " + + "Leave on 'Ask me' to be prompted the first time the quest runs.", + section = microbotSection ) - default ValeTotemsWoodType valeTotemsWoodType() { + default ValeTotemsWoodType valeTotemsWoodType() + { return ValeTotemsWoodType.ASK; } @@ -791,6 +795,25 @@ default boolean showCompletedQuests() return false; } + enum RegionFilterVisibility + { + AUTO, + SHOW, + HIDE + } + + @ConfigItem( + keyName = "regionFilterVisibility", + name = "Region filtering", + description = "Controls when the league region filter is shown. Auto shows it only on league worlds.", + position = 5, + section = filterSection + ) + default RegionFilterVisibility regionFilterVisibility() + { + return RegionFilterVisibility.AUTO; + } + @ConfigSection( position = 5, name = "Development", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java index 3f272b847c..f1b8c045ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestHelperPlugin.java @@ -29,9 +29,9 @@ import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Provides; -import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankTabItems; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.PotionStorage; +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.QuestBankTabInterface; import net.runelite.client.plugins.microbot.questhelper.managers.*; import net.runelite.client.plugins.microbot.questhelper.panel.QuestHelperPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; @@ -39,6 +39,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.Cheerer; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.GlobalFakeObjects; +import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.RuneliteConfigSetter; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.RuneliteObjectManager; import net.runelite.client.plugins.microbot.questhelper.statemanagement.PlayerStateManager; import net.runelite.client.plugins.microbot.questhelper.tools.Icon; @@ -49,7 +50,7 @@ import net.runelite.api.events.*; import net.runelite.api.gameval.InventoryID; import net.runelite.api.gameval.VarPlayerID; -import net.runelite.client.RuneLite; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; @@ -60,9 +61,11 @@ import net.runelite.client.events.RuneScapeProfileChanged; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SkillIconManager; +import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.bank.BankSearch; +import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.components.colorpicker.ColorPickerManager; @@ -101,6 +104,7 @@ public class QuestHelperPlugin extends Plugin @Inject private ClientThread clientThread; + @Getter @Inject private EventBus eventBus; @@ -162,6 +166,17 @@ public class QuestHelperPlugin extends Plugin @Inject public SkillIconManager skillIconManager; + @Inject + public SpriteManager spriteManager; + + @Inject + private QuestBankTabInterface questBankTabInterface; + + public boolean fullCrate; + + @Inject + QuestScript questScript; + private QuestHelperPanel panel; private NavigationButton navButton; @@ -170,9 +185,9 @@ public class QuestHelperPlugin extends Plugin private final Collection configEvents = Arrays.asList("orderListBy", "filterListBy", "questDifficulty", "showCompletedQuests"); private final Collection configItemEvents = Arrays.asList("highlightNeededQuestItems", "highlightNeededMiniquestItems", "highlightNeededAchievementDiaryItems"); - public boolean fullCrate; - @Inject - QuestScript questScript; + + @Getter + private boolean inCutscene = false; @Provides QuestHelperConfig getConfig(ConfigManager configManager) @@ -234,6 +249,7 @@ protected void startUp() throws IOException @Override protected void shutDown() { + questScript.shutdown(); runeliteObjectManager.shutDown(); eventBus.unregister(playerStateManager); @@ -260,6 +276,7 @@ protected void shutDown() public void onGameTick(GameTick event) { questBankManager.loadInitialStateFromConfig(client); + playerStateManager.loadInitialStateFromConfig(); questManager.updateQuestState(); } @@ -314,6 +331,7 @@ public void onGameStateChanged(final GameStateChanged event) questBankManager.saveBankToConfig(); SwingUtilities.invokeLater(() -> panel.refresh(Collections.emptyList(), true, new HashMap<>())); questBankManager.emptyState(); + playerStateManager.emptyState(); questManager.shutDownQuest(true); profileChanged = true; } @@ -325,7 +343,10 @@ public void onGameStateChanged(final GameStateChanged event) GlobalFakeObjects.createNpcs(client, runeliteObjectManager, configManager, config); newVersionManager.updateChatWithNotificationIfNewVersion(); questBankManager.setUnknownInitialState(); + playerStateManager.setUnknownInitialState(); potionStorage.updateCachedPotions = true; + boolean isLeague = client.getWorldType().contains(WorldType.SEASONAL); + SwingUtilities.invokeLater(() -> panel.updateRegionFilterVisibility(isLeague)); clientThread.invokeAtTickEnd(() -> { questManager.setupRequirements(); questManager.setupOnLogin(); @@ -342,6 +363,11 @@ private void onRuneScapeProfileChanged(RuneScapeProfileChanged ev) @Subscribe public void onVarbitChanged(VarbitChanged event) { + if (event.getVarbitId() == VarbitID.CUTSCENE_STATUS) + { + this.inCutscene = event.getValue() == 1; + } + if (!(client.getGameState() == GameState.LOGGED_IN)) { return; @@ -376,6 +402,12 @@ public void onConfigChanged(ConfigChanged event) return; } + if ("regionFilterVisibility".equals(event.getKey())) + { + boolean isLeague = client.getWorldType().contains(WorldType.SEASONAL); + SwingUtilities.invokeLater(() -> panel.updateRegionFilterVisibility(isLeague)); + } + if (configEvents.contains(event.getKey()) || event.getKey().contains("skillfilter")) { clientThread.invokeLater(questManager::updateQuestList); @@ -452,6 +484,37 @@ else if (developerMode && commandExecuted.getCommand().equals("qh-inv")) } log.debug(String.valueOf(inv)); } + else if (developerMode && commandExecuted.getCommand().equals("qh")) + { + var args = commandExecuted.getArguments(); + if (args.length == 0) + { + return; + } + var subCommand = args[0]; + if (subCommand.equals("container")) + { + if (args.length < 2) + { + return; + } + var container = args[1]; + switch (container) + { + case "keyring": + var keyringItems = QuestContainerManager.getKeyRingData().getItems(); + for (var item : keyringItems) + { + log.debug("Key ring item: {}", item); + } + break; + } + } + else if (subCommand.equals("cheer")) + { + addCheerer(); + } + } } @Subscribe(priority = 100) @@ -470,6 +533,11 @@ public List getPluginBankTagItemsForSections() return questBankManager.getBankTagService().getPluginBankTagItemsForSections(false); } + public boolean isBankTabOpen() + { + return questBankTabInterface.isQuestTabActive(); + } + public @Nullable QuestHelper getSelectedQuest() { return questManager.getSelectedQuest(); @@ -530,7 +598,8 @@ public void onMenuEntryAdded(MenuEntryAdded event) @Subscribe public void onChatMessage(ChatMessage chatMessage) { - if (chatMessage.getMessage().equals("The crate is full of bananas.")) { + if (chatMessage.getMessage().equals("The crate is full of bananas.")) + { fullCrate = true; } if (config.showFan() && chatMessage.getType() == ChatMessageType.GAMEMESSAGE) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java index 90c88c4c77..041de959ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTab.java @@ -34,10 +34,12 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.*; import net.runelite.api.events.*; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.InventoryID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarClientID; +import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.ItemQuantityMode; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; @@ -55,13 +57,15 @@ import javax.inject.Inject; import javax.inject.Singleton; -import java.awt.*; import java.awt.Point; -import java.util.*; +import java.awt.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; +import static net.runelite.client.plugins.microbot.questhelper.bank.banktab.PotionStorage.COMPONENTS_PER_POTION; +import static net.runelite.client.plugins.microbot.questhelper.bank.banktab.PotionStorage.VIAL_IDX; import static net.runelite.client.plugins.banktags.BankTagsPlugin.*; @Singleton diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java index 849b9d7035..32e6be9e82 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestBankTabInterface.java @@ -132,10 +132,6 @@ public void handleClick(MenuOptionClicked event) return; } String menuOption = event.getMenuOption(); - if (menuOption == null) - { - return; - } // If click a base tab, close boolean clickedTabTag = menuOption.startsWith("View tab") && !event.getMenuTarget().equals("quest-helper"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java index 48d4486ff5..fc2b9b77dd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bank/banktab/QuestHelperBankTagService.java @@ -32,6 +32,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.api.Client; import net.runelite.api.gameval.ItemID; +import net.runelite.client.config.ConfigManager; import javax.inject.Inject; import javax.inject.Singleton; @@ -50,6 +51,9 @@ public class QuestHelperBankTagService @Inject private Client client; + @Inject + private ConfigManager configManager; + ArrayList taggedItems; ArrayList taggedItemsForBank; @@ -221,14 +225,18 @@ private void getItemsFromRequirement(List pluginItems, ItemRequirem else if (itemRequirement instanceof KeyringRequirement) { KeyringRequirement keyringRequirement = (KeyringRequirement) itemRequirement; - KeyringRequirement fakeRequirement = new KeyringRequirement(keyringRequirement.getName(), plugin.getConfigManager(), - keyringRequirement.getKeyringCollection()); - if (keyringRequirement.hasKeyOnKeyRing()) + var keyringCollection = keyringRequirement.getKeyringCollection(); + var fakeRequirement = keyringRequirement.copy(); + if (keyringCollection.hasKeyOnKeyRing(configManager)) { fakeRequirement.addAlternates(ItemID.FAVOUR_KEY_RING); + // NOTE: If the key is on your key ring _AND_ in your bank, we will still suggest using the key ring. + pluginItems.add(new BankTabItem(fakeRequirement, ItemID.FAVOUR_KEY_RING)); + } + else + { + pluginItems.add(makeBankTabItem(fakeRequirement)); } - pluginItems.add(makeBankTabItem(fakeRequirement)); - } else { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bikeshedder/BikeShedder.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bikeshedder/BikeShedder.java deleted file mode 100644 index 67222f288e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/bikeshedder/BikeShedder.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2024, pajlada - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.bikeshedder; - -import com.google.common.collect.ImmutableMap; -import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.collections.TeleportCollections; -import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; -import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.player.SpellbookRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.Spellbook; -import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.client.plugins.microbot.questhelper.steps.widget.NormalSpells; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - -public class BikeShedder extends BasicQuestHelper -{ - private DetailedQuestStep moveToLumbridge; - private DetailedQuestStep confuseHans; - private DetailedQuestStep equipLightbearer; - - private ItemRequirement anyLog; - private ObjectStep useLogOnBush; - - private ItemRequirement oneCoin; - private ItemRequirement manyCoins; - private ObjectStep useCoinOnBush; - private ObjectStep useManyCoinsOnBush; - - private ItemRequirement varrockTeleport; - private ItemRequirement ardougneTeleport; - private ItemRequirement faladorTeleport; - - private Zone conditionalRequirementZone; - private ZoneRequirement conditionalRequirementZoneRequirement; - private ZoneRequirement conditionalRequirementZoneSouthRequirement; - private ZoneRequirement conditionalRequirementZoneNorthRequirement; - private ItemRequirement conditionalRequirementCoins; - private DetailedQuestStep conditionalRequirementLookAtCoins; - private ItemRequirement conditionalRequirementGoldBar; - private WidgetTextRequirement lookAtCooksAssistantRequirement; - private DetailedQuestStep lookAtCooksAssistant; - private WidgetTextRequirement lookAtCooksAssistantTextRequirement; - private ZoneRequirement byStaircaseInSunrisePalace; - private ObjectStep goDownstairsInSunrisePalace; - private DetailedQuestStep haveRunes; - private ItemRequirement lightbearer; - private ItemRequirement elemental30Unique; - private ItemRequirement elemental30; - private ItemRequirement anyCoins; - private ItemStep getCoins; - - // Sailing - private NpcStep talkToNpcOnBoat; - private NpcStep talkToKlarenceFromShip; - private ObjectStep useSalvagingHook; - private ObjectStep useObjectOffBoat; - private ZoneRequirement onBoat1; - private ZoneRequirement onBoat2; - private ZoneRequirement onBoat3; - private ZoneRequirement onBoat4; - - @Override - public Map loadSteps() - { - var lumbridge = new Zone(new WorldPoint(3217, 3210, 0), new WorldPoint(3226, 3228, 0)); - var outsideLumbridge = new ZoneRequirement(false, lumbridge); - moveToLumbridge.setHighlightZone(lumbridge); - var steps = new ConditionalStep(this, confuseHans); - - // aldarin bank - var plankNoBank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); - { - // Do not check bank for plank - var plankStep = new DetailedQuestStep(this, "Plank requirement will not check bank", plankNoBank); - var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will not check bank (Requirement used as conditional step passed)", plankNoBank); - var cPlankStep = new ConditionalStep(this, plankStep); - cPlankStep.addStep(plankNoBank, plankStepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2926, 0)), cPlankStep); - } - - { - // Check bank for plank using alsoCheckBank - var plank = plankNoBank.alsoCheckBank(); - plank.setName("Plank (check bank 1)"); - var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 1", plank); - var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 1 (Requirement used as conditional step passed)", plank); - var cPlankStep = new ConditionalStep(this, plankStep); - cPlankStep.addStep(plank, plankStepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2925, 0)), cPlankStep); - } - - { - // Check bank for plank using setShouldCheckBank - var plank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); - plank.setShouldCheckBank(true); - plank.setName("Plank (check bank 2)"); - var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 2", plank); - var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 2 (Requirement used as conditional step passed)", plank); - var cPlankStep = new ConditionalStep(this, plankStep); - cPlankStep.addStep(plank, plankStepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2924, 0)), cPlankStep); - } - - // mistrock bank - { - // does not need to be equipped - var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); - var step = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped", blueWizardHat); - var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped (Requirement used as conditional step passed)", blueWizardHat); - var cStep = new ConditionalStep(this, step); - cStep.addStep(blueWizardHat, stepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1383, 2866, 0)), cStep); - } - - { - // must be equipped - var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); - blueWizardHat.setMustBeEquipped(true); - var step = new DetailedQuestStep(this, "Blue wizard hat, must be equipped", blueWizardHat); - var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, must be equipped (Requirement used as conditional step passed)", blueWizardHat); - var cStep = new ConditionalStep(this, step); - cStep.addStep(blueWizardHat, stepPassed); - steps.addStep(new ZoneRequirement(new WorldPoint(1382, 2866, 0)), cStep); - } - - // Boat - steps.addStep(onBoat1, talkToNpcOnBoat); - steps.addStep(onBoat2, talkToKlarenceFromShip); - steps.addStep(onBoat3, useSalvagingHook); - steps.addStep(onBoat4, useObjectOffBoat); - - steps.addStep(byStaircaseInSunrisePalace, goDownstairsInSunrisePalace); - steps.addStep(outsideLumbridge, moveToLumbridge); - steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3218, 0)), haveRunes); - steps.addStep(new ZoneRequirement(new WorldPoint(3222, 3218, 0)), equipLightbearer); - steps.addStep(new ZoneRequirement(new WorldPoint(3223, 3218, 0)), useLogOnBush); - steps.addStep(new ZoneRequirement(new WorldPoint(3222, 3217, 0)), useCoinOnBush); - steps.addStep(new ZoneRequirement(new WorldPoint(3223, 3216, 0)), useManyCoinsOnBush); - steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3216, 0)), getCoins); - steps.addStep(conditionalRequirementZoneRequirement, conditionalRequirementLookAtCoins); - steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3221, 0)), lookAtCooksAssistant); - - return new ImmutableMap.Builder() - .put(-1, steps) - .build(); - } - - @Override - protected void setupRequirements() - { - moveToLumbridge = new DetailedQuestStep(this, new WorldPoint(3221, 3218, 0), "Move to outside Lumbridge Castle"); - - var normalSpellbook = new SpellbookRequirement(Spellbook.NORMAL); - - confuseHans = new NpcStep(this, NpcID.HANS, new WorldPoint(3221, 3218, 0), "Cast Confuse on Hans", normalSpellbook); - confuseHans.addSpellHighlight(NormalSpells.CONFUSE); - - lightbearer = new ItemRequirement("Lightbearer", ItemID.LIGHTBEARER).highlighted(); - equipLightbearer = new DetailedQuestStep(this, "Equip a Lightbearer", lightbearer.equipped()); - - anyLog = new ItemRequirement("Any log", ItemCollections.LOGS_FOR_FIRE).highlighted(); - - useLogOnBush = new ObjectStep(this, ObjectID.PVPW_ARMOURSTAND_BUSH, new WorldPoint(3223, 3217, 0), "Use log on bush", anyLog); - useLogOnBush.addIcon(ItemID.LOGS); - - varrockTeleport = TeleportCollections.VARROCK_TELEPORT.getItemRequirement(); - ardougneTeleport = TeleportCollections.ARDOUGNE_TELEPORT.getItemRequirement(); - faladorTeleport = TeleportCollections.FALADOR_TELEPORT.getItemRequirement(); - - oneCoin = new ItemRequirement("Coins", ItemCollections.COINS, 1); - oneCoin.setHighlightInInventory(true); - useCoinOnBush = new ObjectStep(this, ObjectID.PVPW_ARMOURSTAND_BUSH, new WorldPoint(3223, 3217, 0), "Use coins on the bush.", oneCoin); - useCoinOnBush.addIcon(ItemID.COINS); - - manyCoins = new ItemRequirement("Coins", ItemCollections.COINS, 100); - manyCoins.setHighlightInInventory(true); - useManyCoinsOnBush = new ObjectStep(this, ObjectID.PVPW_ARMOURSTAND_BUSH, new WorldPoint(3223, 3217, 0), "Use many coins on the bush.", manyCoins); - useManyCoinsOnBush.addIcon(ItemID.COINS); - - conditionalRequirementZone = new Zone(new WorldPoint(3223, 3221, 0), new WorldPoint(3223, 3223, 0)); - conditionalRequirementZoneRequirement = new ZoneRequirement(conditionalRequirementZone); - conditionalRequirementZoneSouthRequirement = new ZoneRequirement(new WorldPoint(3223, 3221, 0)); - conditionalRequirementZoneNorthRequirement = new ZoneRequirement(new WorldPoint(3223, 3223, 0)); - - conditionalRequirementCoins = new ItemRequirement("Coins", ItemCollections.COINS, 50); - conditionalRequirementCoins.setTooltip("Obtained by robbing a bank"); - conditionalRequirementCoins.setHighlightInInventory(true); - conditionalRequirementCoins.setConditionToHide(conditionalRequirementZoneSouthRequirement); - - conditionalRequirementGoldBar = new ItemRequirement("Gold Bar", ItemID.GOLD_BAR, 1); - conditionalRequirementGoldBar.setTooltip("Obtained by robbing a bank"); - conditionalRequirementGoldBar.setHighlightInInventory(true); - conditionalRequirementGoldBar.setConditionToHide(or(conditionalRequirementZoneNorthRequirement, conditionalRequirementZoneSouthRequirement)); - - conditionalRequirementLookAtCoins = new DetailedQuestStep(this, "Admire the coins in your inventory.", conditionalRequirementCoins); - - lookAtCooksAssistantRequirement = new WidgetTextRequirement(InterfaceID.Questjournal.TITLE, "Cook's Assistant"); - lookAtCooksAssistantRequirement.setDisplayText("Cook's Assistant quest journal open"); - lookAtCooksAssistantTextRequirement = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "he now lets me use his high quality range"); - lookAtCooksAssistantTextRequirement.setDisplayText("Cook's Assistant quest journal open & received reward (checking text)"); - lookAtCooksAssistant = new DetailedQuestStep(this, "Open the Cook's Assistant quest journal. You must have started the quest for this test to work.", lookAtCooksAssistantRequirement, lookAtCooksAssistantTextRequirement); - - var upstairsInSunrisePalace = new Zone(new WorldPoint(1684, 3162, 1), new WorldPoint(1691, 3168, 1)); - byStaircaseInSunrisePalace = new ZoneRequirement(upstairsInSunrisePalace); - goDownstairsInSunrisePalace = new ObjectStep(getQuest().getQuestHelper(), ObjectID.CIVITAS_PALACE_STAIRS_DOWN, new WorldPoint(1690, 3164, 1), "Climb downstairs, ensure stairs are well highlighted!"); - - - var fire30 = new ItemRequirement("Fire runes", ItemID.FIRERUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 63)); - var air30 = new ItemRequirement("Air runes", ItemID.AIRRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 66)); - var water30 = new ItemRequirement("Water runes", ItemID.WATERRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 56)); - var earth30 = new ItemRequirement("Earth runes", ItemID.EARTHRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 60)); - elemental30Unique = new ItemRequirements(LogicType.OR, "Elemental runes as ItemRequirements OR", air30, water30, earth30, fire30); - elemental30Unique.addAlternates(ItemID.FIRERUNE, ItemID.EARTHRUNE, ItemID.AIRRUNE); - elemental30 = new ItemRequirement("Elemental rune as ItemRequirement", List.of(ItemID.AIRRUNE, ItemID.EARTHRUNE, ItemID.WATERRUNE, - ItemID.FIRERUNE), 30); - elemental30.setTooltip("You have potato"); - haveRunes = new DetailedQuestStep(this, "Compare rune checks for ItemRequirement and ItemRequirements with OR.", elemental30, elemental30Unique); - - anyCoins = new ItemRequirement("Coins", ItemCollections.COINS); - getCoins = new ItemStep(this, new WorldPoint(3224, 3215, 0), "Get coins", anyCoins); - - // Sailing - - var zones1 = new Zone[] { - new Zone(new WorldPoint(3843, 6402, 1), new WorldPoint(3844, 6402, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6389, 1), new WorldPoint(3876, 6389, 1)), - new Zone(new WorldPoint(3842, 6365, 1), new WorldPoint(3860, 6365, 1)), - new Zone(new WorldPoint(3843, 6354, 1), new WorldPoint(3884, 6354, 1)) - }; - onBoat1 = new ZoneRequirement(zones1); - - var zones2 = new Zone[] { - new Zone(new WorldPoint(3843, 6403, 1), new WorldPoint(3844, 6403, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6390, 1), new WorldPoint(3876, 6390, 1)), - new Zone(new WorldPoint(3842, 6366, 1), new WorldPoint(3860, 6366, 1)), - new Zone(new WorldPoint(3843, 6355, 1), new WorldPoint(3884, 6355, 1)) - }; - onBoat2 = new ZoneRequirement(zones2); - - var zones3 = new Zone[] { - new Zone(new WorldPoint(3843, 6404, 1), new WorldPoint(3844, 6404, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6391, 1), new WorldPoint(3876, 6391, 1)), - new Zone(new WorldPoint(3842, 6367, 1), new WorldPoint(3860, 6367, 1)), - new Zone(new WorldPoint(3843, 6356, 1), new WorldPoint(3884, 6356, 1)) - }; - onBoat3 = new ZoneRequirement(zones3); - - var zones4 = new Zone[] { - new Zone(new WorldPoint(3843, 6405, 1), new WorldPoint(3844, 6405, 1)), // Tutorial - new Zone(new WorldPoint(3842, 6312, 1), new WorldPoint(3876, 6392, 1)), - new Zone(new WorldPoint(3842, 6368, 1), new WorldPoint(3860, 6368, 1)), - new Zone(new WorldPoint(3843, 6357, 1), new WorldPoint(3884, 6357, 1)) - }; - onBoat4 = new ZoneRequirement(zones4); - - talkToNpcOnBoat = new NpcStep(this, NpcID.SAILING_INTRO_ANNE_BOAT, "Talk to a ship NPC."); - List shipNpcs = new ArrayList<>(); - for (int i = NpcID.SAILING_CREW_GENERIC_1_WORLD; i <= NpcID.SAILING_CREW_GHOST_JENKINS_CARGO_3; i++) - { - shipNpcs.add(i); - } - talkToNpcOnBoat.addHighlightZones(zones1); - talkToNpcOnBoat.addAlternateNpcs(shipNpcs.toArray(new Integer[0])); - - talkToKlarenceFromShip = new NpcStep(this, NpcID.KLARENSE, new WorldPoint(3046, 3205, 0), "Klarence off the ship."); - talkToKlarenceFromShip.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); - talkToKlarenceFromShip.addHighlightZones(zones2); - List salvagingHookIds = new ArrayList<>(); - for (int i = ObjectID.SAILING_INTRO_SALVAGING_HOOK; i <= ObjectID.SALVAGING_HOOK_LARGE_DRAGON_B; i++) - { - salvagingHookIds.add(i); - } - - useSalvagingHook = new ObjectStep(this, ObjectID.SAILING_INTRO_SALVAGING_HOOK, "Use the salvaging hook."); - useSalvagingHook.addAlternateObjects(salvagingHookIds.toArray(new Integer[0])); - useSalvagingHook.addHighlightZones(zones3); - - useObjectOffBoat = new ObjectStep(this, ObjectID.DRAGONSHIPGANGPLANK_ON, new WorldPoint(3047, 3205, 0), "Click Klarense's gangplank."); - useObjectOffBoat.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); - useObjectOffBoat.addHighlightZones(zones4); - } - - @Override - public List getItemRecommended() { - return Arrays.asList(varrockTeleport, ardougneTeleport, faladorTeleport, elemental30, elemental30Unique); - } - - @Override - public List getPanels() - { - var panels = new ArrayList(); - - panels.add(new PanelDetails("Move to Lumbridge", List.of(moveToLumbridge))); - panels.add(new PanelDetails("Normal Spellbook", List.of(confuseHans))); - panels.add(new PanelDetails("Equip Lightbearer", List.of(equipLightbearer), List.of(lightbearer))); - panels.add(new PanelDetails("Use log on mysterious bush", List.of(useLogOnBush), List.of(anyLog))); - panels.add(new PanelDetails("Use coins on mysterious bush", List.of(useCoinOnBush, useManyCoinsOnBush), List.of(oneCoin, manyCoins))); - panels.add(new PanelDetails("Conditional requirement", List.of(conditionalRequirementLookAtCoins), List.of(conditionalRequirementCoins, conditionalRequirementGoldBar))); - panels.add(new PanelDetails("Item step", List.of(getCoins), List.of(anyCoins))); - panels.add(new PanelDetails("Quest state", List.of(lookAtCooksAssistant), List.of(lookAtCooksAssistantRequirement, lookAtCooksAssistantTextRequirement))); - panels.add(new PanelDetails("Ensure staircase upstairs in Sunrise Palace is highlighted", List.of(goDownstairsInSunrisePalace), List.of())); - panels.add(new PanelDetails("Sailing", List.of(talkToNpcOnBoat, talkToKlarenceFromShip, useSalvagingHook, useObjectOffBoat), List.of())); - - return panels; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java index 37a15faf42..4fe8c70dff 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/ItemCollections.java @@ -243,6 +243,39 @@ public enum ItemCollections ItemID.WILDERNESS_SWORD_ELITE )), + THROWING_KNIVES("Throwing Knives", ImmutableList.of( + ItemID.BRONZE_KNIFE, ItemID.BRONZE_KNIFE_P, ItemID.BRONZE_KNIFE_P_, ItemID.BRONZE_KNIFE_P__, + ItemID.IRON_KNIFE, ItemID.IRON_KNIFE_P, ItemID.IRON_KNIFE_P_, ItemID.IRON_KNIFE_P__, + ItemID.STEEL_KNIFE, ItemID.STEEL_KNIFE_P, ItemID.STEEL_KNIFE_P_, ItemID.STEEL_KNIFE_P__, + ItemID.BLACK_KNIFE, ItemID.BLACK_KNIFE_P, ItemID.BLACK_KNIFE_P_, ItemID.BLACK_KNIFE_P__, + ItemID.MITHRIL_KNIFE, ItemID.MITHRIL_KNIFE_P, ItemID.MITHRIL_KNIFE_P_, ItemID.MITHRIL_KNIFE_P__, + ItemID.ADAMANT_KNIFE, ItemID.ADAMANT_KNIFE_P, ItemID.ADAMANT_KNIFE_P_, ItemID.ADAMANT_KNIFE_P__, + ItemID.RUNE_KNIFE, ItemID.RUNE_KNIFE_P, ItemID.RUNE_KNIFE_P_, ItemID.RUNE_KNIFE_P__, + ItemID.DRAGON_KNIFE, ItemID.DRAGON_KNIFE_P, ItemID.DRAGON_KNIFE_P_, ItemID.DRAGON_KNIFE_P__ + )), + + DARTS("Darts", ImmutableList.of( + ItemID.BRONZE_DART, ItemID.BRONZE_DART_P, ItemID.BRONZE_DART_P_, ItemID.BRONZE_DART_P__, + ItemID.IRON_DART, ItemID.IRON_DART_P, ItemID.IRON_DART_P_, ItemID.IRON_DART_P__, + ItemID.STEEL_DART, ItemID.STEEL_DART_P, ItemID.STEEL_DART_P_, ItemID.STEEL_DART_P__, + ItemID.BLACK_DART, ItemID.BLACK_DART_P, ItemID.BLACK_DART_P_, ItemID.BLACK_DART_P__, + ItemID.MITHRIL_DART, ItemID.MITHRIL_DART_P, ItemID.MITHRIL_DART_P_, ItemID.MITHRIL_DART_P__, + ItemID.ADAMANT_DART, ItemID.ADAMANT_DART_P, ItemID.ADAMANT_DART_P_, ItemID.ADAMANT_DART_P__, + ItemID.RUNE_DART, ItemID.RUNE_DART_P, ItemID.RUNE_DART_P_, ItemID.RUNE_DART_P__, + ItemID.AMETHYST_DART, ItemID.AMETHYST_DART_P, ItemID.AMETHYST_DART_P_, ItemID.AMETHYST_DART_P__, + ItemID.DRAGON_DART, ItemID.DRAGON_DART_P, ItemID.DRAGON_DART_P_, ItemID.DRAGON_DART_P__ + )), + + THROWING_AXES("Throwing Axes", ImmutableList.of( + ItemID.BRONZE_THROWNAXE, + ItemID.IRON_THROWNAXE, + ItemID.STEEL_THROWNAXE, + ItemID.MITHRIL_THROWNAXE, + ItemID.ADAMNT_THROWNAXE, + ItemID.RUNE_THROWNAXE, + ItemID.DRAGON_THROWNAXE + )), + METAL_ARROWS(ImmutableList.of( ItemID.RUNE_ARROW, ItemID.ADAMANT_ARROW, @@ -2211,6 +2244,25 @@ public enum ItemCollections ItemID.WILDBLOOD_HOP_SEED )), + /// Things you can slash webs with that are safe to bring to wildy + SLASH_WEB_KNIFE(ImmutableList.of( + ItemID.KNIFE, + ItemID.WILDERNESS_SWORD_ELITE, + ItemID.WILDERNESS_SWORD_HARD, + ItemID.WILDERNESS_SWORD_MEDIUM, + ItemID.WILDERNESS_SWORD_EASY + )), + + BOAT_REPAIR_KITS(ImmutableList.of( + ItemID.BOAT_REPAIR_KIT_ROSEWOOD, + ItemID.BOAT_REPAIR_KIT_IRONWOOD, + ItemID.BOAT_REPAIR_KIT_CAMPHOR, + ItemID.BOAT_REPAIR_KIT_MAHOGANY, + ItemID.BOAT_REPAIR_KIT_TEAK, + ItemID.BOAT_REPAIR_KIT_OAK, + ItemID.BOAT_REPAIR_KIT + )), + BUSH_SEEDS(ImmutableList.of( ItemID.REDBERRY_BUSH_SEED, ItemID.CADAVABERRY_BUSH_SEED, @@ -2252,6 +2304,13 @@ public enum ItemCollections ItemID.CA_OFFHAND_EASY )), + ARDOUGNE_CLOAK(ImmutableList.of( + ItemID.ARDY_CAPE_EASY, + ItemID.ARDY_CAPE_MEDIUM, + ItemID.ARDY_CAPE_HARD, + ItemID.ARDY_CAPE_ELITE + )), + PROSPECTOR_HELMET(ImmutableList.of( ItemID.MOTHERLODE_REWARD_HAT, ItemID.FOSSIL_MOTHERLODE_REWARD_HAT, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java index aae9f687d5..341738056a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/KeyringCollection.java @@ -24,16 +24,11 @@ */ package net.runelite.client.plugins.microbot.questhelper.collections; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import lombok.Getter; import net.runelite.api.gameval.ItemID; import net.runelite.client.config.ConfigManager; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - public enum KeyringCollection { SHINY_KEY(ItemID.IKOV_SHINYKEY), @@ -50,14 +45,18 @@ public enum KeyringCollection ENCHANTED_KEY(ItemID.MAKINGHISTORY_KEY), NEW_KEY(ItemID.MOURNING_EXCAVATION_KEY); + private final String CONFIG_GROUP = QuestHelperConfig.QUEST_BACKGROUND_GROUP; + @Getter private final int itemID; + KeyringCollection(int itemID) { this.itemID = itemID; } - public String toChatText() + /// The name of this key as seen in the chat box. + public String chatboxText() { return name().toLowerCase().replaceAll("_", " "); } @@ -67,19 +66,20 @@ public String runeliteName() return name().toLowerCase().replaceAll("_", ""); } - public static List allKeyRequirements(ConfigManager configManager) + public boolean hasKeyOnKeyRing(ConfigManager configManager) { - List keys = new ArrayList<>(); - for (KeyringCollection keyringCollection : Collections.unmodifiableList(Arrays.asList(values()))) - { - keys.add(new KeyringRequirement(configManager, keyringCollection)); - } + var value = configManager.getRSProfileConfiguration(CONFIG_GROUP, runeliteName()); - return keys; + return "true".equals(value); } - public KeyringRequirement getRequirement(ConfigManager configManager) + public void setHasKeyOnKeyRing(ConfigManager configManager, boolean value) { - return new KeyringRequirement(configManager, this); + if (configManager.getRSProfileKey() == null) + { + return; + } + + configManager.setRSProfileConfiguration(CONFIG_GROUP, runeliteName(), value ? "true" : "false"); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java index 5e57251daf..258d034304 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/collections/TeleportCollections.java @@ -29,7 +29,7 @@ public ItemRequirement getItemRequirement() ItemRequirement varrockRunes = new ItemRequirements("Varrock teleport runes", new ItemRequirement("Law rune", ItemID.LAWRUNE, 1), new ItemRequirement("Air rune", ItemID.AIRRUNE, 3), - new ItemRequirement("Water rune", ItemID.WATERRUNE, 1) + new ItemRequirement("Fire rune", ItemID.FIRERUNE, 1) ); return new ItemRequirements(LogicType.OR, "Teleport to Varrock. Varrock teleport tablet/spell, Chronicle, Ring of Wealth (Grand Exchange [2])", varrockTele, varrockRunes); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/ConfigKeys.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/ConfigKeys.java deleted file mode 100644 index 5a7402bf71..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/ConfigKeys.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2024, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.config; - -import lombok.Getter; - -public enum ConfigKeys -{ - // Barbarian Training Enums - BARBARIAN_TRAINING_STARTED_FISHING("barbariantrainingstartedfishing"), - BARBARIAN_TRAINING_STARTED_HARPOON("barbariantrainingstartedharpoon"), - BARBARIAN_TRAINING_STARTED_SEED_PLANTING("barbariantrainingstartedseedplanting"), - BARBARIAN_TRAINING_STARTED_POT_SMASHING("barbariantrainingstartedpotsmashing"), - BARBARIAN_TRAINING_STARTED_FIREMAKING("barbariantrainingstartedfiremaking"), - BARBARIAN_TRAINING_STARTED_PYREMAKING("barbariantrainingstartedpyremaking"), - BARBARIAN_TRAINING_STARTED_HERBLORE("barbariantrainingstartedherblore"), - BARBARIAN_TRAINING_STARTED_SPEAR("barbariantrainingstartedspear"), - BARBARIAN_TRAINING_STARTED_HASTA("barbariantrainingstartedhasta"), - - // Finished Barbarian Training Enums - BARBARIAN_TRAINING_FINISHED_FISHING("barbariantrainingfinishedfishing"), - BARBARIAN_TRAINING_FINISHED_HARPOON("barbariantrainingfinishedharpoon"), - BARBARIAN_TRAINING_FINISHED_SEED_PLANTING("barbariantrainingfinishedseedplanting"), - BARBARIAN_TRAINING_FINISHED_POT_SMASHING("barbariantrainingfinishedpotsmashing"), - BARBARIAN_TRAINING_FINISHED_FIREMAKING("barbariantrainingfinishedfiremaking"), - BARBARIAN_TRAINING_FINISHED_PYREMAKING("barbariantrainingfinishedpyremaking"), - BARBARIAN_TRAINING_FINISHED_SPEAR("barbariantrainingfinishedspear"), - BARBARIAN_TRAINING_FINISHED_HASTA("barbariantrainingfinishedhasta"), - BARBARIAN_TRAINING_FINISHED_HERBLORE("barbariantrainingfinishedherblore"), - - // Mid-conditions - BARBARIAN_TRAINING_PLANTED_SEED("barbariantrainingplantedseed"), - BARBARIAN_TRAINING_SMASHED_POT("barbariantrainingsmashedpot"), - BARBARIAN_TRAINING_BOW_FIRE("barbariantrainingbowfire"), - BARBARIAN_TRAINING_PYRE_MADE("barbariantrainingpyremade"), - BARBARIAN_TRAINING_BARBFISHED("barbariantrainingbarbfished"), - BARBARIAN_TRAINING_HARPOONED_FISH("barbariantrainingharpoonedfish"), - BARBARIAN_TRAINING_MADE_POTION("barbariantrainingmadepotion"), - BARBARIAN_TRAINING_MADE_SPEAR("barbariantrainingmadespear"), - BARBARIAN_TRAINING_MADE_HASTA("barbariantrainingmadehasta"); - - @Getter - final String key; - - ConfigKeys(String key) - { - this.key = key; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/RegionHintArrowRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/LeagueFiltering.java similarity index 56% rename from runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/RegionHintArrowRequirement.java rename to runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/LeagueFiltering.java index 6d58100b98..7328abe254 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/RegionHintArrowRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/config/LeagueFiltering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Zoinkwiz + * Copyright (c) 2026, Syrif * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,43 +22,34 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.client.plugins.microbot.questhelper.requirements; +package net.runelite.client.plugins.microbot.questhelper.config; -import net.runelite.api.Client; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueQuestRegions; +import net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueRegion; -public class RegionHintArrowRequirement extends SimpleRequirement -{ - private final Zone zone; +import java.util.EnumSet; - public RegionHintArrowRequirement(WorldPoint worldPoint) - { - assert(worldPoint != null); - this.zone = new Zone(worldPoint, worldPoint); - } +/** + * Filters quests by league regions selected in the panel UI. + * When no regions are selected, all quests pass. When regions are selected, + * only quests completable with those regions are shown. + */ +public class LeagueFiltering +{ + private static EnumSet selectedRegions = null; - public RegionHintArrowRequirement(Zone zone) + public static void setSelectedRegions(EnumSet regions) { - assert(zone != null); - this.zone = zone; + selectedRegions = (regions == null || regions.isEmpty()) ? null : regions; } - public boolean check(Client client) + public static boolean passesLeagueFilter(QuestHelper questHelper) { - WorldPoint hintArrowPoint = client.getHintArrowPoint(); - if (hintArrowPoint == null) + if (selectedRegions == null) { - return false; + return true; } - - WorldPoint wp = QuestPerspective.getWorldPointConsideringWorldView(client, client.getTopLevelWorldView(), hintArrowPoint); - if (wp == null) - { - return false; - } - - return zone.contains(wp); + return LeagueQuestRegions.isCompletableWith(questHelper.getQuest(), selectedRegions); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/domain/QuetzalDestination.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/domain/QuetzalDestination.java new file mode 100644 index 0000000000..bfd66ce012 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/domain/QuetzalDestination.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2026, pajlada + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.domain; + +import lombok.RequiredArgsConstructor; + +/// Mapping from quetzal destinations to the model ID used in the quetzal map widget. +/// +/// See {@link net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight#createQuetzalHighlight} +@RequiredArgsConstructor +public enum QuetzalDestination +{ + CIVITAS_ILLA_FORTIS(51208), + THE_TEOMAT(51205), + SUNSET_COAST(51187), + HUNTER_GUILD(51185), + ALDARIN(54547), + QUETZACALLI_GORGE(54539), + TAL_TEKLAN(56665); + + public final int modelID; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java index c7fab86e21..7b46a4c89a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneEasy.java @@ -41,6 +41,8 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -49,9 +51,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; -import java.util.ArrayList; -import java.util.List; - public class ArdougneEasy extends ComplexStateQuestHelper { // Required items @@ -279,7 +278,7 @@ public List getPanels() sections.add(PanelDetails.lockedPanel( "Identify Sword", notIdentifySword, - identifySword, + identifySwordTask, List.of( identifySword ), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java index 09d5b1c246..63c427560f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneElite.java @@ -119,11 +119,11 @@ public QuestStep loadStep() doElite.addStep(notPickHero, pickHeroTask); runeCrossbowTask = new ConditionalStep(this, spinString); - runeCrossbowTask.addStep(new Conditions(madeString, crossbowString), moveToYan); - runeCrossbowTask.addStep(new Conditions(inYanille, madeString, crossbowString), smithLimbs); - runeCrossbowTask.addStep(new Conditions(inYanille, madeLimbs, crossbowString, runeLimbs), fletchStock); - runeCrossbowTask.addStep(new Conditions(inYanille, madeStock, crossbowString, runeLimbs, yewStock), makeUnstrungCross); runeCrossbowTask.addStep(new Conditions(inYanille, madeCrossU, runeCrossbowU, crossbowString), runeCrossbow); + runeCrossbowTask.addStep(new Conditions(inYanille, madeStock, crossbowString, runeLimbs, yewStock), makeUnstrungCross); + runeCrossbowTask.addStep(new Conditions(inYanille, madeLimbs, crossbowString, runeLimbs), fletchStock); + runeCrossbowTask.addStep(new Conditions(inYanille, madeString, crossbowString), smithLimbs); + runeCrossbowTask.addStep(new Conditions(madeString, crossbowString), moveToYan); doElite.addStep(notRuneCrossbow, runeCrossbowTask); return doElite; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java index d08ea96525..cee94899a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneHard.java @@ -187,7 +187,7 @@ protected void setupRequirements() var hasCompletedSOTE = new QuestRequirement(QuestHelperQuest.SONG_OF_THE_ELVES, QuestState.FINISHED); - newKey = new KeyringRequirement("New key", configManager, KeyringCollection.NEW_KEY).showConditioned(notDeathRune).isNotConsumed().hideConditioned(hasCompletedSOTE); + newKey = new KeyringRequirement("New key", KeyringCollection.NEW_KEY).showConditioned(notDeathRune).isNotConsumed().hideConditioned(hasCompletedSOTE); newKey.setTooltip("Another can be found on the desk in the south-east room of the Mourner HQ basement."); mournerBoots = new ItemRequirement("Mourner boots", ItemID.MOURNING_MOURNER_BOOTS).isNotConsumed().hideConditioned(hasCompletedSOTE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java index 78ae2a463c..1a8c9e4ebf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/ardougne/ArdougneMedium.java @@ -52,7 +52,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import net.runelite.client.game.FishingSpot; import java.util.ArrayList; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java index cf00c7c3de..99af7a2e11 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertEasy.java @@ -39,8 +39,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java index ae515eed2a..61129b38e2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/desert/DesertElite.java @@ -225,7 +225,7 @@ public List getItemRequirements() { return Arrays.asList(rawPie, waterRune.quantity(6), bloodRune.quantity(2), deathRune.quantity(4), dragonDartTip, feather, kqHead, mahoganyPlank.quantity(2), goldLeaves.quantity(2), coins.quantity(50000), saw, - hammer, kqHead); + hammer); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java index 05cd374f16..a53d8be127 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorEasy.java @@ -157,7 +157,7 @@ protected void setupRequirements() //Required bucket = new ItemRequirement("Bucket", ItemID.BUCKET_EMPTY).showConditioned(notFilledWater).isNotConsumed(); - tiara = new ItemRequirement("Silver Tiara", ItemID.TIARA).showConditioned(notMindTiara); + tiara = new ItemRequirement("Tiara", ItemID.TIARA).showConditioned(notMindTiara); mindTalisman = new ItemRequirement("Mind Talisman", ItemID.MIND_TALISMAN).showConditioned(notMindTiara); hammer = new ItemRequirement("Hammer", ItemID.HAMMER).showConditioned(new Conditions(LogicType.OR, notMotherloadMine, notBluriteLimbs)).isNotConsumed(); pickaxe = new ItemRequirement("Any Pickaxe", ItemCollections.PICKAXES) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java index 950d2727f9..114ddbe74d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/falador/FaladorElite.java @@ -50,7 +50,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java index ff4824e6a6..43b00dee03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikElite.java @@ -51,7 +51,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java index 3826ed2387..1a670253cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/fremennik/FremennikMedium.java @@ -52,7 +52,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; @@ -443,7 +447,10 @@ public List getItemRewards() @Override public List getUnlockRewards() { - return Arrays.asList(new UnlockReward("Improved rate of gaining approval on Miscellania.")); + return Arrays.asList( + new UnlockReward("Improved rate of gaining approval on Miscellania."), + new UnlockReward("Unlocking infinite charges for your lyre with Fossegrimen costs 600 of each fish rather than 800") + ); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java index 7b17d45795..ac75ab0c37 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinEasy.java @@ -40,6 +40,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; @@ -53,16 +54,19 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; public class KandarinEasy extends ComplexStateQuestHelper { // Items required - ItemRequirement combatGear, bigFishingNet, coins, juteSeed, seedDibber, rake, batteredKey, + ItemRequirement combatGear, bigFishingNet, coins, juteSeed, seedDibber, rake, spade, batteredKey, emptyFishbowl, fishBowl, seaweed, fishBowlSeaweed, tinyNet, genericFishbowl; // Items recommended @@ -79,7 +83,7 @@ public class KandarinEasy extends ComplexStateQuestHelper QuestStep killFire, killEarth, killWater, killAir; - NpcStep catchMackerel, killEle; + NpcStep catchMackerel; Zone workshop; @@ -127,8 +131,7 @@ public QuestStep loadStep() killEleTask.addStep(new Conditions(inWorkshop, killedFire, killedEarth, killedWater), killAir); killEleTask.addStep(new Conditions(inWorkshop, killedFire, killedEarth), killWater); killEleTask.addStep(new Conditions(inWorkshop, killedFire), killEarth); - killEleTask.addStep(new Conditions(inWorkshop), killFire); - killEleTask.addStep(inWorkshop, killEle); + killEleTask.addStep(inWorkshop, killFire); doEasy.addStep(notKillEle, killEleTask); plantJuteTask = new ConditionalStep(this, plantJute); @@ -175,8 +178,11 @@ protected void setupRequirements() seaweed = new ItemRequirement("Seaweed", ItemID.SEAWEED).showConditioned(notPetFish); juteSeed = new ItemRequirement("Jute seeds", ItemID.JUTE_SEED).showConditioned(notPlantJute); rake = new ItemRequirement("Rake", ItemID.RAKE).showConditioned(notPlantJute).isNotConsumed(); - seedDibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(notPlantJute).isNotConsumed(); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY).showConditioned(notKillEle).isNotConsumed(); + var needSeedDibber = not(new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, 3)); + seedDibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(and(notPlantJute, needSeedDibber)).isNotConsumed(); + spade = new ItemRequirement("Spade (if existing plant in hops patch)", ItemID.SPADE).showConditioned(notPlantJute).isNotConsumed(); + + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY).showConditioned(notKillEle).isNotConsumed(); batteredKey.setTooltip("You can get another by searching the bookcase in the house south of the Elemental " + "Workshop, then reading the book you get from it"); @@ -227,18 +233,14 @@ public void setupSteps() "Speak with Sherlock west of Catherby."); moveToWorkshop = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_SPIRALSTAIRSTOP, new WorldPoint(2711, 3498, 0), "Enter the Elemental Workshop in Seers' Village.", batteredKey, combatGear, food); - killEle = new NpcStep(this, NpcID.ELEMENTAL_FIRE, new WorldPoint(2719, 9889, 0), - "Kill one of each of the 4 elementals.", combatGear, food); - killEle.addAlternateNpcs(NpcID.ELEMENTAL_WATER, NpcID.ELEMENTAL_AIR, NpcID.ELEMENTAL_EARTH); killFire = new NpcStep(this, NpcID.ELEMENTAL_FIRE, new WorldPoint(2719, 9877, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); + "Kill one of the fire elementals.", true, combatGear, food); killEarth = new NpcStep(this, NpcID.ELEMENTAL_EARTH, new WorldPoint(2700, 9903, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); + "Kill one of the earth elementals. Only the roaming ones work for this.", true, combatGear, food); killWater = new NpcStep(this, NpcID.ELEMENTAL_WATER, new WorldPoint(2719, 9903, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); + "Kill one of the water elementals.", true, combatGear, food); killAir = new NpcStep(this, NpcID.ELEMENTAL_AIR, new WorldPoint(2735, 9891, 0), - "Kill one of each of the 4 elementals.", true, combatGear, food); - killEle.addSubSteps(killFire, killEarth, killWater, killAir); + "Kill one of the air elementals.", true, combatGear, food); buyStew = new NpcStep(this, NpcID.FORESTERS_BARTENDER, new WorldPoint(2691, 3494, 0), "Talk with the bartender in Seers' Village and buy a stew.", coins.quantity(20)); @@ -247,7 +249,7 @@ public void setupSteps() "Play the organ in Seers' Village Church."); plantJute = new ObjectStep(this, ObjectID.FARMING_HOPS_PATCH_4, new WorldPoint(2669, 3523, 0), "Plant 3 jute seeds in the hops patch north west of Seers' Village.", juteSeed.quantity(3), - seedDibber, rake); + seedDibber, rake, spade); plantJute.addIcon(ItemID.JUTE_SEED); cupTea = new NpcStep(this, NpcID.BROTHER_GALAHAD, new WorldPoint(2612, 3474, 0), "Talk with Galahad west of McGrubor's Wood until he gives you some tea."); @@ -264,7 +266,7 @@ public void setupSteps() public List getItemRequirements() { return Arrays.asList(coins.quantity(33), bigFishingNet, juteSeed.quantity(3), - seedDibber, rake, batteredKey, genericFishbowl, seaweed, combatGear); + seedDibber, rake, spade, batteredKey, genericFishbowl, seaweed, combatGear); } @Override @@ -354,14 +356,14 @@ public List getPanels() buyStewSteps.setLockingStep(buyStewTask); allSteps.add(buyStewSteps); - PanelDetails killElesSteps = new PanelDetails("Defeat Elementals", Arrays.asList(moveToWorkshop, killEle), + PanelDetails killElesSteps = new PanelDetails("Defeat Elementals", Arrays.asList(moveToWorkshop, killFire, killEarth, killWater, killAir), eleWorkI, batteredKey, combatGear, food); killElesSteps.setDisplayCondition(notKillEle); killElesSteps.setLockingStep(killEleTask); allSteps.add(killElesSteps); PanelDetails plantJuteSteps = new PanelDetails("Plant Jute", Collections.singletonList(plantJute), - new SkillRequirement(Skill.FARMING, 13, true), juteSeed.quantity(3), seedDibber, rake); + new SkillRequirement(Skill.FARMING, 13, true), juteSeed.quantity(3), seedDibber, rake, spade); plantJuteSteps.setDisplayCondition(notPlantJute); plantJuteSteps.setLockingStep(plantJuteTask); allSteps.add(plantJuteSteps); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java index 976de10ded..41134fa0bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinElite.java @@ -147,7 +147,7 @@ protected void setupRequirements() spade = new ItemRequirement("Spade", ItemID.SPADE).showConditioned(notPickDwarf).isNotConsumed(); rake = new ItemRequirement("Rake", ItemID.RAKE).showConditioned(notPickDwarf).isNotConsumed(); compost = new ItemRequirement("Any compost", ItemCollections.COMPOST).showConditioned(notPickDwarf); - harpoon = new ItemRequirement("Harpoon", ItemID.HARPOON).showConditioned(not5Shark).isNotConsumed(); + harpoon = new ItemRequirement("Harpoon", ItemCollections.HARPOONS).showConditioned(not5Shark).isNotConsumed(); cookingGaunt = new ItemRequirement("Cooking gauntlets", ItemID.GAUNTLETS_OF_COOKING).showConditioned(not5Shark).isNotConsumed(); stamPot = new ItemRequirement("Stamina potion (2)", ItemID._2DOSESTAMINA).showConditioned(notStamMix); caviar = new ItemRequirement("Caviar", ItemID.BRUT_CAVIAR).showConditioned(notStamMix); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java index f7df8c3107..304f5709b5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinHard.java @@ -174,7 +174,7 @@ protected void setupRequirements() Conditions not70Agility = new Conditions(LogicType.NOR, new SkillRequirement(Skill.AGILITY, 70, true)); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, notWaterOrb)).isNotConsumed(); dustyKey.setTooltip("You can get this by killing the Jailer in the Black Knights Base in Taverley Dungeon and" + " using the key he drops to enter the jail cell there to talk to Velrak for the dusty key"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java index af183ee3e3..4954a50711 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kandarin/KandarinMedium.java @@ -55,11 +55,14 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; public class KandarinMedium extends ComplexStateQuestHelper { @@ -187,7 +190,7 @@ protected void setupRequirements() hornDust = new ItemRequirement("Horn Dust", ItemID.UNICORN_HORN_DUST, 1).showConditioned(notSuperAnti); vialOfWater = new ItemRequirement("Vial of water", ItemID.VIAL_WATER, 1).showConditioned(notSuperAnti); iritLeaf = new ItemRequirement("Irit leaf", ItemID.IRIT_LEAF, 1).showConditioned(notSuperAnti); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).showConditioned(new Conditions(not70Agility, notGrapOb)).isNotConsumed(); dustyKey.setTooltip("You can get this by killing the Jailer in the Black Knights Base in Taverley Dungeon and" + " using the key he drops to enter the jail cell there to talk to Velrak for the dusty key"); @@ -198,11 +201,12 @@ protected void setupRequirements() bowString = new ItemRequirement("Bow string", ItemID.BOW_STRING).showConditioned(notStringMaple); limpSeed = new ItemRequirement("Limpwurt seed", ItemID.LIMPWURT_SEED).showConditioned(notPickLimp); rake = new ItemRequirement("Rake", ItemID.RAKE).showConditioned(notPickLimp).isNotConsumed(); - seedDib = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(notPickLimp).isNotConsumed(); + var needSeedDibber = not(new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, 3)); + seedDib = new ItemRequirement("Seed dibber", ItemID.DIBBER).showConditioned(and(notPickLimp, needSeedDibber)).isNotConsumed(); primedMind = new ItemRequirement("Mind bar", ItemID.ELEM_MIND_BAR).showConditioned(notMindHelm); hammer = new ItemRequirement("Hammer", ItemID.HAMMER).showConditioned(notMindHelm).isNotConsumed(); beatenBook = new ItemRequirement("Beaten Book", ItemID.ELEMENTAL_WORKSHOP_HELM_BOOK).showConditioned(notMindHelm); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY).showConditioned(notMindHelm); + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY).showConditioned(notMindHelm); batteredKey.setTooltip("You can get another by searching the bookcase in the house south of the Elemental " + "Workshop, then reading the book you get from it"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java index 8dcecb3816..35c3f76957 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaElite.java @@ -206,18 +206,18 @@ public List getPanels() { List allSteps = new ArrayList<>(); - PanelDetails palmSteps = new PanelDetails("Check Palm Tree Health", Collections.singletonList(checkPalm), - new SkillRequirement(Skill.FARMING, 68, true), palmTreeSapling, rake, spade); - palmSteps.setDisplayCondition(notCheckedPalm); - palmSteps.setLockingStep(checkedPalmTask); - allSteps.add(palmSteps); - PanelDetails calquatSteps = new PanelDetails("Check Calquat Tree Health", Collections.singletonList(checkCalquat), farming72, calquatSapling, rake, spade); calquatSteps.setDisplayCondition(notCheckedCalquat); calquatSteps.setLockingStep(checkedCalquatTask); allSteps.add(calquatSteps); + PanelDetails palmSteps = new PanelDetails("Check Palm Tree Health", Collections.singletonList(checkPalm), + new SkillRequirement(Skill.FARMING, 68, true), palmTreeSapling, rake, spade); + palmSteps.setDisplayCondition(notCheckedPalm); + palmSteps.setLockingStep(checkedPalmTask); + allSteps.add(palmSteps); + PanelDetails equipCapeSteps = new PanelDetails("Equip Fire / Infernal Cape", Collections.singletonList(equipCape), fireCapeOrInfernal); equipCapeSteps.setDisplayCondition(notEquippedCape); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java index 5326e82b35..5885eef185 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/karamja/KaramjaMedium.java @@ -73,7 +73,7 @@ public class KaramjaMedium extends BasicQuestHelper Requirement grandTree, taiBwoWannaiTrio, dragonSlayerI, shiloVillage, junglePotion; - QuestStep enterAgilityArena, tag2Pillars, enterVolcano, returnThroughWall, useCart, doCleanup, makeSpiderStick, cookSpider, + QuestStep enterAgilityArena, tagPillar, enterVolcano, returnThroughWall, useCart, doCleanup, makeSpiderStick, cookSpider, climbUpToBoat, travelToKhazard, cutTeak, cutMahogany, catchKarambwanji, catchKarambwan, getMachete, flyToKaramja, growFruitTree, trapGraahk, chopVines, crossLava, climbBrimhavenStaircase, charterFromShipyard, mineRedTopaz, enterCrandor, enterBrimDungeonVine, enterBrimDungeonLava, enterBrimDungeonStairs, claimReward; @@ -108,7 +108,7 @@ public Map loadSteps() doMedium.addStep(notEnteredCrandor, enteredCrandorTask); claimedTicketTask = new ConditionalStep(this, enterAgilityArena); - claimedTicketTask.addStep(inAgilityArena, tag2Pillars); + claimedTicketTask.addStep(inAgilityArena, tagPillar); doMedium.addStep(notClaimedTicket, claimedTicketTask); usedCartTask = new ConditionalStep(this, useCart); @@ -269,7 +269,7 @@ public void setupSteps() enterAgilityArena = new ObjectStep(this, ObjectID.AGILITYARENA_LADDERDOWN, new WorldPoint(2809, 3194, 0), "Pay Cap'n Izzy" + " No Beard 200 coins and enter the Agility Arena in Brimhaven.", coins.quantity(200)); - tag2Pillars = new DetailedQuestStep(this, "Tag 2 marked pillars in a row."); + tagPillar = new DetailedQuestStep(this, "Tag a marked pillar."); enterVolcano = new ObjectStep(this, ObjectID.VOLCANO_ENTRANCE, new WorldPoint(2857, 3169, 0), "Enter the Karamja Volcano."); returnThroughWall = new ObjectStep(this, ObjectID.DRAGONSECRETDOOR, new WorldPoint(2836, 9600, 0), "Return back through the shortcut."); @@ -289,9 +289,12 @@ public void setupSteps() travelToKhazard.addSubSteps(climbUpToBoat); cutTeak = new ObjectStep(this, ObjectID.TEAKTREE, new WorldPoint(2822, 3078, 0), "Chop a teak tree down either in" + " the Hardwood Grove in Tai Bwo Wannai or in the Kharazi Jungle (requires Legends' Quest started).", axe, tradingSticks.quantity(100)); + ((ObjectStep) cutTeak).addAlternateObjects(ObjectID.TEAKTREE_UPDATE); + cutTeak.addDialogStep("Okay, I'll pay 100 trading sticks to enter."); cutMahogany = new ObjectStep(this, ObjectID.MAHOGANYTREE, new WorldPoint(2820, 3080, 0), "Chop a mahogany tree " + "down either in the Hardwood Grove in Tai Bwo Wannai or in the Kharazi Jungle (requires Legends' Quest started).", axe, tradingSticks.quantity(100)); + cutMahogany.addDialogStep("Okay, I'll pay 100 trading sticks to enter."); catchKarambwanji = new NpcStep(this, NpcID._0_43_47_KARAMBWANJI, new WorldPoint(2791,3019,0), "Using your small fishing net, catch some raw karambwanji just south of Tai Bwo Wannai, or buy some from the GE.", smallFishingNet); catchKarambwan = new NpcStep(this, NpcID._0_45_48_KARAMBWAN, new WorldPoint(2899, 3119, 0), @@ -413,7 +416,7 @@ public List getPanels() allSteps.add(enteredCrandorSteps); PanelDetails enterAgiSteps = new PanelDetails("Claim a ticket in The Agility Arena", - Arrays.asList(enterAgilityArena, tag2Pillars), coins.quantity(200)); + Arrays.asList(enterAgilityArena, tagPillar), coins.quantity(200)); enterAgiSteps.setDisplayCondition(notClaimedTicket); enterAgiSteps.setLockingStep(claimedTicketTask); allSteps.add(enterAgiSteps); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java index 53fed369b3..64669b1504 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendEasy.java @@ -43,7 +43,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java index 901115012d..2bc2bca010 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/kourend/KourendMedium.java @@ -256,7 +256,7 @@ public void onGameTick(GameTick event) public void setupSteps() { // Travel to Fairy Ring - travelFairyRing = new ObjectStep(this, ObjectID.POH_FAIRY_RING, new WorldPoint(2658, 3230, 0), + travelFairyRing = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, new WorldPoint(2658, 3230, 0), "Travel from any fairy ring to south of Mount Karuulm (CIR).", dramenStaff.highlighted()); // Kill a lizardman diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java index 5b15a57d47..6b380f2a13 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeEasy.java @@ -46,7 +46,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; @@ -289,7 +293,6 @@ public List getItemRecommended() public List getGeneralRequirements() { List reqs = new ArrayList<>(); - reqs.add(new SkillRequirement(Skill.AGILITY, 10, true)); reqs.add(new SkillRequirement(Skill.FIREMAKING, 15, true)); reqs.add(new SkillRequirement(Skill.FISHING, 15, true)); reqs.add(new SkillRequirement(Skill.MINING, 15, true)); @@ -332,8 +335,7 @@ public List getPanels() { List allSteps = new ArrayList<>(); - PanelDetails draynorRooftopsSteps = new PanelDetails("Draynor Rooftops", Collections.singletonList(drayAgi), - new SkillRequirement(Skill.AGILITY, 10, true)); + PanelDetails draynorRooftopsSteps = new PanelDetails("Draynor Rooftops", Collections.singletonList(drayAgi)); draynorRooftopsSteps.setDisplayCondition(notDrayAgi); draynorRooftopsSteps.setLockingStep(drayAgiTask); allSteps.add(draynorRooftopsSteps); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java index 20ddcfdeaf..6e50050029 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/lumbridgeanddraynor/LumbridgeElite.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java index 8936535a4c..ad2e31c184 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaEasy.java @@ -29,6 +29,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.ComplexRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; @@ -291,15 +292,16 @@ public List getGeneralRequirements() if (questHelperPlugin.getPlayerStateManager().getAccountType().isAnyIronman()) { - // 47 Farming is required to get a Watermelon for the scarecrow step - reqs.add(new SkillRequirement(Skill.FARMING, 47, true)); + // 47 Farming or completion of Troubled Tortugans is required to get a Watermelon for the scarecrow step + reqs.add(new ComplexRequirement(LogicType.OR, "47 Farming OR Finished Troubled Tortugans for a watermelon", + new QuestRequirement(QuestHelperQuest.TROUBLED_TORTUGANS, QuestState.FINISHED), + new SkillRequirement(Skill.FARMING, 47, true))); } else { reqs.add(new SkillRequirement(Skill.FARMING, 23, true)); } - reqs.add(ghostsAhoy); reqs.add(natureSpirit); return reqs; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java index 0645bf64be..c723aed03f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaElite.java @@ -48,7 +48,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java index 7e2fdc8a67..837d16db63 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/morytania/MorytaniaMedium.java @@ -172,7 +172,7 @@ protected void setupRequirements() steelBar = new ItemRequirement("Steel bar", ItemID.STEEL_BAR).showConditioned(notCannonBall); ammoMould = new ItemRequirement("Ammo mould", ItemID.AMMO_MOULD).showConditioned(notCannonBall).isNotConsumed(); ammoMould.addAlternates(ItemID.DOUBLE_AMMO_MOULD); - slayerGloves = new ItemRequirement("Slayer gloves", ItemID.SLAYERGUIDE_SLAYER_GLOVES).showConditioned(notFeverSpider).isNotConsumed(); + slayerGloves = new ItemRequirement("Slayer gloves", ItemID.DEAL_SLAYER_GLOVES).showConditioned(notFeverSpider).isNotConsumed(); ectophial = new ItemRequirement("Ectophial", ItemID.ECTOPHIAL).showConditioned(notEctophialTP).isNotConsumed(); restorePot = new ItemRequirement("Restore potion (4)", ItemID._4DOSESTATRESTORE).showConditioned(notGuthBalance); garlic = new ItemRequirement("Garlic", ItemID.GARLIC).showConditioned(notGuthBalance); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java index c7926e2955..fd66e8f4e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/varrock/VarrockMedium.java @@ -48,7 +48,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java index b87bae14cd..1dc7c98cb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/westernprovinces/WesternMedium.java @@ -55,6 +55,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; public class WesternMedium extends ComplexStateQuestHelper { @@ -136,8 +137,8 @@ public QuestStep loadStep() doMedium.addStep(notApeBass, apeBassTask); apeTeakTask = new ConditionalStep(this, moveToApeTeak); + apeTeakTask.addStep(and(inApeAtoll, teakLogs, choppedLogs), apeTeakBurn); apeTeakTask.addStep(inApeAtoll, apeTeakChop); - apeTeakTask.addStep(new Conditions(inApeAtoll, teakLogs, choppedLogs), apeTeakBurn); doMedium.addStep(notApeTeak, apeTeakTask); interPestTask = new ConditionalStep(this, moveToPest); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java index 13b83d76d8..2a139a97e8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/achievementdiaries/wilderness/WildernessEasy.java @@ -47,7 +47,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java index acdae9c6d6..7bac94818e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingConditionalStep.java @@ -36,7 +36,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; import net.runelite.api.Client; import net.runelite.api.coords.WorldPoint; - import java.util.Map; public class ChartingConditionalStep extends ReorderableConditionalStep diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java index 4677c3d31c..d8f70bd858 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingHelper.java @@ -24,22 +24,32 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; -import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.*; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingCaveTelescopeStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingCrateStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingCurrentStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingDivingStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingGenericObjectStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingPuzzleWrapStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingTaskStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingTelescopeStep; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.steps.ChartingWeatherStep; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.TopLevelPanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.questinfo.HelperConfig; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.StepIsActiveRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.plugins.microbot.questhelper.questinfo.HelperConfig; import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.gameval.VarbitID; - -import java.util.*; - +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; public class ChartingHelper extends ComplexStateQuestHelper diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java index f8a3c231ab..914c86de2e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingSeaSection.java @@ -25,7 +25,6 @@ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; import lombok.Getter; - import java.util.List; @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java index f9d1a59a7c..184d0d495c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTaskDefinition.java @@ -24,10 +24,9 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import lombok.Getter; import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; - import java.util.ArrayList; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java index 5d6779ea15..8797e96b5b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/ChartingTasksData.java @@ -24,13 +24,12 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.VarbitID; +import java.util.List; import net.runelite.client.plugins.microbot.questhelper.requirements.sailing.BoatResistanceType; import net.runelite.client.plugins.microbot.questhelper.requirements.sailing.HasBoatResistanceRequirement; - -import java.util.List; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.coords.WorldPoint; // All data generated from the OSRS Wiki (https://oldschool.runescape.wiki/w/Sea_charting) public final class ChartingTasksData @@ -369,7 +368,7 @@ private ChartingTasksData() )), new ChartingSeaSection(27, "Mythic Sea", List.of( new ChartingTaskDefinition(ChartingType.CRATE, "Find a Sealed crate west of the Void Knights' Outpost and sample the contents.", new WorldPoint(2556, 2664, 0), "Shrouded Ocean", 12, VarbitID.SAILING_CHARTING_DRINK_CRATE_MYTHS_MIXER_COMPLETE, ItemID.SAILING_CHARTING_DRINK_CRATE_MYTHS_MIXER), - new ChartingTaskDefinition(ChartingType.GENERIC, "Find an abandoned camp on Anglers' Retreat. Watch out for Fetid waters!", new WorldPoint(2476, 2707, 0), "Shrouded Ocean", 1, VarbitID.SAILING_CHARTING_GENERIC_ABANDONED_CAMP_COMPLETE), + new ChartingTaskDefinition(ChartingType.GENERIC, "Find an abandoned camp on Anglers' Retreat. Watch out for Fetid waters!", new WorldPoint(2476, 2707, 0), "Shrouded Ocean", 51, VarbitID.SAILING_CHARTING_GENERIC_ABANDONED_CAMP_COMPLETE), new ChartingTaskDefinition(ChartingType.CURRENT, "Test the currents east of Anglers' Retreat. Watch out for Fetid waters!", new WorldPoint(2495, 2708, 0), new WorldPoint(2533, 2736, 0), "Shrouded Ocean", 40, VarbitID.SAILING_CHARTING_CURRENT_DUCK_MYTHIC_SEA_COMPLETE), new ChartingTaskDefinition(ChartingType.DIVING, "With help from a mermaid guide, document the water depth south of the Myths' Guild. Watch out for Fetid waters!", new WorldPoint(2446, 2784, 0), "Shrouded Ocean", 40, VarbitID.SAILING_CHARTING_MERMAID_GUIDE_MYTHIC_SEA_COMPLETE, "The answer is 'Cabbage', 'Onion', 'Tomato'.", List.of(ItemID.CABBAGE, ItemID.ONION, ItemID.TOMATO)) )), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java index 2f66459c73..bed74d3936 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCaveTelescopeStep.java @@ -33,12 +33,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import lombok.Getter; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ObjectID; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java index 2acbeaf141..a5c4aad951 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCrateStep.java @@ -32,8 +32,9 @@ import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class ChartingCrateStep extends ChartingTaskObjectStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java index d5d56dda2b..922868da90 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingCurrentStep.java @@ -28,13 +28,15 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class ChartingCurrentStep extends ChartingTaskObjectStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java index 1ba16f7b9f..b545e6665d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingGenericObjectStep.java @@ -27,8 +27,11 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.ChartingTaskDefinition; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.api.GameObject; import net.runelite.api.TileObject; +import net.runelite.api.gameval.ItemID; +import java.util.List; // This is a lazy implementation where we fully trust the location of the object to only have one thing to work public class ChartingGenericObjectStep extends ChartingTaskObjectStep diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java index 98acdc3aa0..6cc8bde879 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingPuzzleWrapStep.java @@ -33,7 +33,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; public class ChartingPuzzleWrapStep extends PuzzleWrapperStep implements ChartingTaskInterface diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java index 0bf8cd55f7..947902f699 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskNpcStep.java @@ -33,9 +33,9 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import lombok.Getter; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; @Getter public class ChartingTaskNpcStep extends NpcStep implements ChartingTaskInterface diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java index 8af4bd4a3a..33bbbd5477 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskObjectStep.java @@ -33,7 +33,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import lombok.Getter; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java index 03e2b5bf21..ed442ca034 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingTaskStep.java @@ -33,7 +33,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import lombok.Getter; import net.runelite.api.Skill; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java index c8e77aa44c..7e977883af 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/activities/charting/steps/ChartingWeatherStep.java @@ -33,6 +33,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import lombok.Getter; import net.runelite.api.Skill; import net.runelite.api.gameval.ItemID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java index 61100712b4..cf2ee0242f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/alfredgrimhandsbarcrawl/AlfredGrimhandsBarcrawl.java @@ -24,13 +24,11 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.alfredgrimhandsbarcrawl; - import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,59 +38,74 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarPlayerID; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - public class AlfredGrimhandsBarcrawl extends ComplexStateQuestHelper { - //Items Required - ItemRequirement coins208, coins50, coins10, coins70, coins8, coins7, coins15, coins18, coins12, barcrawlCard; - - //Items Recommended - ItemRequirement gamesNecklace, varrockTeleport, faladorTeleport, glory, ardougneTeleport, camelotTeleport, - duelingRing; - - Requirement notTalkedToGuard, notTalkedToBlueMoon, notTalkedToJollyBoar, notTalkedToRisingSun, - notTalkedToRustyAnchor, - notTalkedToZambo, notTalkedToDeadMansChest, notTalkedToFlyingHorseInn, notTalkedToForestersArms, notTalkedToBlurberry, - notTalkedToDragonInn, inGrandTreeF1; - - QuestStep talkToGuardToGetCard, talkToBlueMoon, talkToJollyBoar, talkToRisingSun, talkToRustyAnchor, talkToZambo, - talkToDeadMansChest, talkToFlyingHorseInn, talkToForestersArms, goUpToBlurberry, talkToBlurberry, - talkToDragonInn, talkToGuardAgain; - - //Zones + // Required items + ItemRequirement coins208; + + // Recommended items + ItemRequirement gamesNecklace; + ItemRequirement varrockTeleport; + ItemRequirement lumberyardTeleport; + ItemRequirement faladorTeleport; + ItemRequirement glory; + ItemRequirement ardougneTeleport; + ItemRequirement camelotTeleport; + ItemRequirement duelingRing; + + // Mid-quest item requirements + ItemRequirement coins50; + ItemRequirement coins10; + ItemRequirement coins70; + ItemRequirement coins8; + ItemRequirement coins7; + ItemRequirement coins15; + ItemRequirement coins18; + ItemRequirement coins12; + ItemRequirement barcrawlCard; + + // Zones Zone grandTreeF1; - @Override - public QuestStep loadStep() - { - initializeRequirements(); - setupZones(); - setupConditions(); - setupSteps(); + // Miscellaneous requirements + VarplayerRequirement notTalkedToGuard; + VarplayerRequirement notTalkedToBlueMoon; + VarplayerRequirement notTalkedToJollyBoar; + VarplayerRequirement notTalkedToRisingSun; + VarplayerRequirement notTalkedToRustyAnchor; + VarplayerRequirement notTalkedToZambo; + VarplayerRequirement notTalkedToDeadMansChest; + VarplayerRequirement notTalkedToFlyingHorseInn; + VarplayerRequirement notTalkedToForestersArms; + VarplayerRequirement notTalkedToBlurberry; + VarplayerRequirement notTalkedToDragonInn; + ZoneRequirement inGrandTreeF1; + + // Steps + NpcStep talkToGuardToGetCard; + NpcStep talkToBlueMoon; + NpcStep talkToJollyBoar; + NpcStep talkToRisingSun; + NpcStep talkToRustyAnchor; + NpcStep talkToZambo; + NpcStep talkToDeadMansChest; + NpcStep talkToFlyingHorseInn; + NpcStep talkToForestersArms; + ObjectStep goUpToBlurberry; + NpcStep talkToBlurberry; + NpcStep talkToDragonInn; + NpcStep talkToGuardAgain; - ConditionalStep barcrawl = new ConditionalStep(this, talkToGuardAgain); - barcrawl.addStep(notTalkedToGuard, talkToGuardToGetCard); - barcrawl.addStep(notTalkedToBlueMoon, talkToBlueMoon); - barcrawl.addStep(notTalkedToJollyBoar, talkToJollyBoar); - barcrawl.addStep(notTalkedToRisingSun, talkToRisingSun); - barcrawl.addStep(notTalkedToRustyAnchor, talkToRustyAnchor); - barcrawl.addStep(notTalkedToZambo, talkToZambo); - barcrawl.addStep(notTalkedToDeadMansChest, talkToDeadMansChest); - barcrawl.addStep(notTalkedToFlyingHorseInn, talkToFlyingHorseInn); - barcrawl.addStep(notTalkedToForestersArms, talkToForestersArms); - barcrawl.addStep(new Conditions(notTalkedToBlurberry, inGrandTreeF1), talkToBlurberry); - barcrawl.addStep(notTalkedToBlurberry, goUpToBlurberry); - barcrawl.addStep(notTalkedToDragonInn, talkToDragonInn); - - return barcrawl; + public void setupZones() + { + grandTreeF1 = new Zone(new WorldPoint(2437, 3474, 1), new WorldPoint(2493, 3511, 1)); } @Override @@ -110,6 +123,8 @@ protected void setupRequirements() gamesNecklace = new ItemRequirement("Games necklace", ItemCollections.GAMES_NECKLACES); varrockTeleport = new ItemRequirement("Varrock teleport", ItemID.POH_TABLET_VARROCKTELEPORT); + lumberyardTeleport = new ItemRequirement("Lumberyard teleport", ItemID.TELEPORTSCROLL_LUMBERYARD); + lumberyardTeleport.addAlternates(ItemID.RING_OF_ELEMENTS_CHARGED); faladorTeleport = new ItemRequirement("Falador teleport", ItemID.POH_TABLET_FALADORTELEPORT); glory = new ItemRequirement("Amulet of Glory", ItemCollections.AMULET_OF_GLORIES).isNotConsumed(); ardougneTeleport = new ItemRequirement("Ardougne teleport", ItemID.POH_TABLET_ARDOUGNETELEPORT); @@ -118,15 +133,6 @@ protected void setupRequirements() barcrawlCard = new ItemRequirement("Barcrawl card", ItemID.BARCRAWL_CARD); barcrawlCard.setTooltip("If you've lost it you can get another from the Barbarian Guard"); - } - - public void setupZones() - { - grandTreeF1 = new Zone(new WorldPoint(2437, 3474, 1), new WorldPoint(2493, 3511, 1)); - } - - public void setupConditions() - { inGrandTreeF1 = new ZoneRequirement(grandTreeF1); notTalkedToGuard = new VarplayerRequirement(VarPlayerID.BARCRAWL, false, 0); @@ -144,65 +150,89 @@ public void setupConditions() public void setupSteps() { - talkToGuardToGetCard = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), - "Talk to a barbarian guard outside the Barbarian Agility Course."); - talkToGuardToGetCard.addDialogSteps("I want to come through this gate.", - "Looks can be deceiving, I am in fact a barbarian."); - + talkToGuardToGetCard = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), "Talk to a barbarian guard outside the Barbarian Agility Course at the Barbarian Outpost to learn about Alfred Grimhand's Barcrawl."); + talkToGuardToGetCard.addDialogSteps("I want to come through this gate.", "Looks can be deceiving, I am in fact a barbarian."); - talkToBlueMoon = new NpcStep(this, NpcID.BLUEMOON_BARTENDER, new WorldPoint(3226, 3399, 0), - "Talk to the bartender in the Blue Moon Inn in Varrock.", coins50); + talkToBlueMoon = new NpcStep(this, NpcID.BLUEMOON_BARTENDER, new WorldPoint(3226, 3399, 0), "Talk to the bartender in the Blue Moon Inn in Varrock.", coins50); talkToBlueMoon.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToJollyBoar = new NpcStep(this, NpcID.JOLLYBOAR_BARTENDER, new WorldPoint(3279, 3488, 0), - "Talk to the bartender in the Jolly Boar Inn north east of Varrock.", coins10); + talkToJollyBoar = new NpcStep(this, NpcID.JOLLYBOAR_BARTENDER, new WorldPoint(3279, 3488, 0), "Talk to the bartender in the Jolly Boar Inn north east of Varrock.", coins10); + talkToJollyBoar.addTeleport(lumberyardTeleport); talkToJollyBoar.addDialogStep("I'm doing Alfred Grimhands Barcrawl."); - talkToRisingSun = new NpcStep(this, NpcID.RISINGSUN_BARMAID2, new WorldPoint(2956, 3370, 0), - "Talk to a bartender in the Rising Sun Inn in Falador.", true, coins70); + talkToRisingSun = new NpcStep(this, NpcID.RISINGSUN_BARMAID2, new WorldPoint(2956, 3370, 0), "Talk to a bartender in the Rising Sun Inn in Falador.", true, coins70); talkToRisingSun.addDialogStep("I'm doing Alfred Grimhand's barcrawl."); - ((NpcStep) talkToRisingSun).addAlternateNpcs(NpcID.RISINGSUN_BARMAID, NpcID.RISINGSUN_BARMAID3); + talkToRisingSun.addAlternateNpcs(NpcID.RISINGSUN_BARMAID, NpcID.RISINGSUN_BARMAID3); - talkToRustyAnchor = new NpcStep(this, NpcID.RUSTYANCHOR_BARTENDER, new WorldPoint(3046, 3257, 0), - "Talk to the bartender in the Rusty Anchor in Port Sarim.", coins8); + talkToRustyAnchor = new NpcStep(this, NpcID.RUSTYANCHOR_BARTENDER, new WorldPoint(3046, 3257, 0), "Talk to the bartender in the Rusty Anchor in Port Sarim.", coins8); talkToRustyAnchor.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToZambo = new NpcStep(this, NpcID.ZEMBO, new WorldPoint(2927, 3144, 0), - "Talk to Zembo in the Karamja Spirits Bar on Musa Point.", coins7); + + talkToZambo = new NpcStep(this, NpcID.ZEMBO, new WorldPoint(2927, 3144, 0), "Talk to Zembo in the Karamja Spirits Bar on Musa Point.", coins7); talkToZambo.addDialogStep("I'm doing Alfred Grimhand's barcrawl."); - talkToDeadMansChest = new NpcStep(this, NpcID.DEADMANS_BARTENDER, new WorldPoint(2796, 3156, 0), - "Talk to the bartender in the Dead Man's Chest in Brimhaven.", coins15); + + talkToDeadMansChest = new NpcStep(this, NpcID.DEADMANS_BARTENDER, new WorldPoint(2796, 3156, 0), "Talk to the bartender in the Dead Man's Chest in Brimhaven.", coins15); talkToDeadMansChest.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToFlyingHorseInn = new NpcStep(this, NpcID.FLYINGHORSE_BARTENDER, new WorldPoint(2574, 3323, 0), - "Talk to the bartender in the Flying Horse Inn in Ardougne.", coins8); + + talkToFlyingHorseInn = new NpcStep(this, NpcID.FLYINGHORSE_BARTENDER, new WorldPoint(2574, 3323, 0), "Talk to the bartender in the Flying Horse Inn in Ardougne.", coins8); talkToFlyingHorseInn.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToForestersArms = new NpcStep(this, NpcID.FORESTERS_BARTENDER, new WorldPoint(2690, 3494, 0), - "Talk to the bartender in the Forester's Arms in Seers' Village.", coins18); + + talkToForestersArms = new NpcStep(this, NpcID.FORESTERS_BARTENDER, new WorldPoint(2690, 3494, 0), "Talk to the bartender in the Forester's Arms in Seers' Village.", coins18); talkToForestersArms.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - goUpToBlurberry = new ObjectStep(this, QHObjectID.GRAND_TREE_F0_LADDER, new WorldPoint(2466, 3495, 0), - "Talk to Blurberry in the Grand Tree.", coins10); - talkToBlurberry = new NpcStep(this, NpcID.BLURBERRY, new WorldPoint(2482, 3491, 1), - "Talk to Blurberry in the Grand Tree.", coins10); + goUpToBlurberry = new ObjectStep(this, QHObjectID.GRAND_TREE_F0_LADDER, new WorldPoint(2466, 3495, 0), "Talk to Blurberry in the Grand Tree.", coins10); + talkToBlurberry = new NpcStep(this, NpcID.BLURBERRY, new WorldPoint(2482, 3491, 1), "Talk to Blurberry in the Grand Tree.", coins10); talkToBlurberry.addSubSteps(goUpToBlurberry); - talkToDragonInn = new NpcStep(this, NpcID.DRAGON_BARTENDER, new WorldPoint(2556, 3079, 0), - "Talk to the bartender in Dragon Inn in Yanille.", coins12); + + talkToDragonInn = new NpcStep(this, NpcID.DRAGON_BARTENDER, new WorldPoint(2556, 3079, 0), "Talk to the bartender in Dragon Inn in Yanille.", coins12); talkToDragonInn.addDialogStep("I'm doing Alfred Grimhand's Barcrawl."); - talkToGuardAgain = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), - "Return to the barbarian guards outside the Barbarian Agility Course."); + talkToGuardAgain = new NpcStep(this, NpcID.BARBGUARD1_PRECRAWL, new WorldPoint(2544, 3568, 0), "Return to the barbarian guards outside the Barbarian Agility Course."); + } + + @Override + public QuestStep loadStep() + { + initializeRequirements(); + setupSteps(); + + var barcrawl = new ConditionalStep(this, talkToGuardAgain); + barcrawl.addStep(notTalkedToGuard, talkToGuardToGetCard); + barcrawl.addStep(notTalkedToBlueMoon, talkToBlueMoon); + barcrawl.addStep(notTalkedToJollyBoar, talkToJollyBoar); + barcrawl.addStep(notTalkedToRisingSun, talkToRisingSun); + barcrawl.addStep(notTalkedToRustyAnchor, talkToRustyAnchor); + barcrawl.addStep(notTalkedToZambo, talkToZambo); + barcrawl.addStep(notTalkedToDeadMansChest, talkToDeadMansChest); + barcrawl.addStep(notTalkedToFlyingHorseInn, talkToFlyingHorseInn); + barcrawl.addStep(notTalkedToForestersArms, talkToForestersArms); + barcrawl.addStep(and(notTalkedToBlurberry, inGrandTreeF1), talkToBlurberry); + barcrawl.addStep(notTalkedToBlurberry, goUpToBlurberry); + barcrawl.addStep(notTalkedToDragonInn, talkToDragonInn); + + return barcrawl; } @Override public List getItemRequirements() { - return List.of(coins208); + return List.of( + coins208 + ); } @Override public List getItemRecommended() { - return List.of(gamesNecklace, varrockTeleport, faladorTeleport, glory, ardougneTeleport, - camelotTeleport, duelingRing); + return List.of( + gamesNecklace, + varrockTeleport, + lumberyardTeleport, + faladorTeleport, + glory, + ardougneTeleport, + camelotTeleport, + duelingRing + ); } @Override @@ -217,14 +247,29 @@ public List getUnlockRewards() @Override public ArrayList getPanels() { - var allSteps = new ArrayList(); - - allSteps.add(new PanelDetails("Getting started", List.of(talkToGuardToGetCard))); - - allSteps.add(new PanelDetails("Drinking", Arrays.asList(talkToBlueMoon, talkToJollyBoar, talkToRisingSun, - talkToRustyAnchor, talkToZambo, talkToDeadMansChest, talkToFlyingHorseInn, talkToForestersArms, talkToBlurberry, - talkToDragonInn, talkToGuardAgain), barcrawlCard, coins208)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Getting started", List.of( + talkToGuardToGetCard + ))); + + sections.add(new PanelDetails("Drinking", List.of( + talkToBlueMoon, + talkToJollyBoar, + talkToRisingSun, + talkToRustyAnchor, + talkToZambo, + talkToDeadMansChest, + talkToFlyingHorseInn, + talkToForestersArms, + talkToBlurberry, + talkToDragonInn, + talkToGuardAgain + ), List.of( + barcrawlCard, + coins208 + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java index 0179424eb5..e41e977228 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/barbariantraining/BarbarianTraining.java @@ -26,33 +26,26 @@ import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.config.ConfigKeys; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import net.runelite.client.plugins.microbot.questhelper.requirements.ChatMessageRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.MesBoxRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.MultiChatMessageRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -61,49 +54,143 @@ public class BarbarianTraining extends BasicQuestHelper { // Items Required - ItemRequirement barbFishingRod, tinderbox, bow, knife, fish, combatGear, antifireShield, chewedBones, bronzeBar, logs, hammer, - roe, attackPotion, sapling, seed, spade, oakLogs, axe, feathers, barbarianAttackPotion; + ItemRequirement barbFishingRod; + ItemRequirement tinderbox; + ItemRequirement bow; + ItemRequirement knife; + ItemRequirement fish; + ItemRequirement combatGear; + ItemRequirement antifireShield; + ItemRequirement chewedBones; + ItemRequirement bronzeBar; + ItemRequirement logs; + ItemRequirement hammer; + ItemRequirement roe; + ItemRequirement attackPotion; + ItemRequirement sapling; + ItemRequirement seed; + ItemRequirement spade; + ItemRequirement oakLogs; + ItemRequirement axe; + ItemRequirement feathers; + ItemRequirement barbarianAttackPotion; // Items recommended - ItemRequirement gamesNecklace, catherbyTeleport; - - Requirement fishing48, agility15, strength15, fishing55, strength35, firemaking35, crafting11, farming15, smithing5; - - QuestRequirement druidicRitual, taiBwoWannaiTrio; - - Requirement taskedWithFishing, taskedWithHarpooning, taskedWithFarming, taskedWithBowFiremaking, taskedWithPyre, taskedWithPotSmashing, - taskedWithSpears, taskedWithHastae, taskedWithHerblore; + ItemRequirement gamesNecklace; + ItemRequirement catherbyTeleport; + + Requirement fishing48; + Requirement agility15; + Requirement strength15; + Requirement fishing55; + Requirement strength35; + Requirement firemaking35; + Requirement crafting11; + Requirement farming15; + Requirement smithing5; + + QuestRequirement druidicRitual; + QuestRequirement taiBwoWannaiTrio; Requirement chewedBonesNearby; - Requirement plantedSeed, smashedPot, litFireWithBow, sacrificedRemains, caughtBarbarianFish, - caughtFishWithoutHarpoon, madePotion, madeSpear, madeHasta; - - DetailedQuestStep talkToOttoAboutFishing, searchBed, catchFish, talkToOttoAfterFish; - - DetailedQuestStep talkToOttoAboutBarehanded, fishHarpoon, talkToOttoAfterHarpoon; - - DetailedQuestStep talkToOttoAboutBow, lightLogWithBow, talkToOttoAfterBow; - - DetailedQuestStep talkToOttoAboutPyre, enterWhirlpool, goDownToBrutalGreen, goUpToMithrilDragons, killMithrilDragons, - pickupChewedBones, useLogOnPyre, talkToOttoAfterPyre; - - DetailedQuestStep talkToOttoAboutFarming, plantSeed, talkToOttoAfterPlantingSeed; - - DetailedQuestStep talkToOttoAboutPots, plantSapling, talkToOttoAfterSmashingPot; - - DetailedQuestStep talkToOttoAboutSpears, makeBronzeSpear, talkToOttoAfterBronzeSpear, talkToOttoAboutHastae, makeBronzeHasta, talkToOttoAfterMakingHasta; - - DetailedQuestStep talkToOttoAboutHerblore, getBarbRodForHerblore, fishForHerblore, dissectFish, useRoeOnAttackPotion, talkToOttoAfterPotion; - - ConditionalStep fishingSteps, harpoonSteps, seedSteps, potSmashingSteps, firemakingSteps, pyreSteps, spearSteps, - spearAndHastaeSteps, herbloreSteps; - - Requirement finishedFishing, finishedHarpoon, finishedSeedPlanting, finishedPotSmashing, finishedFiremaking, finishedPyre, finishedSpear, finishedHasta, finishedHerblore; - - Zone ancientCavernF0, ancientCavernF1, ancientCavernArrivalRoom; - - ZoneRequirement inAncientCavernF0, inAncientCavernF1, inAncientCavernArrivalRoom; + DetailedQuestStep talkToOttoAboutFishing; + DetailedQuestStep searchBed; + DetailedQuestStep catchFish; + DetailedQuestStep talkToOttoAfterFish; + + DetailedQuestStep talkToOttoAboutBarehanded; + DetailedQuestStep fishHarpoon; + DetailedQuestStep talkToOttoAfterHarpoon; + + DetailedQuestStep talkToOttoAboutBow; + DetailedQuestStep lightLogWithBow; + DetailedQuestStep talkToOttoAfterBow; + + DetailedQuestStep talkToOttoAboutPyre; + DetailedQuestStep enterWhirlpool; + DetailedQuestStep goDownToBrutalGreen; + DetailedQuestStep goUpToMithrilDragons; + DetailedQuestStep killMithrilDragons; + DetailedQuestStep pickupChewedBones; + DetailedQuestStep useLogOnPyre; + DetailedQuestStep talkToOttoAfterPyre; + + DetailedQuestStep talkToOttoAboutFarming; + DetailedQuestStep plantSeed; + DetailedQuestStep talkToOttoAfterPlantingSeed; + + DetailedQuestStep talkToOttoAboutPots; + DetailedQuestStep plantSapling; + DetailedQuestStep talkToOttoAfterSmashingPot; + + DetailedQuestStep talkToOttoAboutSpears; + DetailedQuestStep makeBronzeSpear; + DetailedQuestStep talkToOttoAfterBronzeSpear; + DetailedQuestStep talkToOttoAboutHastae; + DetailedQuestStep makeBronzeHasta; + DetailedQuestStep talkToOttoAfterMakingHasta; + + DetailedQuestStep talkToOttoAboutHerblore; + DetailedQuestStep getBarbRodForHerblore; + DetailedQuestStep fishForHerblore; + DetailedQuestStep dissectFish; + DetailedQuestStep useRoeOnAttackPotion; + DetailedQuestStep talkToOttoAfterPotion; + + ConditionalStep fishingSteps; + ConditionalStep harpoonSteps; + ConditionalStep seedSteps; + ConditionalStep potSmashingSteps; + ConditionalStep firemakingSteps; + ConditionalStep pyreSteps; + ConditionalStep spearSteps; + ConditionalStep spearAndHastaeSteps; + ConditionalStep herbloreSteps; + + Zone ancientCavernF0; + Zone ancientCavernF1; + Zone ancientCavernArrivalRoom; + + ZoneRequirement inAncientCavernF0; + ZoneRequirement inAncientCavernF1; + ZoneRequirement inAncientCavernArrivalRoom; + + VarbitRequirement taskedWithFishing; + VarbitRequirement caughtBarbarianFish; + VarbitRequirement finishedFishing; + + VarbitRequirement taskedWithHerblore; + VarbitRequirement madePotion; + VarbitRequirement finishedHerblore; + + VarbitRequirement taskedWithHarpooning; + VarbitRequirement caughtFishWithoutHarpoon; + VarbitRequirement finishedHarpoon; + + VarbitRequirement taskedWithFarming; + VarbitRequirement plantedSeed; + VarbitRequirement finishedSeedPlanting; + + VarbitRequirement taskedWithPotSmashing; + VarbitRequirement smashedPot; + VarbitRequirement finishedPotSmashing; + + VarbitRequirement taskedWithBowFiremaking; + VarbitRequirement litFireWithBow; + VarbitRequirement finishedFiremaking; + + VarbitRequirement taskedWithSpears; + VarbitRequirement madeSpear; + VarbitRequirement finishedSpear; + + VarbitRequirement taskedWithHastae; + VarbitRequirement madeHasta; + VarbitRequirement finishedHasta; + + VarbitRequirement taskedWithPyre; + VarbitRequirement sacrificedRemains; + VarbitRequirement finishedPyre; @Override public Map loadSteps() @@ -189,13 +276,10 @@ public Map loadSteps() allSteps.addDialogSteps("Let's talk about my training.", "I seek more knowledge."); allSteps.setCheckAllChildStepsOnListenerCall(true); - - // Started, 9613 + // Controlled by VarbitID.BRUT_MINIQUEST, specifying the number of miniquests completed steps.put(0, allSteps); steps.put(1, allSteps); - // Increments after doing a task steps.put(2, allSteps); - // 9610, 0->1 at some point??? Probably for pot smashing, or for whirlpool? steps.put(3, allSteps); steps.put(4, allSteps); steps.put(5, allSteps); @@ -259,281 +343,64 @@ public void setupRequirements() crafting11 = new SkillRequirement(Skill.CRAFTING, 11); farming15 = new SkillRequirement(Skill.FARMING, 15, true); smithing5 = new SkillRequirement(Skill.SMITHING, 5, true); + + var barbFishing = new VarbitBuilder(VarbitID.BRUT_FISHING_R); + taskedWithFishing = barbFishing.eq(1); + caughtBarbarianFish = barbFishing.eq(2); + finishedFishing = barbFishing.eq(3); + finishedFishing.setDisplayText("Finished Barbarian Fishing"); + + var barbHerblore = new VarbitBuilder(VarbitID.BRUT_HERB_POTION); + taskedWithHerblore = barbHerblore.eq(1); + madePotion = barbHerblore.eq(2); + finishedHerblore = barbHerblore.eq(3); + finishedHerblore.setDisplayText("Finished Barbarian Herblore"); + + var barbHarpooning = new VarbitBuilder(VarbitID.BRUT_FISHING_S); + taskedWithHarpooning = barbHarpooning.eq(1); + caughtFishWithoutHarpoon = barbHarpooning.eq(2); + finishedHarpoon = barbHarpooning.eq(3); + finishedHarpoon.setDisplayText("Finished Barbarian Harpooning"); + + var barbPlanting = new VarbitBuilder(VarbitID.BRUT_FARMING_PLANTING); + taskedWithFarming = barbPlanting.eq(1); + plantedSeed = barbPlanting.eq(2); + finishedSeedPlanting = barbPlanting.eq(3); + finishedSeedPlanting.setDisplayText("Finished Barbarian Planting"); + + var barbPotSmashing = new VarbitBuilder(VarbitID.BRUT_FARMING_SMASHING); + taskedWithPotSmashing = barbPotSmashing.eq(1); + smashedPot = barbPotSmashing.eq(2); + finishedPotSmashing = barbPotSmashing.eq(3); + finishedPotSmashing.setDisplayText("Finished Barbarian Pot Smashing"); + + var barbFiremaking = new VarbitBuilder(VarbitID.BRUT_FIRE); + taskedWithBowFiremaking = barbFiremaking.eq(1); + litFireWithBow = barbFiremaking.eq(2); + finishedFiremaking = barbFiremaking.eq(3); + finishedFiremaking.setDisplayText("Finished Barbarian Firemaking"); + + var barbSpear = new VarbitBuilder(VarbitID.BRUT_SMITH_SPEAR); + taskedWithSpears = barbSpear.eq(1); + madeSpear = barbSpear.eq(2); + finishedSpear = barbSpear.eq(3); + finishedSpear.setDisplayText("Finished Barbarian Spear Smithing"); + + var barbHasta = new VarbitBuilder(VarbitID.BRUT_SMITH_HASTA); + taskedWithHastae = barbHasta.eq(1); + madeHasta = barbHasta.eq(2); + finishedHasta = barbHasta.eq(3); + finishedHasta.setDisplayText("Finished Barbarian Hastae Smithing"); + + var barbPyre = new VarbitBuilder(VarbitID.BRUT_CRAFT_SHIP); + taskedWithPyre = barbPyre.eq(1); + sacrificedRemains = barbPyre.eq(2); + finishedPyre = barbPyre.eq(3); + finishedPyre.setDisplayText("Finished Barbarian Pyremaking"); } public void setupConditions() { - // Started tasks - - taskedWithFishing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Certainly. Take the rod from under my bed and fish in the lake. When you have caught a few fish, I am sure you will be ready to talk more with me."), - new DialogRequirement("Alas, I do not sense that you have been successful in your fishing yet. The look in your eyes is not that of the osprey."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with a new") - ) - ); - - taskedWithHarpooning = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("... and I thought fishing was a safe way to pass the time."), - new DialogRequirement("I see you need encouragement in learning the ways of fishing without a harpoon."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with my") - ) - ); - - taskedWithFarming = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Remember to be calm, and good luck."), - new DialogRequirement("I see you have yet to be successful in planting a seed with your fists."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "plant a seed with") - ) - ); - - taskedWithPotSmashing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("May the spirits guide you into success."), - new DialogRequirement("You have not yet attempted to plant a tree. Why not?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smash pots after") - ) - ); - - taskedWithBowFiremaking = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The spirits will aid you. The power they supply will guide your hands. Go and benefit from their guidance upon oak logs."), - new DialogRequirement("By now you know my response."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "light a fire with") - ) - ); - - taskedWithPyre = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Dive into the whirlpool in the lake to the east. The spirits will use their abilities to ensure you arrive in the correct location. Be warned, their influence fades, so you must find y"), - new DialogRequirement("I will repeat myself fully, since this is quite complex. Listen well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to create pyre ships") - ) - ); - - taskedWithHerblore = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Have I become so predictable? But yes, I do indeed require a potion. It is of the highest importance that you bring me a lesser attack potion combined with fish roe."), - new DialogRequirement("Do you have my potion?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to make a new type") - ) - ); - - taskedWithSpears = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Note well that you will require wood for the spear shafts. The quality of wood must be similar to that of the metal involved."), - new DialogRequirement("You do not exude the presence of one who has poured his soul into manufacturing spears."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smith spears") - ) - ); - - taskedWithHastae = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_STARTED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Indeed. You may use our special anvil for this spear type too. The ways of black and dragon hastae are beyond our knowledge, however."), - new DialogRequirement("Take some wood and metal and make a spear upon the
nearby anvil, then you may return to me. As an
example, you may use bronze bars with normal logs or
iron bars with oak logs."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, " has tasked me with learning how to smith a hasta") - ) - ); - - // Finished tasks - finishedFishing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Patience young one. These are fish which are fat with eggs rather than fat of flesh. It is these eggs that are the thing to make use of."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to catch a fish with the new rod!") - ), - "Finished Barbarian Fishing" - ); - - finishedHarpoon = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I mean that when you eventually die and find peace, at least the spirits you encounter will be your friends. Alas for you adventurous sort, the natural ways of passing are close to imp"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to fish with my hands!") - ), - "Finished Barbarian Harpooning" - ); - - finishedSeedPlanting = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("No child, but we all have potential to improve our strength."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to plant a seed with my fists!") - ), - "Finished Barbarian Seed Planting" - ); - - finishedPotSmashing = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("It will become more natural with practice."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smash a plant pot without littering!") - ), - "Finished Barbarian Pot Smashing" - ); - - finishedFiremaking = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Fine news indeed!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to light a fire with a bow!") - ), - "Finished Barbarian Firemaking" - ); - - finishedPyre = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("On this great day you have my eternal thanks. May you find riches while rescuing my spiritual ancestors in the caverns for many moons to come."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a pyre ship!") - ), - "Finished Barbarian Pyremaking" - ); - - finishedSpear = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The manufacture of spears is now yours as a speciality. Use your skill well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smith a spear!") - ), - "Finished Barbarian Spear Smithing" - ); - - finishedHasta = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("To live life to it's fullest of course - that you may be a peaceful spirit when your time ends."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a hasta!") - ), - "Finished Barbarian Hasta Smithing" - ); - - finishedHerblore = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_FINISHED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I will take that off your hands now. I will say no more than that I am eternally grateful."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a new potion!") - ), - "Finished Barbarian Herblore" - ); - - // Mid-conditions - plantedSeed = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_PLANTED_SEED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to plant a seed with my fists!") - ) - ); - - smashedPot = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_SMASHED_POT.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement(" sapling"), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smash a pot without littering!") - ) - ); - - litFireWithBow = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_BOW_FIRE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The fire catches and the logs begin to burn."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to light a fire with a bow!") - ) - ); - - sacrificedRemains = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_PYRE_MADE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The ancient barbarian is laid to rest."), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to create a pyre ship! I should let") - ) - ); - - caughtBarbarianFish = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_BARBFISHED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a leaping trout.", "You catch a leaping salmon.", "You catch a leaping sturgeon."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to catch a fish with the new rod! I should let") - ) - ); - - caughtFishWithoutHarpoon = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_HARPOONED_FISH.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a raw tuna.", "You catch a swordfish.", "You catch a shark.", "You catch a shark!"), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to fish with my hands! I should let Otto know") - ) - ); - - madePotion = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_MADE_POTION.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You combine your potion with the fish eggs."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to make a new type of potion! I should let") - ) - ); - - madeSpear = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_MADE_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" spear."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a spear!") - ) - ); - - madeHasta = new RuneliteRequirement( - getConfigManager(), ConfigKeys.BARBARIAN_TRAINING_MADE_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" hasta."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a hasta!") - ) - ); - - // For harpooning, - // You catch a tuna. - ancientCavernArrivalRoom = new Zone(new WorldPoint(1762, 5364, 1), new WorldPoint(1769, 5359, 1)); ancientCavernF0 = new Zone(new WorldPoint(1734, 5318, 0), new WorldPoint(1800, 5400, 0)); ancientCavernF1 = new Zone(new WorldPoint(1734, 5318, 1), new WorldPoint(1800, 5400, 1)); @@ -593,9 +460,9 @@ public void setupSteps() pickupChewedBones = new ItemStep(this, "Pick up the chewed bones.", chewedBones); useLogOnPyre = new ObjectStep(this, ObjectID.BRUT_BURNED_GROUND, new WorldPoint(2506, 3518, 0), "Construct a pyre on the lake near Otto.", logs, chewedBones, tinderbox, axe); - useLogOnPyre.addDialogStep("I've created a pyre ship!"); talkToOttoAfterPyre = new NpcStep(this, NpcID.BRUT_OTTO, new WorldPoint(2500, 3488, 0), "Return to Otto and tell him about the succesful pyre-making."); + talkToOttoAfterPyre.addDialogStep("I've created a pyre ship!"); // Barbarian Farming talkToOttoAboutFarming = new NpcStep(this, NpcID.BRUT_OTTO, new WorldPoint(2500, 3488, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java index 8214a77b8a..e5f22510d6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/daddyshome/DaddysHome.java @@ -29,6 +29,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -38,17 +40,17 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class DaddysHome extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java index fc8e5808d2..6e49d97982 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKey.java @@ -70,7 +70,7 @@ public Map loadSteps() protected void setupRequirements() { spade = new ItemRequirement("Spade", ItemID.SPADE).isNotConsumed(); - key = new KeyringRequirement("Enchanted key", configManager, KeyringCollection.ENCHANTED_KEY); + key = new KeyringRequirement("Enchanted key", KeyringCollection.ENCHANTED_KEY); varrockTeleports = new ItemRequirement("Varrock teleports", ItemID.POH_TABLET_VARROCKTELEPORT); ardougneTeleports = new ItemRequirement("Ardougne teleports", ItemID.POH_TABLET_ARDOUGNETELEPORT); rellekkaTeleports = new ItemRequirement("Rellekka teleport", ItemID.NZONE_TELETAB_RELLEKKA); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java index 3e6bd6e3b8..72b02d328f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/enchantedkey/EnchantedKeyDigStep.java @@ -42,7 +42,6 @@ import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -185,7 +184,7 @@ public boolean update(final String message) return false; } - final WorldPoint localWorld = Rs2Player.getWorldLocation(); + final WorldPoint localWorld = player.getWorldLocation(); if (localWorld == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java index d145cc52d6..98e3576b6b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/lairoftarnrazorlor/TarnRoute.java @@ -43,7 +43,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Prayer; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.Arrays; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java index fc1f5000a7..35303c6638 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenai/TheMageArenaI.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.themagearenai; +import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; @@ -86,7 +87,7 @@ protected void setupRequirements() { runesForCasts = new ItemRequirement("Runes for fighting Kolodion", -1, -1); runesForCasts.setDisplayItemId(ItemID.DEATHRUNE); - knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemID.KNIFE).isNotConsumed(); + knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemCollections.SLASH_WEB_KNIFE).isNotConsumed(); godCape = new ItemRequirement("God cape", ItemID.ZAMORAK_CAPE).isNotConsumed(); godCape.addAlternates(ItemID.GUTHIX_CAPE, ItemID.SARADOMIN_CAPE); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java index 320158b135..c9585dbe4f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MA2Locator.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.themagearenaii; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; @@ -38,7 +39,9 @@ import net.runelite.api.QuestState; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; +import net.runelite.client.ui.overlay.components.PanelComponent; +import java.awt.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -46,10 +49,10 @@ public class MA2Locator extends ComplexStateQuestHelper { - ItemRequirement zamorakStaff, guthixStaff, saradominStaff, runesForCasts, magicCombatGear, knife, brews, restores + ItemRequirement zamorakStaff, guthixStaff, saradominStaff, godStaff, runesForCasts, magicCombatGear, knife, brews, restores , food, recoils, enchantedSymbol, justicarsHand, demonsHeart, entRoots, godCape; - QuestStep locateFollowerSara; + QuestStep locateFollowers; Zone cavern; @@ -59,7 +62,7 @@ public QuestStep loadStep() initializeRequirements(); setupSteps(); - return locateFollowerSara; + return locateFollowers; } @Override @@ -71,6 +74,11 @@ protected void setupRequirements() guthixStaff.setTooltip("You can buy one from the Chamber Guardian in the Mage Arena Cavern for 80k"); saradominStaff = new ItemRequirement("Saradomin staff", ItemID.SARADOMIN_STAFF); saradominStaff.setTooltip("You can buy one from the Chamber Guardian in the Mage Arena Cavern for 80k"); + + godStaff = new ItemRequirement("God staff matching boss you're killing", ItemID.SARADOMIN_STAFF); + godStaff.addAlternates(ItemID.ZAMORAK_STAFF, ItemID.GUTHIX_STAFF); + godStaff.setTooltip("You can buy one from the Chamber Guardian in the Mage Arena Cavern for 80k"); + runesForCasts = new ItemRequirements("Runes for 50+ casts of god spells", new ItemRequirement("Blood runes", ItemID.BLOODRUNE, -1), new ItemRequirement("Air runes", ItemID.AIRRUNE, -1), @@ -102,7 +110,7 @@ protected void setupZones() public void setupSteps() { - locateFollowerSara = new MageArenaBossStep(this, saradominStaff, "desired", "", + locateFollowers = new MageArenaBossStep(this, godStaff, "", enchantedSymbol, food); } @@ -146,8 +154,21 @@ public List getGeneralRequirements() public List getPanels() { List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Upgrading the God Cape", Collections.singletonList(locateFollowerSara), + allSteps.add(new PanelDetails("Upgrading the God Cape", Collections.singletonList(locateFollowers), knife, saradominStaff, guthixStaff, zamorakStaff, runesForCasts)); return allSteps; } + + @Override + public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, PanelComponent panelComponent) + { + super.renderDebugOverlay(graphics, plugin, panelComponent); + + var currentStep = this.getCurrentStep(); + if (currentStep instanceof MageArenaBossStep) + { + var bossStep = (MageArenaBossStep) currentStep; + bossStep.renderDebugOverlay(graphics, plugin, panelComponent); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java index 076b82da09..569947a4cb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaBossStep.java @@ -31,18 +31,27 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; import lombok.NonNull; import net.runelite.api.ChatMessageType; +import net.runelite.api.KeyCode; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.VarbitID; +import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -52,8 +61,11 @@ import java.awt.image.BufferedImage; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; public class MageArenaBossStep extends DetailedQuestStep @@ -77,33 +89,79 @@ public class MageArenaBossStep extends DetailedQuestStep ItemRequirement[] baseRequirements; - @Nullable - private MageArenaSolver mageArenaSolver; + private God godToFind; + + private God lastGodClicked; + + /// Set to true after the user clicks "Activate" on the MA2 Enchanted Symbol. + /// This helps ensure we don't add key and mouse listeners to unrelated dialogs. + private boolean clickedActivateOnSymbol = false; + + private final Map mageArenaSolvers = new HashMap<>(); boolean foundLocation = false; int currentVar = 0; + boolean allowChangingBoss; + + // We need this as a player can press multiple keys in the options dialog, but only the first press counts + boolean keyPressedOnce; + + /// If set, will be used when "Activate" is clicked to figure out whether it's the last option available (only a thing during MA2) + private final @Nullable VarbitRequirement finishedSaradomin; + + /// If set, will be used when "Activate" is clicked to figure out whether it's the last option available (only a thing during MA2) + private final @Nullable VarbitRequirement finishedGuthix; + + /// If set, will be used when "Activate" is clicked to figure out whether it's the last option available (only a thing during MA2) + private final @Nullable VarbitRequirement finishedZamorak; + public MageArenaBossStep(QuestHelper questHelper, ItemRequirement staff, String bossName, - String abilityDetail, ItemRequirement... requirements) + String abilityDetail, + VarbitRequirement finishedSaradomin, + VarbitRequirement finishedGuthix, + VarbitRequirement finishedZamorak, + ItemRequirement... requirements) { super(questHelper, originalTextStart + bossName + originalTextEnd, requirements); this.bossName = bossName; this.abilityDetail = abilityDetail; this.staff = staff; this.baseRequirements = requirements; + this.godToFind = God.getByName(bossName); + + this.finishedSaradomin = finishedSaradomin; + this.finishedGuthix = finishedGuthix; + this.finishedZamorak = finishedZamorak; + } + + public MageArenaBossStep(QuestHelper questHelper, ItemRequirement staff, + String abilityDetail, ItemRequirement... requirements) + { + super(questHelper, originalTextStart + "desired" + originalTextEnd, requirements); + this.bossName = "desired"; + this.abilityDetail = abilityDetail; + this.staff = staff; + this.baseRequirements = requirements; + this.allowChangingBoss = true; + this.godToFind = God.SARADOMIN; + + this.finishedSaradomin = null; + this.finishedGuthix = null; + this.finishedZamorak = null; } @Override public void makeOverlayHint(PanelComponent panelComponent, QuestHelperPlugin plugin, @NonNull List additionalText, @NonNull List additionalRequirements) { super.makeOverlayHint(panelComponent, plugin, additionalText, additionalRequirements); - if (mageArenaSolver == null) + if (mageArenaSolvers == null) { return; } - final Collection digLocations = mageArenaSolver.getPossibleLocations(); + final Collection digLocations = mageArenaSolvers.get(godToFind).getPossibleLocations(); List locations = digLocations.stream() .map(MageArenaSpawnLocation::getArea) .distinct() @@ -169,16 +227,47 @@ public void resetState() setWorldPoint(DefinedPoint.of(null)); Set locations = Arrays.stream(MageArenaSpawnLocation.values()) - .collect(Collectors.toSet()); + .collect(Collectors.toSet()); + + if (mageArenaSolvers == null) return; + + mageArenaSolvers.forEach(((god, mageArenaSolver) -> + mageArenaSolver.resetSolver(locations) + )); - if (mageArenaSolver != null) + if (mageArenaSolvers.get(godToFind).getPossibleLocations().size() == 1) { - mageArenaSolver.resetSolver(locations); + this.setWorldPoint(mageArenaSolvers.get(godToFind).getPossibleLocations().iterator().next().getWorldPoint()); } - if (mageArenaSolver.getPossibleLocations().size() == 1) + } + + @Override + public void setWorldPoint(DefinedPoint definedPoint) + { + super.setWorldPoint(definedPoint); + + if (definedPoint == null || definedPoint.getWorldPoint() == null) { - this.setWorldPoint(mageArenaSolver.getPossibleLocations().iterator().next().getWorldPoint()); + setHighlightZone(java.util.Collections.emptyList()); + return; } + + final WorldPoint worldPoint = definedPoint.getWorldPoint(); + final int maxDistance = MageArenaTemperature.SHAKING.getMaxDistance(); + + final WorldPoint minPoint = new WorldPoint( + worldPoint.getX() - maxDistance, + worldPoint.getY() - maxDistance, + worldPoint.getPlane() + ); + + final WorldPoint maxPoint = new WorldPoint( + worldPoint.getX() + maxDistance, + worldPoint.getY() + maxDistance, + worldPoint.getPlane() + ); + + setHighlightZone(new Zone(minPoint, maxPoint)); } @Override @@ -201,9 +290,130 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) OverlayUtil.renderTileOverlay(client, graphics, localLocation, getSymbolLocation(), questHelper.getConfig().targetOverlayColor()); } + @Override + public void onWidgetLoaded(WidgetLoaded widgetLoaded) + { + super.onWidgetLoaded(widgetLoaded); + if (widgetLoaded.getGroupId() != InterfaceID.CHATMENU) return; + if (!clickedActivateOnSymbol) return; + + clickedActivateOnSymbol = false; + clientThread.invokeAtTickEnd(this::addListeners); + } + + public void addListeners() + { + final AtomicInteger SARADOMIN_KC = new AtomicInteger(-1); + final AtomicInteger GUTHIX_KC = new AtomicInteger(-1); + final AtomicInteger ZAMORAK_KC = new AtomicInteger(-1); + var chatMenu = client.getWidget(InterfaceID.Chatmenu.OPTIONS); + if (chatMenu == null || chatMenu.isHidden()) return; + if (chatMenu.getChildren() == null || chatMenu.getChildren().length < 4) return; + + for (var i = 1; i < 4; ++i) + { + var button = chatMenu.getChild(i); + if (button == null) + { + return; + } + var buttonText = button.getText(); + var buttonIndex = button.getIndex(); + if ("Saradomin".equals(buttonText)) + { + button.setOnClickListener((JavaScriptCallback) ev -> { handleBossButtonClick(God.SARADOMIN); }); + if (buttonIndex == 1) SARADOMIN_KC.set(KeyCode.KC_1); + else if (buttonIndex == 2) SARADOMIN_KC.set(KeyCode.KC_2); + else if (buttonIndex == 3) SARADOMIN_KC.set(KeyCode.KC_3); + } + else if ("Guthix".equals(buttonText)) + { + button.setOnClickListener((JavaScriptCallback) ev -> {handleBossButtonClick(God.GUTHIX);}); + if (buttonIndex == 1) GUTHIX_KC.set(KeyCode.KC_1); + else if (buttonIndex == 2) GUTHIX_KC.set(KeyCode.KC_2); + else if (buttonIndex == 3) GUTHIX_KC.set(KeyCode.KC_3); + } + else if ("Zamorak".equals(buttonText)) + { + button.setOnClickListener((JavaScriptCallback) ev -> { handleBossButtonClick(God.ZAMORAK); }); + if (buttonIndex == 1) ZAMORAK_KC.set(KeyCode.KC_1); + else if (buttonIndex == 2) ZAMORAK_KC.set(KeyCode.KC_2); + else if (buttonIndex == 3) ZAMORAK_KC.set(KeyCode.KC_3); + } + } + + keyPressedOnce = false; + + chatMenu.setHasListener(true); + chatMenu.setOnKeyListener((JavaScriptCallback) ev -> { + if (keyPressedOnce) return; + keyPressedOnce = true; + var saradominKc = SARADOMIN_KC.get(); + var guthixKc = GUTHIX_KC.get(); + var zamorakKc = ZAMORAK_KC.get(); + if (saradominKc != -1 && ev.getTypedKeyCode() == saradominKc) handleBossButtonClick(God.SARADOMIN); + if (guthixKc != -1 && ev.getTypedKeyCode() == guthixKc) handleBossButtonClick(God.GUTHIX); + if (zamorakKc != -1 && ev.getTypedKeyCode() == zamorakKc) handleBossButtonClick(God.ZAMORAK); + }); + chatMenu.revalidate(); + } + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked e) + { + if (e.getItemId() == ItemID.MA2_SYMBOL && "Activate".equals(e.getMenuOption())) + { + if (finishedSaradomin != null && finishedGuthix != null && finishedZamorak != null) { + var finishedSaradomin = this.finishedSaradomin.check(client); + var finishedGuthix = this.finishedGuthix.check(client); + var finishedZamorak = this.finishedZamorak.check(client); + + if (finishedSaradomin && finishedGuthix && !finishedZamorak) + { + // User only has Zamorak left + handleBossButtonClick(God.ZAMORAK); + return; + } + + if (finishedSaradomin && !finishedGuthix && finishedZamorak) + { + // User only has Guthix left + handleBossButtonClick(God.GUTHIX); + return; + } + + if (!finishedSaradomin && finishedGuthix && finishedZamorak) + { + // User only has Saradomin left + handleBossButtonClick(God.SARADOMIN); + return; + } + } + + clickedActivateOnSymbol = true; + } + } + + private void handleBossButtonClick(God godClicked) + { + if (allowChangingBoss && godToFind != godClicked) + { + // Technically this could be set to the last wp of the previous god tracking, but that + // Seemed to cause issues sometimes so something seems wrong with that assumption + mageArenaSolvers.get(godClicked).setLastWorldPoint(null); + godToFind = godClicked; + } + else + { + lastGodClicked = godClicked; + } + } + + @Override public void onChatMessage(ChatMessage chatMessage) { + super.onChatMessage(chatMessage); + if (chatMessage.getType() == ChatMessageType.GAMEMESSAGE) { update(chatMessage.getMessage()); @@ -212,7 +422,15 @@ public void onChatMessage(ChatMessage chatMessage) public void update(final String message) { - if (mageArenaSolver == null) + final MageArenaTemperatureChange temperatureChange = MageArenaTemperatureChange.of(message); + + if (mageArenaSolvers == null || mageArenaSolvers.get(godToFind) == null) + { + return; + } + + // If looking only for a specific boss, don't bother checking others + if (!allowChangingBoss && lastGodClicked != godToFind) { return; } @@ -235,13 +453,12 @@ public void update(final String message) return; } - final MageArenaTemperatureChange temperatureChange = MageArenaTemperatureChange.of(message); - - mageArenaSolver.signal(localWorld, temperature, temperatureChange); + final MageArenaSolver currentMageArenaSolver = mageArenaSolvers.get(godToFind); + currentMageArenaSolver.signal(localWorld, temperature, temperatureChange); - if (mageArenaSolver.getPossibleLocations().size() == 1) + if (currentMageArenaSolver.getPossibleLocations().size() == 1) { - this.setWorldPoint(mageArenaSolver.getPossibleLocations().iterator().next().getWorldPoint()); + this.setWorldPoint(currentMageArenaSolver.getPossibleLocations().iterator().next().getWorldPoint()); } else { @@ -255,14 +472,20 @@ public void startUp() { super.startUp(); currentVar = client.getVarbitValue(VarbitID.MA2_TIMER_REMAINING); - Set locations = - Arrays.stream(MageArenaSpawnLocation.values()) + + mageArenaSolvers.put(God.SARADOMIN, new MageArenaSolver(Arrays.stream(MageArenaSpawnLocation.values()).collect(Collectors.toSet()))); + mageArenaSolvers.put(God.GUTHIX, new MageArenaSolver(Arrays.stream(MageArenaSpawnLocation.values()).collect(Collectors.toSet()))); + mageArenaSolvers.put(God.ZAMORAK, new MageArenaSolver(Arrays.stream(MageArenaSpawnLocation.values()).collect(Collectors.toSet()))); + + var locations = Arrays.stream(MageArenaSpawnLocation.values()) .collect(Collectors.toSet()); - mageArenaSolver = new MageArenaSolver(locations); + if (locations.size() == 1) { this.setWorldPoint(locations.iterator().next().getWorldPoint()); } + + addListeners(); } @Override @@ -276,4 +499,55 @@ private BufferedImage getSymbolLocation() { return itemManager.getImage(ItemID.MA2_SYMBOL); } + + public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, PanelComponent panelComponent) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("God name") + .leftColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .right(this.bossName) + .rightColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .build() + ); + + panelComponent.getChildren().add(LineComponent.builder() + .left("God to find") + .leftColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .right(this.godToFind.name) + .rightColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .build() + ); + + panelComponent.getChildren().add(LineComponent.builder() + .left("Pending") + .leftColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .right(clickedActivateOnSymbol ? "y" : "n") + .rightColor(ColorScheme.BRAND_ORANGE_TRANSPARENT) + .build() + ); + } + + enum God + { + SARADOMIN("Saradomin"), + GUTHIX("Guthix"), + ZAMORAK("Zamorak"); + + final String name; + + God(String name) + { + this.name = name; + } + + public static God getByName(String name) + { + for (God god : God.values()) + { + if (god.name.equals(name)) return god; + } + // Failure catch + return SARADOMIN; + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java index 87383dcbc0..d46335f5ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSolver.java @@ -49,7 +49,9 @@ public class MageArenaSolver { @Setter private Set possibleLocations; + @Nullable + @Setter private WorldPoint lastWorldPoint; public MageArenaSolver(Set possibleLocations) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java index 39c8ca96a0..aa23732a44 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/MageArenaSpawnLocation.java @@ -48,13 +48,12 @@ public enum MageArenaSpawnLocation NORTH_EAST_LAVA_DRAGON_4(new WorldPoint(3247, 3862, 0), "North east of the Lava Dragon Isle."), WEST_LAVA_DRAGON(new WorldPoint(3146, 3895, 0), "West of the Lava Dragon Isle."), WEST_LAVA_DRAGON_2(new WorldPoint(3163, 3833, 0), "West of the Lava Dragon Isle."), - WEST_DEMONIC_RUINS(new WorldPoint(3314, 3876, 0), "West of the Demonic Ruins."), + EAST_DEMONIC_RUINS(new WorldPoint(3314, 3876, 0), "East of the Demonic Ruins."), EAST_LAVA_DRAGON_ISLE(new WorldPoint(3246, 3834, 0), "East of the Lava Dragon Isle."), EAST_LAVA_DRAGON_ISLE_2(new WorldPoint(3279, 3823, 0), "East of the Lava Dragon Isle."), SOUTH_EAST_LAVA_DRAGON_ISLE(new WorldPoint(3266, 3814, 0), "South east of the Lava Dragon Isle."), EAST_ROGUE(new WorldPoint(3306, 3936, 0), "East of the Rogues' Castle."), - // TODO: This one isn't a precise position - EAST_ROGUE_2(new WorldPoint(3343, 3911, 0), "East of the Rogues' Castle."), + EAST_ROGUE_2(new WorldPoint(3335, 3902, 0), "East of the Rogues' Castle."), WEST_ROGUE(new WorldPoint(3261, 3909, 0), "West of the Rogues' Castle."); private final WorldPoint worldPoint; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java index d3cd649cc1..1029c9420a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/themagearenaii/TheMageArenaII.java @@ -35,7 +35,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; @@ -46,6 +48,7 @@ import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -55,7 +58,14 @@ public class TheMageArenaII extends BasicQuestHelper ItemRequirement zamorakStaff, guthixStaff, saradominStaff, runesForCasts, magicCombatGear, knife, brews, restores , food, recoils, enchantedSymbol, justicarsHand, demonsHeart, entRoots, godCape; - Requirement inCavern, givenHand, givenHeart, givenRoots; + Requirement inCavern; + VarbitRequirement givenHand; + VarbitRequirement givenHeart; + VarbitRequirement givenRoots; + + VarplayerRequirement unlockedSaradominStrike; + VarplayerRequirement unlockedClawsOfGuthix; + VarplayerRequirement unlockedFlamesOfZamorak; QuestStep enterCavern, talkToKolodion, locateFollowerSara, locateFollowerGuthix, locateFollowerZammy, enterCavernWithHand, enterCavernWithHeart, enterCavernWithRoots, giveKolodionHeart, giveKolodionHand, @@ -115,7 +125,7 @@ protected void setupRequirements() new ItemRequirement("Fire runes", ItemID.FIRERUNE, -1)); magicCombatGear = new ItemRequirement("Magic combat gear", -1, 1).isNotConsumed(); magicCombatGear.setDisplayItemId(BankSlotIcons.getMagicCombatGear()); - knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemID.KNIFE).isNotConsumed(); + knife = new ItemRequirement("Knife or sharp weapon to cut through a web", ItemCollections.SLASH_WEB_KNIFE).isNotConsumed(); brews = new ItemRequirement("Saradomin brews", ItemCollections.SARADOMIN_BREWS, -1); restores = new ItemRequirement("Super restores", ItemCollections.SUPER_RESTORE_POTIONS, -1); food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); @@ -130,6 +140,13 @@ protected void setupRequirements() godCape = new ItemRequirement("God cape", ItemID.ZAMORAK_CAPE).isNotConsumed(); godCape.addAlternates(ItemID.GUTHIX_CAPE, ItemID.SARADOMIN_CAPE); godCape.setHighlightInInventory(true); + + unlockedSaradominStrike = new VarplayerRequirement(VarPlayerID.SARAMAGE, 100, Operation.GREATER_EQUAL, "Unlocked Saradomin Strike"); + unlockedSaradominStrike.setTooltip("Unlocked by casting the Saradomin Strike 100 times within the mage arena"); + unlockedClawsOfGuthix = new VarplayerRequirement(VarPlayerID.GUTHMAGE, 100, Operation.GREATER_EQUAL, "Unlocked Claws of Guthix"); + unlockedClawsOfGuthix.setTooltip("Unlocked by casting the Claws of Guthix 100 times within the mage arena"); + unlockedFlamesOfZamorak = new VarplayerRequirement(VarPlayerID.ZAMOMAGE, 100, Operation.GREATER_EQUAL, "Unlocked Flames of Zamorak"); + unlockedFlamesOfZamorak.setTooltip("Unlocked by casting the Flames of Zamorak 100 times within the mage arena"); } @Override @@ -161,14 +178,15 @@ public void setupSteps() locateFollowerSara = new MageArenaBossStep(this, saradominStaff, "Saradomin", "If he fires a blue wave at " + "you, move off your tile to avoid it. If you don't, he will pull you into melee distance.", - enchantedSymbol, food); + givenHand, givenRoots, givenHeart, enchantedSymbol, food); locateFollowerSara.addDialogStep("Saradomin"); locateFollowerGuthix = new MageArenaBossStep(this, guthixStaff, "Guthix", "If he spawns green orbs, destroy " + - "them to stop them healing him.", enchantedSymbol, food); + "them to stop them healing him.", + givenHand, givenRoots, givenHeart, enchantedSymbol, food); locateFollowerGuthix.addDialogStep("Guthix"); locateFollowerZammy = new MageArenaBossStep(this, zamorakStaff, "Zamorak", "If he fires an energy ball at " + "you, move away away from the boss to reduce the damage you take.", - enchantedSymbol, food); + givenHand, givenRoots, givenHeart, enchantedSymbol, food); locateFollowerZammy.addDialogStep("Zamorak"); enterCavernWithHand = new ObjectStep(this, ObjectID.MAGEARENA_LEVER_TO_CELLAR, new WorldPoint(3090, 3956, 0), "Return with" + @@ -237,7 +255,9 @@ public List getGeneralRequirements() ArrayList reqs = new ArrayList<>(); reqs.add(new SkillRequirement(Skill.MAGIC, 75)); reqs.add(new QuestRequirement(QuestHelperQuest.THE_MAGE_ARENA, QuestState.FINISHED)); - reqs.add(new ItemRequirement("Unlocked all 3 god spells", -1, -1)); + reqs.add(unlockedSaradominStrike); + reqs.add(unlockedClawsOfGuthix); + reqs.add(unlockedFlamesOfZamorak); return reqs; } @@ -252,7 +272,7 @@ public List getPanels() { List allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Upgrading the God Cape", Arrays.asList(enterCavern, - talkToKolodion, locateAndKillMinions), knife, saradominStaff, guthixStaff, zamorakStaff, runesForCasts)); + talkToKolodion, locateAndKillMinions, useGodCapeOnKolidion), knife, saradominStaff, guthixStaff, zamorakStaff, unlockedSaradominStrike, unlockedClawsOfGuthix, unlockedFlamesOfZamorak, runesForCasts)); return allSteps; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java index c716a0340a..e985036891 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/miniquests/valetotems/ValeTotems.java @@ -32,14 +32,21 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -48,14 +55,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - /** * The quest guide for the "Vale Totems" OSRS quest */ @@ -153,7 +152,7 @@ protected void setupRequirements() oneDecorativeItem.setTooltip("You can also use Willow, Maple, Yew, Magic, or Redwood decorative items, but it needs to match the logs you used to build the totem."); needToBuildTotem = new VarbitRequirement(VarbitID.ENT_TOTEMS_BROKEN_CHAT, 1); - isTotemBaseBuilt = new VarbitRequirement(VarbitID.ENT_TOTEMS_SITE_1_BASE, 1); + isTotemBaseBuilt = new VarbitRequirement(VarbitID.ENT_TOTEMS_SITE_1_BASE, 0, Operation.GREATER); isBuffaloNearby = or( new VarbitRequirement(VarbitID.ENT_TOTEMS_SITE_1_ANIMAL_1, 1), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java index 09ddde6c43..e580be9e8b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingConfigChangeHandler.java @@ -28,7 +28,6 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.config.ConfigManager; import net.runelite.client.events.ConfigChanged; - import java.util.function.Consumer; public class FarmingConfigChangeHandler diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java index 01c49e4e82..36f7e1f383 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingPatch.java @@ -48,14 +48,28 @@ public class FarmingPatch private final PatchImplementation implementation; private int farmer = -1; private final int patchNumber; - @Getter + @Getter(AccessLevel.NONE) private final WorldPoint location; - @Getter private final Shape patchArea; + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation) + { + this(name, varbit, implementation, null, new Polygon(), -1, -1); + } + + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, int farmer) + { + this(name, varbit, implementation, null, new Polygon(), farmer, -1); + } + + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, int farmer, int patchNumber) + { + this(name, varbit, implementation, null, new Polygon(), farmer, patchNumber); + } + FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, WorldPoint location) { - this(name, varbit, implementation, location, new Polygon(), -1); + this(name, varbit, implementation, location, new Polygon(), -1, -1); } FarmingPatch(String name, @Varbit int varbit, PatchImplementation implementation, WorldPoint location, Shape patchArea) @@ -79,6 +93,19 @@ public class FarmingPatch this.patchArea = patchArea; } + public WorldPoint getLocation() + { + if (location != null) + { + return location; + } + if (region == null) + { + return null; + } + return WorldPoint.fromRegion(region.getRegionID(), 32, 32, 0); + } + String configKey() { return region.getRegionID() + "." + varbit; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java index 288f603bab..f0dbdcf5bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingRegion.java @@ -24,22 +24,16 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns; -import java.util.Collections; -import java.util.HashSet; import lombok.Getter; import net.runelite.api.coords.WorldPoint; -import java.util.Set; -import org.jetbrains.annotations.NotNull; - @Getter -public class FarmingRegion implements Comparable +public class FarmingRegion { private final String name; private final int regionID; private final boolean definite; private final FarmingPatch[] patches; - private final Set regionIDs; FarmingRegion(String name, int regionID, boolean definite, FarmingPatch... patches) { @@ -47,56 +41,20 @@ public class FarmingRegion implements Comparable this.regionID = regionID; this.definite = definite; this.patches = patches; - this.regionIDs = Set.of(regionID); - for (FarmingPatch p : patches) - { - p.setRegion(this); - } - } - - FarmingRegion(String name, int regionID, boolean definite, Set regionIDs, FarmingPatch... patches) - { - this.name = name; - this.regionID = regionID; - this.definite = definite; - this.patches = patches; - - Set allRegionIds = new HashSet<>(regionIDs); - allRegionIds.add(regionID); - this.regionIDs = Collections.unmodifiableSet(allRegionIds); - for (FarmingPatch p : patches) { p.setRegion(this); } } - /** - * Check if the given WorldPoint is within this farming region - * Checks if the point's regionID is in this region's regionIDs set - * - * @param loc The WorldPoint to check - * @return true if the point is within this farming region - */ public boolean isInBounds(WorldPoint loc) { - return regionIDs.contains(loc.getRegionID()); + return true; } @Override public String toString() { - String sb = "FarmingRegion{name='" + name + '\'' + - ", regionID=" + regionID + - ", definite=" + definite + - ", patches=" + patches.length + - '}'; - return sb; - } - - @Override - public int compareTo(@NotNull FarmingRegion o) - { - return Integer.compare(regionID, o.getRegionID()); + return name; } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java index 8280a86e6c..e03879a7bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingUtils.java @@ -27,6 +27,8 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.Client; import net.runelite.api.gameval.ItemID; import net.runelite.client.config.ConfigManager; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java index 6f2416d201..52f4a864f1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/FarmingWorld.java @@ -30,15 +30,21 @@ import com.google.common.collect.Multimaps; import com.google.inject.Singleton; import java.awt.Polygon; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.stream.Collectors; import lombok.Getter; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarbitID; import net.runelite.client.plugins.timetracking.Tab; -import java.util.*; -import java.util.stream.Collectors; - @Singleton public class FarmingWorld { @@ -46,12 +52,13 @@ public class FarmingWorld private Multimap regions = HashMultimap.create(); @Getter + @SuppressWarnings("PMD.ImmutableField") private Map> tabs = new HashMap<>(); private final Comparator tabSorter = Comparator - .comparing(FarmingPatch::getImplementation) - .thenComparing((FarmingPatch p) -> p.getRegion().getName()) - .thenComparing(FarmingPatch::getName); + .comparing(FarmingPatch::getImplementation) + .thenComparing((FarmingPatch p) -> p.getRegion().getName()) + .thenComparing(FarmingPatch::getName); @Getter private final FarmingRegion farmingGuildRegion; @@ -60,120 +67,104 @@ public class FarmingWorld { // Some of these patches get updated in multiple regions. // It may be worth it to add a specialization for these patches - add(new FarmingRegion("Al Kharid", 13106, false, Set.of(13105, 13362), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CACTUS, new WorldPoint(3317, 3203, 0), - new Polygon( + add(new FarmingRegion("Al Kharid", 13106, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CACTUS, new WorldPoint(3317, 3203, 0), new Polygon( new int[]{3315, 3315, 3316, 3316}, new int[]{3202, 3203, 3203, 3202}, 4 - ), - NpcID.FARMING_GARDENER_CACTUS) - )); + ), NpcID.FARMING_GARDENER_CACTUS) + ), 13362, 13105); - add(new FarmingRegion("Aldarin", 5421, false, Set.of(5165, 5166, 5422, 5677, 5678), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(1366, 2941, 0), - new Polygon( + add(new FarmingRegion("Aldarin", 5421, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(1366, 2941, 0), new Polygon( new int[]{1363, 1363, 1366, 1366}, new int[]{2937, 2940, 2940, 2937}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_5) + ), NpcID.FARMING_GARDENER_HOPS_5) + ), 5165, 5166, 5422, 5677, 5678); + + add(new FarmingRegion("Anglers' Retreat", 9770, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, NpcID.FARMING_GARDENER_HARDWOOD_TREE_5) )); - add(new FarmingRegion("Ardougne", 10290, false, Set.of(10546), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2616, 3226, 0), - new Polygon( + add(new FarmingRegion("Ardougne", 10290, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2616, 3226, 0), new Polygon( new int[]{2617, 2617, 2618, 2618}, new int[]{3225, 3226, 3226, 3225}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_4) - )); + ), NpcID.FARMING_GARDENER_BUSH_4) + ), 10546); add(new FarmingRegion("Ardougne", 10548, false, - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3379, 0), - new Polygon( + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3379, 0), new Polygon( new int[]{2662, 2662, 2671, 2671, 2663, 2663}, new int[]{3377, 3379, 3379, 3378, 3378, 3377}, 6 - ), - NpcID.KRAGEN, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3371, 0), - new Polygon( + ), NpcID.KRAGEN, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2672, 3371, 0), new Polygon( new int[]{2662, 2662, 2663, 2663, 2671, 2671}, new int[]{3370, 3372, 3372, 3371, 3371, 3370}, 6 - ), - NpcID.KRAGEN, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2668, 3375, 0), - new Polygon( + ), NpcID.KRAGEN, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2668, 3375, 0), new Polygon( new int[]{2666, 2666, 2667, 2667}, new int[]{3374, 3375, 3375, 3374}, - 4) - ), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2672, 3375, 0), - new Polygon( + 4)), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2672, 3375, 0), new Polygon( new int[]{2670, 2670, 2671, 2671}, new int[]{3374, 3375, 3375, 3374}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(2662, 3375, 0)) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) )); - add(new FarmingRegion("Avium Savannah", 6702, true, Set.of(6446), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(1685, 2971, 0), - new Polygon( + add(new FarmingRegion("Auburnvale", 5427, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, NpcID.FARMING_GARDENER_TREE_7), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.BELLADONNA) + ), 5428, 5684); + + add(new FarmingRegion("Avium Savannah", 6702, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(1685, 2971, 0), new Polygon( new int[]{1686, 1686, 1688, 1688}, new int[]{2971, 2973, 2973, 2971}, 4 - ), - NpcID.FROG_QUEST_MARCELLUS) - )); + ), NpcID.FROG_QUEST_MARCELLUS) + ), 6446); - add(new FarmingRegion("Brimhaven", 11058, false, Set.of(11057), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2766, 3213, 0), - new Polygon( + add(new FarmingRegion("Brimhaven", 11058, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2766, 3213, 0), new Polygon( new int[]{2764, 2764, 2765, 2765}, new int[]{3212, 3213, 3213, 3212}, 4 - ), - NpcID.GARTH), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2800, 3202, 0), - new Polygon( + ), NpcID.GARTH), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2800, 3202, 0), new Polygon( new int[]{2801, 2801, 2803, 2803}, new int[]{3202, 3204, 3204, 3202}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_3) - )); + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_3) + ), 11057); - add(new FarmingRegion("Catherby", 11062, false, Set.of(11061, 11318, 11317), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2814, 3466, 0), - new Polygon( + add(new FarmingRegion("Catherby", 11062, false, + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(2814, 3466, 0), new Polygon( new int[]{2805, 2805, 2814, 2814, 2806, 2806}, new int[]{3466, 3468, 3468, 3467, 3467, 3466}, 6 - ), - NpcID.DANTAERA, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2815, 3460, 0), - new Polygon( + ), NpcID.DANTAERA, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(2815, 3460, 0), new Polygon( new int[]{2805, 2805, 2806, 2806, 2814, 2814}, new int[]{3459, 3461, 3461, 3460, 3460, 3459}, 6 - ), - NpcID.DANTAERA, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2810, 3465, 0), - new Polygon( + ), NpcID.DANTAERA, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(2810, 3465, 0), new Polygon( new int[]{2809, 2809, 2810, 2810}, new int[]{3463, 3464, 3464, 3463}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2815, 3464, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(2815, 3464, 0), new Polygon( new int[]{2813, 2813, 2814, 2814}, new int[]{3463, 3464, 3464, 3463}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(2805, 3464, 0)) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) ) { @Override @@ -186,15 +177,13 @@ public boolean isInBounds(WorldPoint loc) } return true; } - }); + }, 11061, 11318, 11317); add(new FarmingRegion("Catherby", 11317, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2860, 3432, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2860, 3432, 0), new Polygon( new int[]{2860, 2860, 2861, 2861}, new int[]{3433, 3434, 3434, 3433}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_4) + ), NpcID.FARMING_GARDENER_FRUIT_4) ) { //The fruit tree patch is always sent when upstairs in 11317 @@ -205,119 +194,92 @@ public boolean isInBounds(WorldPoint loc) } }); - add(new FarmingRegion("Civitas illa Fortis", 6192, false, Set.of(6447, 6448, 6449, 6191, 6193), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1586, 3102, 0), - new Polygon( + add(new FarmingRegion("Civitas illa Fortis", 6192, false, + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1586, 3102, 0), new Polygon( new int[]{1581, 1581, 1585, 1585, 1582, 1582}, new int[]{3098, 3103, 3103, 3102, 3102, 3098}, 6 - ), - NpcID.FORTIS_GARDENER, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1591, 3098, 0), - new Polygon( + ), NpcID.FORTIS_GARDENER, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1591, 3098, 0), new Polygon( new int[]{1585, 1585, 1589, 1589, 1590, 1590}, new int[]{3094, 3095, 3095, 3098, 3098, 3094}, 6 - ), - NpcID.FORTIS_GARDENER, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1587, 3099, 0), - new Polygon( + ), NpcID.FORTIS_GARDENER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1587, 3099, 0), new Polygon( new int[]{1585, 1585, 1586, 1586}, new int[]{3098, 3099, 3099, 3098}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1581, 3094, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1581, 3094, 0), new Polygon( new int[]{1581, 1581, 1582, 1582}, new int[]{3094, 3095, 3095, 3094}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(1587, 3103, 0)) - )); + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) + ), 6447, 6448, 6449, 6191, 6193); add(new FarmingRegion("Champions' Guild", 12596, true, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(3181, 3356, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(3181, 3356, 0), new Polygon( new int[]{3181, 3181, 3182, 3182}, new int[]{3357, 3358, 3358, 3357}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_1) + ), NpcID.FARMING_GARDENER_BUSH_1) )); add(new FarmingRegion("Draynor Manor", 12340, false, - new FarmingPatch("Belladonna", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BELLADONNA, new WorldPoint(3088, 3355, 0), - new Polygon( - new int[]{3086, 3086, 3087, 3087}, - new int[]{3354, 3355, 3355, 3354}, - 4 - )) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BELLADONNA) )); - add(new FarmingRegion("Entrana", 11060, false, Set.of(11316), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2812, 3334, 0), - new Polygon( + add(new FarmingRegion("Entrana", 11060, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2812, 3334, 0), new Polygon( new int[]{2809, 2809, 2812, 2812}, new int[]{3335, 3338, 3338, 3335}, 4 - ), - NpcID.FRANCIS) - )); + ), NpcID.FRANCIS) + ), 11316); add(new FarmingRegion("Etceteria", 10300, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2592, 3862, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2592, 3862, 0), new Polygon( new int[]{2591, 2591, 2592, 2592}, new int[]{3863, 3864, 3864, 3863}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_3), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2613, 3856, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_BUSH_3), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SPIRIT_TREE, new WorldPoint(2613, 3856, 0), new Polygon( new int[]{2612, 2612, 2614, 2614}, new int[]{3857, 3859, 3859, 3857}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_2) + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_2) )); - add(new FarmingRegion("Falador", 11828, false, Set.of(12084), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3004, 3371, 0), - new Polygon( + add(new FarmingRegion("Falador", 11828, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3004, 3371, 0), new Polygon( new int[]{3003, 3003, 3005, 3005}, new int[]{3372, 3374, 3374, 3372}, 4 - ), - NpcID.FARMING_GARDENER_TREE_2) - )); + ), NpcID.FARMING_GARDENER_TREE_2) + ), 12084); add(new FarmingRegion("Falador", 12083, false, - new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3052, 3307, 0), - new Polygon( + new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3052, 3307, 0), new Polygon( new int[]{3050, 3050, 3054, 3054, 3051, 3051}, new int[]{3307, 3312, 3312, 3311, 3311, 3307}, 6 - ), - NpcID.ELSTAN, 0), - new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3055, 3305, 0), - new Polygon( + ), NpcID.ELSTAN, 0), + new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3055, 3305, 0), new Polygon( new int[]{3055, 3055, 3058, 3058, 3059, 3059}, new int[]{3303, 3304, 3304, 3308, 3308, 3303}, 6 - ), - NpcID.ELSTAN, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3053, 3307, 0), - new Polygon( + ), NpcID.ELSTAN, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3053, 3307, 0), new Polygon( new int[]{3054, 3054, 3055, 3055}, new int[]{3307, 3308, 3308, 3307}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3057, 3311, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3057, 3311, 0), new Polygon( new int[]{3058, 3058, 3059, 3059}, new int[]{3311, 3312, 3312, 3311}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(3056, 3311, 0)) + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) ) { @Override @@ -328,28 +290,22 @@ public boolean isInBounds(WorldPoint loc) } }); - add(new FarmingRegion("Fossil Island", 14651, false, Set.of(14907, 14908, 15164, 14652, 14906, 14650, 15162, 15163), - new FarmingPatch("East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3713, 3835, 0), - new Polygon( + add(new FarmingRegion("Fossil Island", 14651, false, + new FarmingPatch("East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3713, 3835, 0), new Polygon( new int[]{3714, 3714, 3716, 3716}, new int[]{3834, 3836, 3836, 3834}, 4 - ), - NpcID.FOSSIL_SQUIRREL_GARDENER1), - new FarmingPatch("Middle", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3708, 3835, 0), - new Polygon( + ), NpcID.FOSSIL_SQUIRREL_GARDENER1), + new FarmingPatch("Middle", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3708, 3835, 0), new Polygon( new int[]{3707, 3707, 3709, 3709}, new int[]{3832, 3834, 3834, 3832}, 4 - ), - NpcID.FOSSIL_SQUIRREL_GARDENER2), - new FarmingPatch("West", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3701, 3836, 0), - new Polygon( + ), NpcID.FOSSIL_SQUIRREL_GARDENER2), + new FarmingPatch("West", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.HARDWOOD_TREE, new WorldPoint(3701, 3836, 0), new Polygon( new int[]{3701, 3701, 3703, 3703}, new int[]{3836, 3838, 3838, 3836}, 4 - ), - NpcID.FOSSIL_SQUIRREL_GARDENER3) + ), NpcID.FOSSIL_SQUIRREL_GARDENER3) ) { @Override @@ -366,194 +322,168 @@ public boolean isInBounds(WorldPoint loc) //East and west ladders to rope bridge if ((loc.getX() == 3729 || loc.getX() == 3728 || loc.getX() == 3747 || loc.getX() == 3746) - && loc.getY() <= 3832 && loc.getY() >= 3830) + && loc.getY() <= 3832 && loc.getY() >= 3830) { return false; } return loc.getPlane() == 0; } - }); + }, 14907, 14908, 15164, 14652, 14906, 14650, 15162, 15163); add(new FarmingRegion("Seaweed", 15008, false, - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SEAWEED, new WorldPoint(3733, 10272, 1), - new Polygon( + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SEAWEED, new WorldPoint(3733, 10272, 1), new Polygon( new int[]{3733, 3733, 3734, 3734}, new int[]{10273, 10274, 10274, 10273}, 4 - ), - NpcID.FOSSIL_GARDENER_UNDERWATER, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SEAWEED, new WorldPoint(3733, 10269, 1), - new Polygon( + ), NpcID.FOSSIL_GARDENER_UNDERWATER, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.SEAWEED, new WorldPoint(3733, 10269, 1), new Polygon( new int[]{3733, 3733, 3734, 3734}, new int[]{10267, 10268, 10268, 10267}, 4 - ), - NpcID.FOSSIL_GARDENER_UNDERWATER, 1) + ), NpcID.FOSSIL_GARDENER_UNDERWATER, 1) )); - add(new FarmingRegion("Gnome Stronghold", 9781, true, Set.of(9782, 9526, 9525), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2437, 3417, 0), - new Polygon( + add(new FarmingRegion("Gnome Stronghold", 9781, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2437, 3417, 0), new Polygon( new int[]{2437, 2437, 2435, 2435}, new int[]{3416, 3414, 3414, 3416}, 4 - ), - NpcID.FARMING_GARDENER_TREE_GNOME), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.FRUIT_TREE, new WorldPoint(2475, 3447, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_TREE_GNOME), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.FRUIT_TREE, new WorldPoint(2475, 3447, 0), new Polygon( new int[]{2475, 2475, 2476, 2476}, new int[]{3445, 3446, 3446, 3445}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_1) - )); + ), NpcID.FARMING_GARDENER_FRUIT_1) + ), 9782, 9526, 9525); + + add(new FarmingRegion("Great Conch", 12581, true, + new FarmingPatch("East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CORAL, NpcID.TORTUGAN_CORAL_FARMER, 0), + new FarmingPatch("West", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.CORAL, NpcID.TORTUGAN_CORAL_FARMER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.CALQUAT, NpcID.FARMING_GARDENER_CALQUAT_3) + ), 12325, 12326, 12327, 12580, 12581, 12582, 12583, 12836, 12837, 12838, 12839, 13092, 13093, 13194); add(new FarmingRegion("Harmony", 15148, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3795, 2838, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3795, 2838, 0), new Polygon( new int[]{3794, 3794}, new int[]{2833, 2838}, 2 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HERB, new WorldPoint(3790, 3839, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.HERB, new WorldPoint(3790, 3839, 0), new Polygon( new int[]{3789, 3789, 3790, 3790}, new int[]{2837, 2838, 2838, 2837}, 4 )) )); - add(new FarmingRegion("Kourend", 6967, false, Set.of(6711), - new FarmingPatch("North East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1739, 3553, 0), - new Polygon( + add(new FarmingRegion("Kastori", 5423, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CALQUAT, NpcID.FARMING_GARDENER_CALQUAT_2), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.FRUIT_TREE, NpcID.FARMING_GARDENER_FRUIT_7), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER) + ), 5167, 5424); + + add(new FarmingRegion("Kourend", 6967, false, + new FarmingPatch("North East", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(1739, 3553, 0), new Polygon( new int[]{1733, 1733, 1739, 1739, 1738, 1738}, new int[]{3558, 3559, 3559, 3554, 3554, 3558}, 6 - ), - NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 0), - new FarmingPatch("South West", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1735, 3552, 0), - new Polygon( + ), NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 0), + new FarmingPatch("South West", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(1735, 3552, 0), new Polygon( new int[]{1730, 1730, 1731, 1731, 1735, 1735}, new int[]{3550, 3555, 3555, 3551, 3551, 3550}, 6 - ), - NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1735, 3553, 0), - new Polygon( + ), NpcID.HOSIDIUS_ALLOTMENT_GARDENER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(1735, 3553, 0), new Polygon( new int[]{1734, 1734, 1735, 1734}, new int[]{3554, 3555, 3555, 1734}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1739, 3552, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(1739, 3552, 0), new Polygon( new int[]{1738, 1738, 1739, 1739}, new int[]{3550, 3551, 3551, 3550}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(1730, 3557, 0)), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.SPIRIT_TREE, new WorldPoint(1695, 3543, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.SPIRIT_TREE, new WorldPoint(1695, 3543, 0), new Polygon( new int[]{1692, 1692, 1694, 1694}, new int[]{3541, 3543, 3543, 3541}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_4) - )); - - /* - Not implemented - */ + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_4) + ), 6711); add(new FarmingRegion("Kourend", 7223, false, - new FarmingPatch("East 1", VarbitID.FARMING_TRANSMIT_A1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 2", VarbitID.FARMING_TRANSMIT_A2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 3", VarbitID.FARMING_TRANSMIT_B1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 4", VarbitID.FARMING_TRANSMIT_B2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 5", VarbitID.FARMING_TRANSMIT_C1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("East 6", VarbitID.FARMING_TRANSMIT_C2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 1", VarbitID.FARMING_TRANSMIT_D1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 2", VarbitID.FARMING_TRANSMIT_D2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 3", VarbitID.FARMING_TRANSMIT_E1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 4", VarbitID.FARMING_TRANSMIT_E2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 5", VarbitID.FARMING_TRANSMIT_F1, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)), - new FarmingPatch("West 6", VarbitID.FARMING_TRANSMIT_F2, PatchImplementation.GRAPES, new WorldPoint(-1, -1, 0)) - )); - - add(new FarmingRegion("Lletya", 9265, false, Set.of(11103), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2345, 3162, 0), - new Polygon( + new FarmingPatch("East 1", VarbitID.FARMING_TRANSMIT_A1, PatchImplementation.GRAPES), + new FarmingPatch("East 2", VarbitID.FARMING_TRANSMIT_A2, PatchImplementation.GRAPES), + new FarmingPatch("East 3", VarbitID.FARMING_TRANSMIT_B1, PatchImplementation.GRAPES), + new FarmingPatch("East 4", VarbitID.FARMING_TRANSMIT_B2, PatchImplementation.GRAPES), + new FarmingPatch("East 5", VarbitID.FARMING_TRANSMIT_C1, PatchImplementation.GRAPES), + new FarmingPatch("East 6", VarbitID.FARMING_TRANSMIT_C2, PatchImplementation.GRAPES), + new FarmingPatch("West 1", VarbitID.FARMING_TRANSMIT_D1, PatchImplementation.GRAPES), + new FarmingPatch("West 2", VarbitID.FARMING_TRANSMIT_D2, PatchImplementation.GRAPES), + new FarmingPatch("West 3", VarbitID.FARMING_TRANSMIT_E1, PatchImplementation.GRAPES), + new FarmingPatch("West 4", VarbitID.FARMING_TRANSMIT_E2, PatchImplementation.GRAPES), + new FarmingPatch("West 5", VarbitID.FARMING_TRANSMIT_F1, PatchImplementation.GRAPES), + new FarmingPatch("West 6", VarbitID.FARMING_TRANSMIT_F2, PatchImplementation.GRAPES) + )); + + add(new FarmingRegion("Lletya", 9265, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2345, 3162, 0), new Polygon( new int[]{2346, 2346, 2347, 2347}, new int[]{3161, 3162, 3162, 3161}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_TREE_5) - )); + ), NpcID.FARMING_GARDENER_FRUIT_TREE_5) + ), 11103); add(new FarmingRegion("Lumbridge", 12851, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(3232, 3317, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(3232, 3317, 0), new Polygon( new int[]{3227, 3227, 3231, 3231}, new int[]{3313, 3317, 3317, 3313}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_3) + ), NpcID.FARMING_GARDENER_HOPS_3) )); - add(new FarmingRegion("Lumbridge", 12594, false, Set.of(12850), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3195, 3230, 0), - new Polygon( + add(new FarmingRegion("Lumbridge", 12594, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3195, 3230, 0), new Polygon( new int[]{3192, 3192, 3194, 3194}, new int[]{3230, 3232, 3232, 3230}, 4 - ), - NpcID.FARMING_GARDENER_TREE_4) - )); + ), NpcID.FARMING_GARDENER_TREE_4) + ), 12850); - add(new FarmingRegion("Morytania", 13622, false, Set.of(13878), - new FarmingPatch("Mushroom", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.MUSHROOM, new WorldPoint(3451, 3474, 0), - new Polygon( + add(new FarmingRegion("Morytania", 13622, false, + new FarmingPatch("Mushroom", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.MUSHROOM, new WorldPoint(3451, 3474, 0), new Polygon( new int[]{3451, 3451, 3452, 3452}, new int[]{3472, 3473, 3473, 3472}, 4 )) - )); - add(new FarmingRegion("Morytania", 14391, false, Set.of(14390), - new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3597, 3524, 0), - new Polygon( + ), 13878); + add(new FarmingRegion("Morytania", 14391, false, + new FarmingPatch("North West", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3597, 3524, 0), new Polygon( new int[]{3597, 3597, 3601, 3601, 3598, 3598}, new int[]{3525, 3530, 3530, 3529, 3529, 3525}, 6 - ), - NpcID.LYRA, 0), - new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3601, 3522, 0), - new Polygon( + ), NpcID.LYRA, 0), + new FarmingPatch("South East", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3601, 3522, 0), new Polygon( new int[]{3602, 3602, 3605, 3605, 3606, 3606}, new int[]{3521, 3522, 3522, 3526, 3526, 3521}, 6 - ), - NpcID.LYRA, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3601, 3524, 0), - new Polygon( + ), NpcID.LYRA, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3601, 3524, 0), new Polygon( new int[]{3601, 3601, 3602, 3602}, new int[]{3225, 3226, 3226, 3225}, 4 - ) - ), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3605, 3528, 0), - new Polygon( + )), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.HERB, new WorldPoint(3605, 3528, 0), new Polygon( new int[]{3605, 3605, 3606, 3606}, new int[]{3529, 3530, 3530, 3529}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST, new WorldPoint(3609, 3522, 0)) - )); + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.COMPOST) + ), 14390); - add(new FarmingRegion("Port Sarim", 12082, false, Set.of(12083), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(3059, 3257, 0), - new Polygon( + add(new FarmingRegion("Port Sarim", 12082, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(3059, 3257, 0), new Polygon( new int[]{3059, 3059, 3061, 3061}, new int[]{3257, 3259, 3259, 3257}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_1) + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_1) ) { @Override @@ -561,90 +491,74 @@ public boolean isInBounds(WorldPoint loc) { return loc.getY() < 3272; } - }); + }, 12083); - add(new FarmingRegion("Rimmington", 11570, false, Set.of(11826), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2940, 3223, 0), - new Polygon( + add(new FarmingRegion("Rimmington", 11570, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.BUSH, new WorldPoint(2940, 3223, 0), new Polygon( new int[]{2940, 2940, 2941, 2941}, new int[]{3221, 3222, 3222, 3221}, 4 - ), - NpcID.FARMING_GARDENER_BUSH_2) - )); + ), NpcID.FARMING_GARDENER_BUSH_2) + ), 11826); - add(new FarmingRegion("Seers' Village", 10551, false, Set.of(10550), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2669, 3522, 0), - new Polygon( + add(new FarmingRegion("Seers' Village", 10551, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2669, 3522, 0), new Polygon( new int[]{2664, 2664, 2669, 2669}, new int[]{3523, 3528, 3528, 3523}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_4) - )); + ), NpcID.FARMING_GARDENER_HOPS_4) + ), 10550); add(new FarmingRegion("Tai Bwo Wannai", 11056, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CALQUAT, new WorldPoint(2796, 3103, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.CALQUAT, new WorldPoint(2796, 3103, 0), new Polygon( new int[]{2795, 2795, 2797, 2797}, new int[]{3100, 3102, 3102, 3100}, 4 - ), - NpcID.FARMING_GARDENER_CALQUAT) + ), NpcID.FARMING_GARDENER_CALQUAT) )); - add(new FarmingRegion("Taverley", 11573, false, Set.of(11829), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2936, 3440, 0), - new Polygon( + add(new FarmingRegion("Taverley", 11573, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(2936, 3440, 0), new Polygon( new int[]{2935, 2935, 2937, 2937}, new int[]{3437, 3439, 3439, 3437}, 4 - ), - NpcID.FARMING_GARDENER_TREE_1) - )); + ), NpcID.FARMING_GARDENER_TREE_1) + ), 11829); - add(new FarmingRegion("Tree Gnome Village", 9777, true, Set.of(10033), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2488, 3180, 0), - new Polygon( + add(new FarmingRegion("Tree Gnome Village", 9777, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.FRUIT_TREE, new WorldPoint(2488, 3180, 0), new Polygon( new int[]{2489, 2489, 2490, 2490}, new int[]{3179, 3180, 3180, 3179}, 4 - ), - NpcID.FARMING_GARDENER_FRUIT_2) - )); + ), NpcID.FARMING_GARDENER_FRUIT_2) + ), 10033); add(new FarmingRegion("Troll Stronghold", 11321, true, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2827, 3693, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2827, 3693, 0), new Polygon( new int[]{2826, 2826, 2827, 2827}, new int[]{3694, 3695, 3695, 3694}, 4 )) )); - add(new FarmingRegion("Varrock", 12854, false, Set.of(12853), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3229, 3457, 0), - new Polygon( + add(new FarmingRegion("Varrock", 12854, false, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.TREE, new WorldPoint(3229, 3457, 0), new Polygon( new int[]{3228, 3228, 3230, 3230}, new int[]{3458, 3460, 3460, 3458}, 4 - ), - NpcID.FARMING_GARDENER_TREE_3_02) - )); + ), NpcID.FARMING_GARDENER_TREE_3_02) + ), 12853); add(new FarmingRegion("Yanille", 10288, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2573, 3106, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HOPS, new WorldPoint(2573, 3106, 0), new Polygon( new int[]{2574, 2574, 2577, 2577}, new int[]{3103, 3106, 3106, 3103}, 4 - ), - NpcID.FARMING_GARDENER_HOPS_1) + ), NpcID.FARMING_GARDENER_HOPS_1) )); add(new FarmingRegion("Weiss", 11325, false, - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2849, 3933, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.HERB, new WorldPoint(2849, 3933, 0), new Polygon( new int[]{2848, 2848, 2849, 2849}, new int[]{3934, 3935, 3935, 3934}, 4 @@ -652,8 +566,7 @@ public boolean isInBounds(WorldPoint loc) )); add(new FarmingRegion("Farming Guild", 5021, true, - new FarmingPatch("Hespori", VarbitID.FARMING_TRANSMIT_J, PatchImplementation.HESPORI, new WorldPoint(1246, 10085, 0), - new Polygon( + new FarmingPatch("Hespori", VarbitID.FARMING_TRANSMIT_J, PatchImplementation.HESPORI, new WorldPoint(1246, 10085, 0), new Polygon( new int[]{1246, 1248, 1248, 1246}, new int[]{10086, 10088, 10088, 10086}, 4 @@ -661,121 +574,95 @@ public boolean isInBounds(WorldPoint loc) )); //Full 3x3 region area centered on farming guild - add(farmingGuildRegion = new FarmingRegion("Farming Guild", 4922, true, Set.of(5177, 5178, 5179, 4921, 4923, 4665, 4666, 4667), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_G, PatchImplementation.TREE, new WorldPoint(1233, 3734, 0), - new Polygon( + add(farmingGuildRegion = new FarmingRegion("Farming Guild", 4922, true, + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_G, PatchImplementation.TREE, new WorldPoint(1233, 3734, 0), new Polygon( new int[]{1231, 1231, 1233, 1233}, new int[]{3735, 3737, 3737, 3735}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T2), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.HERB, new WorldPoint(1238, 3728, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T2), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.HERB, new WorldPoint(1238, 3728, 0), new Polygon( new int[]{1238, 1238, 1239, 1239}, new int[]{3726, 3727, 3727, 3726}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.BUSH, new WorldPoint(1261, 3732, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.BUSH, new WorldPoint(1261, 3732, 0), new Polygon( new int[]{1260, 1260, 1261, 1261}, new int[]{3733, 3734, 3734, 3733}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 3), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_H, PatchImplementation.FLOWER, new WorldPoint(1261, 3727, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 3), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_H, PatchImplementation.FLOWER, new WorldPoint(1261, 3727, 0), new Polygon( new int[]{1260, 1260, 1261, 1261}, new int[]{3725, 3726, 3726, 3725}, 4 )), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3732, 0), - new Polygon( + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3732, 0), new Polygon( new int[]{1267, 1267, 1268, 1268, 1272, 1272}, new int[]{3732, 3736, 3736, 3733, 3733, 3732}, 6 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 1), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3727, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 1), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.ALLOTMENT, new WorldPoint(1266, 3727, 0), new Polygon( new int[]{1267, 1267, 1272, 1272, 1268, 1268}, new int[]{3723, 3727, 3727, 3726, 3726, 3723}, 6 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 2), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_N, PatchImplementation.BIG_COMPOST, new WorldPoint(1271, 3729, 0)), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.CACTUS, new WorldPoint(1264, 3746, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 2), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_N, PatchImplementation.BIG_COMPOST), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_F, PatchImplementation.CACTUS, new WorldPoint(1264, 3746, 0), new Polygon( new int[]{1264, 1264, 1265, 1265}, new int[]{3747, 3748, 3748, 3747}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T1, 0), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(1251, 3749, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T1, 0), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.SPIRIT_TREE, new WorldPoint(1251, 3749, 0), new Polygon( new int[]{1252, 1252, 1254, 1254}, new int[]{3749, 3751, 3751, 3749}, 4 - ), - NpcID.FARMING_GARDENER_SPIRIT_TREE_5), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_K, PatchImplementation.FRUIT_TREE, new WorldPoint(1243, 3757, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_SPIRIT_TREE_5), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_K, PatchImplementation.FRUIT_TREE, new WorldPoint(1243, 3757, 0), new Polygon( new int[]{1242, 1242, 1243, 1243}, new int[]{3758, 3759, 3758, 3758}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_T3), - new FarmingPatch("Anima", VarbitID.FARMING_TRANSMIT_M, PatchImplementation.ANIMA, new WorldPoint(1233, 3725, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_T3), + new FarmingPatch("Anima", VarbitID.FARMING_TRANSMIT_M, PatchImplementation.ANIMA, new WorldPoint(1233, 3725, 0), new Polygon( new int[]{1231, 1231, 1233, 1233}, new int[]{3722, 3724, 3724, 3722}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_L, PatchImplementation.CELASTRUS, new WorldPoint(1245, 3752, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_L, PatchImplementation.CELASTRUS, new WorldPoint(1245, 3752, 0), new Polygon( new int[]{1243, 1243, 1245, 1245}, new int[]{3749, 3751, 3751, 3749}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_CELASTRUS), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_I, PatchImplementation.REDWOOD, new WorldPoint(1233, 3752, 0), - new Polygon( + ), NpcID.FARMING_GARDENER_FARMGUILD_CELASTRUS), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_I, PatchImplementation.REDWOOD, new WorldPoint(1233, 3752, 0), new Polygon( new int[]{1225, 1225, 1232, 1232}, new int[]{3751, 3758, 3758, 3751}, 4 - ), - NpcID.FARMING_GARDENER_FARMGUILD_REDWOOD) - )); + ), NpcID.FARMING_GARDENER_FARMGUILD_REDWOOD) + ), 5177, 5178, 5179, 4921, 4923, 4665, 4666, 4667); //All of Prifddinas, and all of Prifddinas Underground - add(new FarmingRegion("Prifddinas", 13151, false, Set.of(12895, 12894, 13150, 12994, 12993, 12737, 12738, 12126, 12127, 13250), - new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3293, 6105, 0), - new Polygon( + add(new FarmingRegion("Prifddinas", 13151, false, + new FarmingPatch("North", VarbitID.FARMING_TRANSMIT_A, PatchImplementation.ALLOTMENT, new WorldPoint(3293, 6105, 0), new Polygon( new int[]{3288, 3288, 3293, 3293, 3289, 3289}, new int[]{6101, 6104, 6104, 6103, 6103, 6101}, 6 - ), - NpcID.PRIF_GARDENER, 0), - new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3294, 6096, 0), - new Polygon( + ), NpcID.PRIF_GARDENER, 0), + new FarmingPatch("South", VarbitID.FARMING_TRANSMIT_B, PatchImplementation.ALLOTMENT, new WorldPoint(3294, 6096, 0), new Polygon( new int[]{3288, 3288, 3289, 3289, 3293, 3293}, new int[]{6095, 6098, 6098, 6096, 6096, 6095}, 6 - ), - NpcID.PRIF_GARDENER, 1), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3294, 6100, 0), - new Polygon( + ), NpcID.PRIF_GARDENER, 1), + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_C, PatchImplementation.FLOWER, new WorldPoint(3294, 6100, 0), new Polygon( new int[]{3292, 3292, 3293, 3293}, new int[]{6099, 6100, 6100, 6099}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.CRYSTAL_TREE, new WorldPoint(3291, 6117, 0), - new Polygon( + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_E, PatchImplementation.CRYSTAL_TREE, new WorldPoint(3291, 6117, 0), new Polygon( new int[]{3291, 3291, 3292, 3292}, new int[]{6118, 6119, 6119, 6118}, 4 )), - new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.COMPOST, new WorldPoint(3288, 6100, 0)) - )); + new FarmingPatch("", VarbitID.FARMING_TRANSMIT_D, PatchImplementation.COMPOST) + ), 12895, 12894, 13150, + /* Underground */ 12994, 12993, 12737, 12738, 12126, 12127, 13250); // Finalize this.regions = Multimaps.unmodifiableMultimap(this.regions); @@ -787,25 +674,25 @@ public boolean isInBounds(WorldPoint loc) this.tabs = Collections.unmodifiableMap(umtabs); } - private void add(FarmingRegion r) + private void add(FarmingRegion r, int... extraRegions) { regions.put(r.getRegionID(), r); - for (int er : r.getRegionIDs()) + for (int er : extraRegions) { regions.put(er, r); } for (FarmingPatch p : r.getPatches()) { tabs - .computeIfAbsent(p.getImplementation().getTab(), k -> new TreeSet<>(tabSorter)) - .add(p); + .computeIfAbsent(p.getImplementation().getTab(), k -> new TreeSet<>(tabSorter)) + .add(p); } } Collection getRegionsForLocation(WorldPoint location) { return this.regions.get(location.getRegionID()).stream() - .filter(region -> region.isInBounds(location)) - .collect(Collectors.toSet()); + .filter(region -> region.isInBounds(location)) + .collect(Collectors.toSet()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java index cf76611eed..5351434349 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/HerbRun.java @@ -26,7 +26,6 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.config.ConfigKeys; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.TopLevelPanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; @@ -40,6 +39,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.QuestState; @@ -77,6 +77,8 @@ public class HerbRun extends ComplexStateQuestHelper // Recommended items ItemRequirement compost; + ItemRequirement enoughCompost; + ItemRequirement bottomlessBucket; ItemRequirement ectophial; ItemRequirement magicSec; ItemRequirement explorerRing2; @@ -87,7 +89,6 @@ public class HerbRun extends ComplexStateQuestHelper ItemRequirement icyBasalt; ItemRequirement stonyBasalt; ItemRequirement farmingGuildTeleport; - ItemRequirement hosidiusHouseTeleport; ItemRequirement hunterWhistle; ItemRequirement harmonyTeleport; ItemRequirement gracefulHood; @@ -109,7 +110,8 @@ public class HerbRun extends ComplexStateQuestHelper QuestRequirement accessToTrollStronghold; SkillRequirement accessToFarmingGuildPatch; QuestRequirement accessToVarlamore; - RuneliteRequirement unlockedBarbarianPlanting; + QuestRequirement accessToMorytania; + VarbitRequirement unlockedBarbarianPlanting; ManualRequirement ardougneEmpty; ManualRequirement catherbyEmpty; @@ -220,8 +222,9 @@ protected void setupRequirements() accessToWeiss = new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED); accessToTrollStronghold = new QuestRequirement(QuestHelperQuest.MY_ARMS_BIG_ADVENTURE, QuestState.FINISHED); accessToVarlamore = new QuestRequirement(QuestHelperQuest.CHILDREN_OF_THE_SUN, QuestState.FINISHED); + accessToMorytania = new QuestRequirement(QuestHelperQuest.PRIEST_IN_PERIL, QuestState.FINISHED); - unlockedBarbarianPlanting = new RuneliteRequirement(configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_SEED_PLANTING.getKey()); + unlockedBarbarianPlanting = new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, Operation.EQUAL, 3, "Unlocked Barbarian Planting"); spade = new ItemRequirement("Spade", ItemID.SPADE); dibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).hideConditioned(unlockedBarbarianPlanting); @@ -247,6 +250,10 @@ protected void setupRequirements() } compost = new ItemRequirement("Compost", ItemCollections.COMPOST); compost.setDisplayMatchedItemName(true); + + bottomlessBucket = new ItemRequirement("Bottomless Compost Bucket", ItemID.BOTTOMLESS_COMPOST_BUCKET_FILLED); + enoughCompost = new ItemRequirements(LogicType.OR, "Compost or bottomless bucket", bottomlessBucket, compost); + ectophial = new ItemRequirement("Ectophial", ItemID.ECTOPHIAL).showConditioned(new QuestRequirement(QuestHelperQuest.GHOSTS_AHOY, QuestState.FINISHED)); ectophial.addAlternates(ItemID.ECTOPHIAL_EMPTY); magicSec = new ItemRequirement("Magic secateurs", ItemID.FAIRY_ENCHANTED_SECATEURS).showConditioned(new QuestRequirement(QuestHelperQuest.FAIRYTALE_I__GROWING_PAINS, QuestState.FINISHED)); @@ -256,20 +263,19 @@ protected void setupRequirements() ardyCloak2.addAlternates(ItemID.ARDY_CAPE_HARD, ItemID.ARDY_CAPE_ELITE); xericsTalisman = new ItemRequirement("Xeric's talisman", ItemID.XERIC_TALISMAN); - hosidiusHouseTeleport = new ItemRequirement("Teleport to Hosidius House", ItemID.NZONE_TELETAB_KOUREND); - hosidiusHouseTeleport.addAlternates(ItemID.XERIC_TALISMAN); + xericsTalisman.addAlternates(ItemID.NZONE_TELETAB_KOUREND); var catherbyRunes = new ItemRequirements("Catherby teleport runes", new ItemRequirement("Law rune", ItemID.LAWRUNE), new ItemRequirement("Air rune", ItemID.AIRRUNE, 5)); var catherbyTablet = new ItemRequirement("Catherby tablet", ItemID.LUNAR_TABLET_CATHERBY_TELEPORT); - catherbyTeleport = new ItemRequirements(LogicType.OR, "Catherby teleport", catherbyRunes, catherbyTablet); + catherbyTeleport = new ItemRequirements(LogicType.OR, "Catherby teleport", catherbyTablet, catherbyRunes); var trollheimRunes = new ItemRequirements("Trollheim teleport runes", new ItemRequirement("Law rune", ItemID.LAWRUNE, 2), new ItemRequirement("Fire rune", ItemID.FIRERUNE, 2)); var trollheimTablet = new ItemRequirement("Trollheim tablet", ItemID.NZONE_TELETAB_TROLLHEIM); - trollheimTeleport = new ItemRequirements(LogicType.OR, "Trollheim teleport", trollheimRunes, trollheimTablet) - .hideConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); + trollheimTeleport = new ItemRequirements(LogicType.OR, "Trollheim teleport", trollheimTablet, trollheimRunes) + .showConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); icyBasalt = new ItemRequirement("Icy basalt", ItemID.WEISS_TELEPORT_BASALT).showConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); stonyBasalt = new ItemRequirement("Stony basalt", ItemID.STRONGHOLD_TELEPORT_BASALT).showConditioned(new QuestRequirement(QuestHelperQuest.MAKING_FRIENDS_WITH_MY_ARM, QuestState.FINISHED)); @@ -279,7 +285,7 @@ protected void setupRequirements() farmingGuildTeleport.addAlternates(ItemCollections.SKILLS_NECKLACES); farmingGuildTeleport.addAlternates(ItemCollections.FAIRY_STAFF); - harmonyTeleport = new ItemRequirement("Harmony Teleport", ItemID.TELETAB_HARMONY); + harmonyTeleport = new ItemRequirement("Harmony Teleport", ItemID.TELETAB_HARMONY).showConditioned(accessToHarmony); hunterWhistle = new ItemRequirement("Quetzal whistle", ItemID.HG_QUETZALWHISTLE_PERFECTED).showConditioned(accessToVarlamore); hunterWhistle.addAlternates(ItemID.HG_QUETZALWHISTLE_BASIC); @@ -370,7 +376,7 @@ public void setupSteps() faladorPlant.addIcon(ItemID.RANARR_SEED); faladorPatch.addSubSteps(faladorPlant); - hosidiusPlant = new ObjectStep(this, ObjectID.FARMING_HERB_PATCH_6, new WorldPoint(1738, 3550, 0), "Plant your seeds into the Hosidius patch.", hosidiusHouseTeleport); + hosidiusPlant = new ObjectStep(this, ObjectID.FARMING_HERB_PATCH_6, new WorldPoint(1738, 3550, 0), "Plant your seeds into the Hosidius patch.", xericsTalisman); hosidiusPlant.addIcon(ItemID.RANARR_SEED); hosidiusPatch.addSubSteps(hosidiusPlant); @@ -385,6 +391,7 @@ public void setupSteps() harmonyPatch.addSubSteps(harmonyPlant); morytaniaPlant = new ObjectStep(this, ObjectID.FARMING_HERB_PATCH_4, new WorldPoint(3605, 3529, 0), "Plant your seeds into the Morytania patch.", ectophial); + morytaniaPlant.conditionToHideInSidebar(new Conditions(LogicType.NOR, accessToMorytania)); morytaniaPlant.addIcon(ItemID.RANARR_SEED); morytaniaPatch.addSubSteps(morytaniaPlant); @@ -423,8 +430,8 @@ public QuestStep loadStep() steps.addStep(catherbyReady, catherbyPatch); steps.addStep(catherbyEmpty, catherbyPlant); - steps.addStep(morytaniaReady, morytaniaPatch); - steps.addStep(morytaniaEmpty, morytaniaPlant); + steps.addStep(new Conditions(accessToMorytania, morytaniaReady), morytaniaPatch); + steps.addStep(new Conditions(accessToMorytania, morytaniaEmpty), morytaniaPlant); steps.addStep(hosidiusReady, hosidiusPatch); steps.addStep(hosidiusEmpty, hosidiusPlant); @@ -566,7 +573,7 @@ public List getItemRequirements() @Override public List getItemRecommended() { - return Arrays.asList(compost, ectophial, magicSec, explorerRing2, ardyCloak2, xericsTalisman, hosidiusHouseTeleport, catherbyTeleport, + return Arrays.asList(enoughCompost, ectophial, magicSec, explorerRing2, ardyCloak2, xericsTalisman, catherbyTeleport, trollheimTeleport, icyBasalt, stonyBasalt, farmingGuildTeleport, hunterWhistle, harmonyTeleport, gracefulOutfit, farmersOutfit); } @@ -588,11 +595,11 @@ private void prepopulateSidebarPanels() new PanelDetails("Falador", Collections.singletonList(faladorPatch)).withId(1), new PanelDetails("Ardougne", Collections.singletonList(ardougnePatch)).withId(2), new PanelDetails("Catherby", Collections.singletonList(catherbyPatch)).withId(3), - new PanelDetails("Morytania", Collections.singletonList(morytaniaPatch)).withId(4), + new PanelDetails("Morytania", Collections.singletonList(morytaniaPatch)).withId(4).withHideCondition(nor(accessToMorytania)), new PanelDetails("Hosidius", Collections.singletonList(hosidiusPatch)).withId(5), - new PanelDetails("Varlamore", Collections.singletonList(varlamorePatch)).withId(6), - new PanelDetails("Troll Stronghold", Collections.singletonList(trollStrongholdPatch)).withId(7), - new PanelDetails("Weiss", Collections.singletonList(weissPatch)).withId(8), + new PanelDetails("Varlamore", Collections.singletonList(varlamorePatch)).withId(6).withHideCondition(nor(accessToVarlamore)), + new PanelDetails("Troll Stronghold", Collections.singletonList(trollStrongholdPatch)).withId(7).withHideCondition(nor(accessToTrollStronghold)), + new PanelDetails("Weiss", Collections.singletonList(weissPatch)).withId(8).withHideCondition(nor(accessToWeiss)), new PanelDetails("Harmony Island", Collections.singletonList(harmonyPatch)).withId(9).withHideCondition(nor(accessToHarmony)) ); allSteps.add(farmRunSidebar); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java index f7a1c2e1fb..226f95622f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PatchImplementation.java @@ -24,13 +24,12 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns; +import javax.annotation.Nullable; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.runelite.client.plugins.timetracking.Tab; import net.runelite.client.plugins.timetracking.farming.Produce; -import javax.annotation.Nullable; - @RequiredArgsConstructor @Getter public enum PatchImplementation @@ -1261,7 +1260,7 @@ PatchState forVarbitValue(int value) if (value == 33) { // Apple tree stump[Clear,Inspect,Guide] 7961 - return new PatchState(Produce.APPLE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.APPLE, CropState.STUMP, 0); } if (value == 34) { @@ -1291,7 +1290,7 @@ PatchState forVarbitValue(int value) if (value == 60) { // Banana tree stump[Clear,Inspect,Guide] 8019 - return new PatchState(Produce.BANANA, CropState.HARVESTABLE, 0); + return new PatchState(Produce.BANANA, CropState.STUMP, 0); } if (value == 61) { @@ -1331,7 +1330,7 @@ PatchState forVarbitValue(int value) if (value == 97) { // Orange tree stump[Clear,Inspect,Guide] 8077 - return new PatchState(Produce.ORANGE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.ORANGE, CropState.STUMP, 0); } if (value == 98) { @@ -1361,7 +1360,7 @@ PatchState forVarbitValue(int value) if (value == 124) { // Curry tree stump[Clear,Inspect,Guide] 8046 - return new PatchState(Produce.CURRY, CropState.HARVESTABLE, 0); + return new PatchState(Produce.CURRY, CropState.STUMP, 0); } if (value == 125) { @@ -1396,7 +1395,7 @@ PatchState forVarbitValue(int value) if (value == 161) { // Pineapple plant stump[Clear,Inspect,Guide] 7992 - return new PatchState(Produce.PINEAPPLE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.PINEAPPLE, CropState.STUMP, 0); } if (value == 162) { @@ -1426,7 +1425,7 @@ PatchState forVarbitValue(int value) if (value == 188) { // Papaya tree stump[Clear,Inspect,Guide] 8131 - return new PatchState(Produce.PAPAYA, CropState.HARVESTABLE, 0); + return new PatchState(Produce.PAPAYA, CropState.STUMP, 0); } if (value == 189) { @@ -1461,7 +1460,7 @@ PatchState forVarbitValue(int value) if (value == 225) { // Palm tree stump[Clear,Inspect,Guide] 8104 - return new PatchState(Produce.PALM, CropState.HARVESTABLE, 0); + return new PatchState(Produce.PALM, CropState.STUMP, 0); } if (value == 226) { @@ -1491,7 +1490,7 @@ PatchState forVarbitValue(int value) if (value == 252) { // Dragonfruit tree stump[Clear,Inspect,Guide] 34034 - return new PatchState(Produce.DRAGONFRUIT, CropState.HARVESTABLE, 0); + return new PatchState(Produce.DRAGONFRUIT, CropState.STUMP, 0); } if (value == 253) { @@ -1867,7 +1866,7 @@ PatchState forVarbitValue(int value) if (value == 14) { // Oak tree stump[Clear,Inspect,Guide] 8468 - return new PatchState(Produce.OAK, CropState.HARVESTABLE, 0); + return new PatchState(Produce.OAK, CropState.STUMP, 0); } if (value >= 15 && value <= 20) { @@ -1887,7 +1886,7 @@ PatchState forVarbitValue(int value) if (value == 23) { // Willow tree stump[Clear,Inspect,Guide] 8489 - return new PatchState(Produce.WILLOW, CropState.HARVESTABLE, 0); + return new PatchState(Produce.WILLOW, CropState.STUMP, 0); } if (value >= 24 && value <= 31) { @@ -1907,7 +1906,7 @@ PatchState forVarbitValue(int value) if (value == 34) { // Tree stump[Clear,Inspect,Guide] 8445 - return new PatchState(Produce.MAPLE, CropState.HARVESTABLE, 0); + return new PatchState(Produce.MAPLE, CropState.STUMP, 0); } if (value >= 35 && value <= 44) { @@ -1927,7 +1926,7 @@ PatchState forVarbitValue(int value) if (value == 47) { // Yew tree stump[Clear,Inspect,Guide] 8514 - return new PatchState(Produce.YEW, CropState.HARVESTABLE, 0); + return new PatchState(Produce.YEW, CropState.STUMP, 0); } if (value >= 48 && value <= 59) { @@ -1947,7 +1946,7 @@ PatchState forVarbitValue(int value) if (value == 62) { // Magic Tree Stump[Clear,Inspect,Guide] 8410 - return new PatchState(Produce.MAGIC, CropState.HARVESTABLE, 0); + return new PatchState(Produce.MAGIC, CropState.STUMP, 0); } if (value >= 63 && value <= 72) { @@ -2150,7 +2149,7 @@ PatchState forVarbitValue(int value) if (value == 17) { // Tree stump[Clear,Inspect,Guide] 30446 - return new PatchState(Produce.TEAK, CropState.HARVESTABLE, 0); + return new PatchState(Produce.TEAK, CropState.STUMP, 0); } if (value >= 18 && value <= 23) { @@ -2180,7 +2179,7 @@ PatchState forVarbitValue(int value) if (value == 40) { // Mahogany tree stump[Clear,Inspect,Guide] 30418 - return new PatchState(Produce.MAHOGANY, CropState.HARVESTABLE, 0); + return new PatchState(Produce.MAHOGANY, CropState.STUMP, 0); } if (value >= 41 && value <= 47) { @@ -2210,7 +2209,7 @@ PatchState forVarbitValue(int value) if (value == 65) { // Camphor tree stump[Clear,Inspect,Guide] 58724 - return new PatchState(Produce.CAMPHOR, CropState.HARVESTABLE, 0); + return new PatchState(Produce.CAMPHOR, CropState.STUMP, 0); } if (value >= 66 && value <= 72) { @@ -2240,7 +2239,7 @@ PatchState forVarbitValue(int value) if (value == 90) { // Ironwood tree stump[Clear,Inspect,Guide] 58755 - return new PatchState(Produce.IRONWOOD, CropState.HARVESTABLE, 0); + return new PatchState(Produce.IRONWOOD, CropState.STUMP, 0); } if (value >= 91 && value <= 97) { @@ -2270,7 +2269,7 @@ PatchState forVarbitValue(int value) if (value == 116) { // Rosewood tree stump[Clear,Inspect,Guide] 58786 - return new PatchState(Produce.ROSEWOOD, CropState.HARVESTABLE, 0); + return new PatchState(Produce.ROSEWOOD, CropState.STUMP, 0); } if (value >= 117 && value <= 124) { @@ -2751,7 +2750,7 @@ PatchState forVarbitValue(int value) if (value == 28) { // Celastrus tree stump[Clear,Inspect,Guide] 33721 - return new PatchState(Produce.CELASTRUS, CropState.HARVESTABLE, 0); + return new PatchState(Produce.CELASTRUS, CropState.STUMP, 0); } if (value >= 29 && value <= 255) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java index e60d07530c..f3086e0569 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/PaymentTracker.java @@ -24,15 +24,14 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns; +import javax.inject.Inject; +import javax.inject.Singleton; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.runelite.client.config.ConfigManager; import net.runelite.client.plugins.timetracking.TimeTrackingConfig; -import javax.inject.Inject; -import javax.inject.Singleton; - @Slf4j @RequiredArgsConstructor( access = AccessLevel.PRIVATE, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java index be0e8318a0..0fd0dcbaee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/farmruns/TreeRun.java @@ -28,7 +28,13 @@ import com.google.inject.Inject; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; -import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.*; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.FruitTreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.GracefulOrFarming; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.HardwoodTreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.TreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.CalquatTreeSapling; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.PayOrCut; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.FarmingUtils.PayOrCompost; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.TopLevelPanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.ComplexStateQuestHelper; @@ -46,6 +52,8 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.client.plugins.microbot.questhelper.steps.widget.LunarSpells; import net.runelite.client.plugins.microbot.questhelper.steps.widget.NormalSpells; +import java.util.Set; + import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; import net.runelite.api.QuestState; import net.runelite.api.Skill; @@ -56,11 +64,9 @@ import net.runelite.client.events.ConfigChanged; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.timetracking.Tab; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Set; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; @@ -71,6 +77,8 @@ * */ public class TreeRun extends ComplexStateQuestHelper { + private static final String TREE_PROTECTION_DIALOG = "Would you look after my crops for me?"; + @Inject private FarmingWorld farmingWorld; @@ -88,6 +96,9 @@ public class TreeRun extends ComplexStateQuestHelper DetailedQuestStep farmingGuildTreePatchCheckHealth, lumbridgeTreePatchCheckHealth, faladorTreePatchCheckHealth, taverleyTreePatchCheckHealth, varrockTreePatchCheckHealth, gnomeStrongholdTreePatchCheckHealth, auburnvaleTreePatchCheckHealth; + DetailedQuestStep farmingGuildTreePatchCutDown, lumbridgeTreePatchCutDown, faladorTreePatchCutDown, + taverleyTreePatchCutDown, varrockTreePatchCutDown, gnomeStrongholdTreePatchCutDown, + auburnvaleTreePatchCutDown; DetailedQuestStep farmingGuildTreePatchPlant, lumbridgeTreePatchPlant, faladorTreePatchPlant, taverleyTreePatchPlant, varrockTreePatchPlant, gnomeStrongholdTreePatchPlant, auburnvaleTreePatchPlant; @@ -118,6 +129,10 @@ public class TreeRun extends ComplexStateQuestHelper DetailedQuestStep farmingGuildFruitTreePatchDig, gnomeStrongholdFruitTreePatchDig, gnomeVillageFruitTreePatchDig, brimhavenFruitTreePatchDig, lletyaFruitTreePatchDig, catherbyFruitTreePatchDig, taiBwoWannaiCalquatPatchDig, kastoriFruitTreePatchDig, kastoriCalquatPatchDig, greatConchCalquatPatchDig; + DetailedQuestStep farmingGuildFruitTreePatchCutDown, gnomeStrongholdFruitTreePatchCutDown, gnomeVillageFruitTreePatchCutDown, + brimhavenFruitTreePatchCutDown, lletyaFruitTreePatchCutDown, catherbyFruitTreePatchCutDown, + kastoriFruitTreePatchCutDown; + DetailedQuestStep taiBwoWannaiCalquatPatchRemove, kastoriCalquatPatchRemove, greatConchCalquatPatchRemove; DetailedQuestStep guildFruitProtect, strongholdFruitProtect, villageFruitProtect, brimhavenFruitProtect, lletyaFruitProtect, catherbyFruitProtect, taiBwoWannaiCalquatProtect, kastoriFruitProtect, @@ -133,6 +148,8 @@ public class TreeRun extends ComplexStateQuestHelper DetailedQuestStep eastHardwoodTreePatchClear, westHardwoodTreePatchClear, middleHardwoodTreePatchClear, savannahClear, anglersClear; + DetailedQuestStep eastHardwoodTreePatchCutDown, westHardwoodTreePatchCutDown, middleHardwoodTreePatchCutDown, + savannahCutDown, anglersCutDown; DetailedQuestStep eastHardwoodProtect, westHardwoodProtect, middleHardwoodProtect, savannahProtect, anglersProtect; @@ -165,15 +182,17 @@ public class TreeRun extends ComplexStateQuestHelper gnomeStrongholdTreeStates, auburnvaleStates; PatchStates gnomeStrongholdFruitStates, gnomeVillageStates, brimhavenStates, catherbyStates, lletyaStates, - farmingGuildFruitStates, taiBwoWannaiStates, kastoriStates, greatConchStates; + farmingGuildFruitStates, taiBwoWannaiStates, kastoriFruitStates, kastoriCalquatStates, greatConchStates; PatchStates eastHardwoodStates, middleHardwoodStates, westHardwoodStates, savannahStates, anglersRetreatStates; Requirement allGrowing; - ConditionalStep farmingGuildStep, lumbridgeStep, varrockStep, faladorStep, taverleyStep, strongholdStep, - villageStep, lletyaStep, catherbyStep, brimhavenStep, fossilIslandStep, savannahStep, auburnvaleStep, - kastoriStep, anglersRetreatStep, greatConchStep; + ReorderableConditionalStep farmingGuildStep, strongholdStep, karamjaStep, fossilIslandStep, kastoriStep; + ConditionalStep farmingGuildTreeStep, farmingGuildFruitStep, lumbridgeStep, varrockStep, faladorStep, taverleyStep, + strongholdTreeStep, strongholdFruitStep, villageStep, lletyaStep, catherbyStep, brimhavenStep, + taiBwoWannaiStep, fossilIslandEastStep, fossilIslandMiddleStep, fossilIslandWestStep, savannahStep, + auburnvaleStep, kastoriFruitStep, kastoriCalquatStep, anglersRetreatStep, greatConchStep; private final String PAY_OR_CUT = "payOrCutTree"; private final String PAY_OR_COMPOST = "payOrCompostTree"; @@ -193,194 +212,216 @@ public QuestStep loadStep() // Varrock -> Gnome Stronghold Fruit -> Gnome Stronghold Tree -> Gnome Village -> catherby // -> Brimhaven -> lletya -> east hardwood -> middle hardwood -> west hardwood. - farmingGuildStep = new ConditionalStep(this, farmingGuildTreePatchCheckHealth); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsUnchecked(), farmingGuildTreePatchCheckHealth); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsHarvestable(), farmingGuildTreePatchClear); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsStump(), farmingGuildTreePatchDig); - farmingGuildStep.addStep(farmingGuildTreeStates.getIsEmpty(), farmingGuildTreePatchPlant); - farmingGuildStep.addStep(nor(farmingGuildTreeStates.getIsProtected(), usingCompostorNothing), farmingGuildTreePayForProtection); - - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsUnchecked()), farmingGuildFruitTreePatchCheckHealth); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsHarvestable()), farmingGuildFruitTreePatchClear); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsStump()), farmingGuildFruitTreePatchDig); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsEmpty()), farmingGuildFruitTreePatchPlant); - farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, nor(farmingGuildFruitStates.getIsProtected(), usingCompostorNothing)), guildFruitProtect); - - steps.addStep(and(accessToFarmingGuildTreePatch, nand(farmingGuildTreeStates.getIsGrowing(), - farmingGuildFruitStates.getIsGrowing())), farmingGuildStep.withId(0)); + farmingGuildTreeStep = (ConditionalStep) new ConditionalStep(this, farmingGuildTreePatchCheckHealth).withId(-1); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsUnchecked(), farmingGuildTreePatchCheckHealth); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsStump(), farmingGuildTreePatchDig); + farmingGuildTreeStep.addStep(and(farmingGuildTreeStates.getIsHarvestable(), not(payingForRemoval)), farmingGuildTreePatchCutDown); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsHarvestable(), farmingGuildTreePatchClear); + farmingGuildTreeStep.addStep(farmingGuildTreeStates.getIsEmpty(), farmingGuildTreePatchPlant); + farmingGuildTreeStep.addStep(nor(farmingGuildTreeStates.getIsProtected(), usingCompostorNothing), farmingGuildTreePayForProtection); + + // TODO: Ideally we should allow for null steps to be rejected and propagate up conditionalstep chains + farmingGuildStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + farmingGuildStep.addStep(not(farmingGuildTreeStates.getIsGrowing()), farmingGuildTreeStep); + + farmingGuildFruitStep = (ConditionalStep) new ConditionalStep(this, farmingGuildFruitTreePatchCheckHealth).withId(-2); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsUnchecked()), farmingGuildFruitTreePatchCheckHealth); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsHarvestable(), not(payingForRemoval)), farmingGuildFruitTreePatchCutDown); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsHarvestable()), farmingGuildFruitTreePatchClear); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsStump()), farmingGuildFruitTreePatchDig); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, farmingGuildFruitStates.getIsEmpty()), farmingGuildFruitTreePatchPlant); + farmingGuildFruitStep.addStep(and(accessToFarmingGuildFruitTreePatch, nor(farmingGuildFruitStates.getIsProtected(), usingCompostorNothing)), guildFruitProtect); + farmingGuildStep.addStep(and(accessToFarmingGuildFruitTreePatch, not(farmingGuildFruitStates.getIsGrowing())), farmingGuildFruitStep); + steps.addStep(or(and(accessToFarmingGuildTreePatch, not(farmingGuildTreeStates.getIsGrowing())), and(accessToFarmingGuildFruitTreePatch, not(farmingGuildFruitStates.getIsGrowing()))), farmingGuildStep.withId(0)); lumbridgeStep = new ConditionalStep(this, lumbridgeTreePatchCheckHealth); lumbridgeStep.addStep(lumbridgeStates.getIsUnchecked(), lumbridgeTreePatchCheckHealth); + lumbridgeStep.addStep(and(lumbridgeStates.getIsHarvestable(), not(payingForRemoval)), lumbridgeTreePatchCutDown); lumbridgeStep.addStep(lumbridgeStates.getIsEmpty(), lumbridgeTreePatchPlant); lumbridgeStep.addStep(lumbridgeStates.getIsHarvestable(), lumbridgeTreePatchClear); lumbridgeStep.addStep(lumbridgeStates.getIsStump(), lumbridgeTreePatchDig); lumbridgeStep.addStep(nor(usingCompostorNothing, lumbridgeStates.getIsProtected()), lumbridgeTreeProtect); - - steps.addStep(nor(lumbridgeStates.getIsGrowing()), lumbridgeStep.withId(1)); + steps.addStep(not(lumbridgeStates.getIsGrowing()), lumbridgeStep.withId(1)); faladorStep = new ConditionalStep(this, faladorTreePatchCheckHealth); faladorStep.addStep(faladorStates.getIsUnchecked(), faladorTreePatchCheckHealth); + faladorStep.addStep(and(faladorStates.getIsHarvestable(), not(payingForRemoval)), faladorTreePatchCutDown); faladorStep.addStep(faladorStates.getIsEmpty(), faladorTreePatchPlant); faladorStep.addStep(faladorStates.getIsHarvestable(), faladorTreePatchClear); faladorStep.addStep(faladorStates.getIsStump(), faladorTreePatchDig); faladorStep.addStep(nor(usingCompostorNothing, faladorStates.getIsProtected()), faladorTreeProtect); - - steps.addStep(nor(faladorStates.getIsGrowing()), faladorStep.withId(2)); + steps.addStep(not(faladorStates.getIsGrowing()), faladorStep.withId(2)); taverleyStep = new ConditionalStep(this, taverleyTreePatchCheckHealth); taverleyStep.addStep(taverleyStates.getIsUnchecked(), taverleyTreePatchCheckHealth); + taverleyStep.addStep(and(taverleyStates.getIsHarvestable(), not(payingForRemoval)), taverleyTreePatchCutDown); taverleyStep.addStep(taverleyStates.getIsEmpty(), taverleyTreePatchPlant); taverleyStep.addStep(taverleyStates.getIsHarvestable(), taverleyTreePatchClear); taverleyStep.addStep(taverleyStates.getIsStump(), taverleyTreePatchDig); taverleyStep.addStep(nor(usingCompostorNothing, taverleyStates.getIsProtected()), taverleyTreeProtect); - - steps.addStep(nor(taverleyStates.getIsGrowing()), taverleyStep.withId(3)); + steps.addStep(not(taverleyStates.getIsGrowing()), taverleyStep.withId(3)); varrockStep = new ConditionalStep(this, varrockTreePatchCheckHealth); varrockStep.addStep(varrockStates.getIsUnchecked(), varrockTreePatchCheckHealth); + varrockStep.addStep(and(varrockStates.getIsHarvestable(), not(payingForRemoval)), varrockTreePatchCutDown); varrockStep.addStep(varrockStates.getIsEmpty(), varrockTreePatchPlant); varrockStep.addStep(varrockStates.getIsHarvestable(), varrockTreePatchClear); varrockStep.addStep(varrockStates.getIsStump(), varrockTreePatchDig); varrockStep.addStep(nor(usingCompostorNothing, varrockStates.getIsProtected()), varrockTreeProtect); - - steps.addStep(nor(varrockStates.getIsGrowing()), varrockStep.withId(4)); - - strongholdStep = new ConditionalStep(this, gnomeStrongholdFruitTreePatchCheckHealth); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsUnchecked(), gnomeStrongholdFruitTreePatchCheckHealth); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsEmpty(), gnomeStrongholdFruitTreePatchPlant); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsHarvestable(), gnomeStrongholdFruitTreePatchClear); - strongholdStep.addStep(gnomeStrongholdFruitStates.getIsStump(), gnomeStrongholdFruitTreePatchDig); - strongholdStep.addStep(nor(usingCompostorNothing, gnomeStrongholdFruitStates.getIsProtected()), strongholdFruitProtect); - - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsUnchecked(), gnomeStrongholdTreePatchCheckHealth); - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsEmpty(), gnomeStrongholdTreePatchPlant); - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsHarvestable(), gnomeStrongholdTreePatchClear); - strongholdStep.addStep(gnomeStrongholdTreeStates.getIsStump(), gnomeStrongholdTreePatchDig); - strongholdStep.addStep(nor(usingCompostorNothing, gnomeStrongholdTreeStates.getIsProtected()), strongholdTreeProtect); - - steps.addStep(nand(gnomeStrongholdTreeStates.getIsGrowing(), - gnomeStrongholdFruitStates.getIsGrowing()), strongholdStep.withId(5)); + steps.addStep(not(varrockStates.getIsGrowing()), varrockStep.withId(4)); + + strongholdFruitStep = (ConditionalStep) new ConditionalStep(this, gnomeStrongholdFruitTreePatchCheckHealth).withId(51); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsUnchecked(), gnomeStrongholdFruitTreePatchCheckHealth); + strongholdFruitStep.addStep(and(gnomeStrongholdFruitStates.getIsHarvestable(), not(payingForRemoval)), gnomeStrongholdFruitTreePatchCutDown); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsEmpty(), gnomeStrongholdFruitTreePatchPlant); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsHarvestable(), gnomeStrongholdFruitTreePatchClear); + strongholdFruitStep.addStep(gnomeStrongholdFruitStates.getIsStump(), gnomeStrongholdFruitTreePatchDig); + strongholdFruitStep.addStep(nor(usingCompostorNothing, gnomeStrongholdFruitStates.getIsProtected()), strongholdFruitProtect); + strongholdStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + strongholdStep.addStep(not(gnomeStrongholdFruitStates.getIsGrowing()), strongholdFruitStep); + strongholdTreeStep = (ConditionalStep) new ConditionalStep(this, gnomeStrongholdTreePatchCheckHealth).withId(52); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsUnchecked(), gnomeStrongholdTreePatchCheckHealth); + strongholdTreeStep.addStep(and(gnomeStrongholdTreeStates.getIsHarvestable(), not(payingForRemoval)), gnomeStrongholdTreePatchCutDown); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsEmpty(), gnomeStrongholdTreePatchPlant); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsHarvestable(), gnomeStrongholdTreePatchClear); + strongholdTreeStep.addStep(gnomeStrongholdTreeStates.getIsStump(), gnomeStrongholdTreePatchDig); + strongholdTreeStep.addStep(nor(usingCompostorNothing, gnomeStrongholdTreeStates.getIsProtected()), strongholdTreeProtect); + strongholdStep.addStep(not(gnomeStrongholdTreeStates.getIsGrowing()), strongholdTreeStep); + steps.addStep(nand(gnomeStrongholdFruitStates.getIsGrowing(), gnomeStrongholdTreeStates.getIsGrowing()), strongholdStep.withId(5)); villageStep = new ConditionalStep(this, gnomeVillageFruitTreePatchCheckHealth); villageStep.addStep(gnomeVillageStates.getIsUnchecked(), gnomeVillageFruitTreePatchCheckHealth); + villageStep.addStep(and(gnomeVillageStates.getIsHarvestable(), not(payingForRemoval)), gnomeVillageFruitTreePatchCutDown); villageStep.addStep(gnomeVillageStates.getIsEmpty(), gnomeVillageFruitTreePatchPlant); villageStep.addStep(gnomeVillageStates.getIsHarvestable(), gnomeVillageFruitTreePatchClear); villageStep.addStep(gnomeVillageStates.getIsStump(), gnomeVillageFruitTreePatchDig); villageStep.addStep(nor(usingCompostorNothing, gnomeVillageStates.getIsProtected()), villageFruitProtect); - - steps.addStep(nor(gnomeVillageStates.getIsGrowing()), villageStep.withId(6)); + steps.addStep(not(gnomeVillageStates.getIsGrowing()), villageStep.withId(6)); catherbyStep = new ConditionalStep(this, catherbyFruitTreePatchCheckHealth); catherbyStep.addStep(catherbyStates.getIsUnchecked(), catherbyFruitTreePatchCheckHealth); + catherbyStep.addStep(and(catherbyStates.getIsHarvestable(), not(payingForRemoval)), catherbyFruitTreePatchCutDown); catherbyStep.addStep(catherbyStates.getIsEmpty(), catherbyFruitTreePatchPlant); catherbyStep.addStep(catherbyStates.getIsHarvestable(), catherbyFruitTreePatchClear); catherbyStep.addStep(catherbyStates.getIsStump(), catherbyFruitTreePatchDig); catherbyStep.addStep(nor(usingCompostorNothing, catherbyStates.getIsProtected()), catherbyFruitProtect); + steps.addStep(not(catherbyStates.getIsGrowing()), catherbyStep.withId(7)); - steps.addStep(nor(catherbyStates.getIsGrowing()), catherbyStep.withId(7)); - - brimhavenStep = new ConditionalStep(this, brimhavenFruitTreePatchCheckHealth); + brimhavenStep = (ConditionalStep) new ConditionalStep(this, brimhavenFruitTreePatchCheckHealth).withId(81); brimhavenStep.addStep(brimhavenStates.getIsUnchecked(), brimhavenFruitTreePatchCheckHealth); + brimhavenStep.addStep(and(brimhavenStates.getIsHarvestable(), not(payingForRemoval)), brimhavenFruitTreePatchCutDown); brimhavenStep.addStep(brimhavenStates.getIsEmpty(), brimhavenFruitTreePatchPlant); brimhavenStep.addStep(brimhavenStates.getIsHarvestable(), brimhavenFruitTreePatchClear); brimhavenStep.addStep(brimhavenStates.getIsStump(), brimhavenFruitTreePatchDig); brimhavenStep.addStep(nor(usingCompostorNothing, brimhavenStates.getIsProtected()), brimhavenFruitProtect); - brimhavenStep.addStep(taiBwoWannaiStates.getIsUnchecked(), taiBwoWannaiCalquatPatchCheckHealth); - brimhavenStep.addStep(taiBwoWannaiStates.getIsEmpty(), taiBwoWannaiCalquatPatchPlant); - brimhavenStep.addStep(taiBwoWannaiStates.getIsHarvestable(), taiBwoWannaiCalquatPatchClear); - brimhavenStep.addStep(taiBwoWannaiStates.getIsStump(), taiBwoWannaiCalquatPatchDig); - brimhavenStep.addStep(nor(usingCompostorNothing, taiBwoWannaiStates.getIsProtected()), + karamjaStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + karamjaStep.addStep(not(brimhavenStates.getIsGrowing()), brimhavenStep); + + taiBwoWannaiStep = (ConditionalStep) new ConditionalStep(this, taiBwoWannaiCalquatPatchCheckHealth).withId(82); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsUnchecked(), taiBwoWannaiCalquatPatchCheckHealth); + taiBwoWannaiStep.addStep(and(taiBwoWannaiStates.getIsHarvestable(), not(payingForRemoval)), taiBwoWannaiCalquatPatchRemove); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsEmpty(), taiBwoWannaiCalquatPatchPlant); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsHarvestable(), taiBwoWannaiCalquatPatchClear); + taiBwoWannaiStep.addStep(taiBwoWannaiStates.getIsStump(), taiBwoWannaiCalquatPatchDig); + taiBwoWannaiStep.addStep(nor(usingCompostorNothing, taiBwoWannaiStates.getIsProtected()), taiBwoWannaiCalquatProtect); - - steps.addStep(nand(brimhavenStates.getIsGrowing(), taiBwoWannaiStates.getIsGrowing()), brimhavenStep.withId(8)); + karamjaStep.addStep(not(taiBwoWannaiStates.getIsGrowing()), taiBwoWannaiStep); + steps.addStep(nand(brimhavenStates.getIsGrowing(), taiBwoWannaiStates.getIsGrowing()), karamjaStep.withId(8)); lletyaStep = new ConditionalStep(this, lletyaFruitTreePatchCheckHealth); lletyaStep.addStep(lletyaStates.getIsUnchecked(), lletyaFruitTreePatchCheckHealth); + lletyaStep.addStep(and(lletyaStates.getIsHarvestable(), not(payingForRemoval)), lletyaFruitTreePatchCutDown); lletyaStep.addStep(lletyaStates.getIsEmpty(), lletyaFruitTreePatchPlant); lletyaStep.addStep(lletyaStates.getIsHarvestable(), lletyaFruitTreePatchClear); lletyaStep.addStep(lletyaStates.getIsStump(), lletyaFruitTreePatchDig); lletyaStep.addStep(nor(usingCompostorNothing, lletyaStates.getIsProtected()), lletyaFruitProtect); - - steps.addStep(and(accessToLletya, nor(lletyaStates.getIsGrowing())), lletyaStep.withId(9)); - - fossilIslandStep = new ConditionalStep(this, eastHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(eastHardwoodStates.getIsUnchecked(), eastHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(eastHardwoodStates.getIsEmpty(), eastHardwoodTreePatchPlant); - fossilIslandStep.addStep(eastHardwoodStates.getIsHarvestable(), eastHardwoodTreePatchClear); - fossilIslandStep.addStep(eastHardwoodStates.getIsStump(), eastHardwoodTreePatchDig); - fossilIslandStep.addStep(nor(usingCompostorNothing, eastHardwoodStates.getIsProtected()), eastHardwoodProtect); - - fossilIslandStep.addStep(middleHardwoodStates.getIsUnchecked(), middleHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(middleHardwoodStates.getIsEmpty(), middleHardwoodTreePatchPlant); - fossilIslandStep.addStep(middleHardwoodStates.getIsHarvestable(), middleHardwoodTreePatchClear); - fossilIslandStep.addStep(middleHardwoodStates.getIsStump(), middleHardwoodTreePatchDig); - fossilIslandStep.addStep(nor(usingCompostorNothing, middleHardwoodStates.getIsProtected()), middleHardwoodProtect); - - fossilIslandStep.addStep(westHardwoodStates.getIsUnchecked(), westHardwoodTreePatchCheckHealth); - fossilIslandStep.addStep(westHardwoodStates.getIsEmpty(), westHardwoodTreePatchPlant); - fossilIslandStep.addStep(westHardwoodStates.getIsHarvestable(), westHardwoodTreePatchClear); - fossilIslandStep.addStep(westHardwoodStates.getIsStump(), westHardwoodTreePatchDig); - fossilIslandStep.addStep(nor(usingCompostorNothing, westHardwoodStates.getIsProtected()), westHardwoodProtect); - - steps.addStep(and(accessToFossilIsland, - nand(eastHardwoodStates.getIsGrowing(), westHardwoodStates.getIsGrowing(), middleHardwoodStates.getIsGrowing())), - fossilIslandStep.withId(10)); + steps.addStep(and(accessToLletya, not(lletyaStates.getIsGrowing())), lletyaStep.withId(9)); + + fossilIslandEastStep = (ConditionalStep) new ConditionalStep(this, eastHardwoodTreePatchCheckHealth).withId(101); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsUnchecked(), eastHardwoodTreePatchCheckHealth); + fossilIslandEastStep.addStep(and(eastHardwoodStates.getIsHarvestable(), not(payingForRemoval)), eastHardwoodTreePatchCutDown); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsEmpty(), eastHardwoodTreePatchPlant); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsHarvestable(), eastHardwoodTreePatchClear); + fossilIslandEastStep.addStep(eastHardwoodStates.getIsStump(), eastHardwoodTreePatchDig); + fossilIslandEastStep.addStep(nor(usingCompostorNothing, eastHardwoodStates.getIsProtected()), eastHardwoodProtect); + fossilIslandStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + fossilIslandStep.addStep(not(eastHardwoodStates.getIsGrowing()), fossilIslandEastStep); + fossilIslandMiddleStep = (ConditionalStep) new ConditionalStep(this, middleHardwoodTreePatchCheckHealth).withId(102); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsUnchecked(), middleHardwoodTreePatchCheckHealth); + fossilIslandMiddleStep.addStep(and(middleHardwoodStates.getIsHarvestable(), not(payingForRemoval)), middleHardwoodTreePatchCutDown); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsEmpty(), middleHardwoodTreePatchPlant); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsHarvestable(), middleHardwoodTreePatchClear); + fossilIslandMiddleStep.addStep(middleHardwoodStates.getIsStump(), middleHardwoodTreePatchDig); + fossilIslandMiddleStep.addStep(nor(usingCompostorNothing, middleHardwoodStates.getIsProtected()), middleHardwoodProtect); + fossilIslandStep.addStep(not(middleHardwoodStates.getIsGrowing()), fossilIslandMiddleStep); + + fossilIslandWestStep = (ConditionalStep) new ConditionalStep(this, westHardwoodTreePatchCheckHealth).withId(103); + fossilIslandWestStep.addStep(westHardwoodStates.getIsUnchecked(), westHardwoodTreePatchCheckHealth); + fossilIslandWestStep.addStep(and(westHardwoodStates.getIsHarvestable(), not(payingForRemoval)), westHardwoodTreePatchCutDown); + fossilIslandWestStep.addStep(westHardwoodStates.getIsEmpty(), westHardwoodTreePatchPlant); + fossilIslandWestStep.addStep(westHardwoodStates.getIsHarvestable(), westHardwoodTreePatchClear); + fossilIslandWestStep.addStep(westHardwoodStates.getIsStump(), westHardwoodTreePatchDig); + fossilIslandWestStep.addStep(nor(usingCompostorNothing, westHardwoodStates.getIsProtected()), westHardwoodProtect); + fossilIslandStep.addStep(not(westHardwoodStates.getIsGrowing()), fossilIslandWestStep); + steps.addStep(and(accessToFossilIsland, nand(eastHardwoodStates.getIsGrowing(), middleHardwoodStates.getIsGrowing(), westHardwoodStates.getIsGrowing())), fossilIslandStep.withId(10)); savannahStep = new ConditionalStep(this, savannahCheckHealth); savannahStep.addStep(savannahStates.getIsUnchecked(), savannahCheckHealth); + savannahStep.addStep(and(savannahStates.getIsHarvestable(), not(payingForRemoval)), savannahCutDown); savannahStep.addStep(savannahStates.getIsEmpty(), savannahPlant); savannahStep.addStep(savannahStates.getIsHarvestable(), savannahClear); savannahStep.addStep(savannahStates.getIsStump(), savannahDig); savannahStep.addStep(nor(usingCompostorNothing, savannahStates.getIsProtected()), savannahProtect); - - steps.addStep(and(accessToSavannah, nor(savannahStates.getIsGrowing())), savannahStep.withId(11)); + steps.addStep(and(accessToSavannah, not(savannahStates.getIsGrowing())), savannahStep.withId(11)); auburnvaleStep = new ConditionalStep(this, auburnvaleTreePatchCheckHealth); auburnvaleStep.addStep(auburnvaleStates.getIsUnchecked(), auburnvaleTreePatchCheckHealth); + auburnvaleStep.addStep(and(auburnvaleStates.getIsHarvestable(), not(payingForRemoval)), auburnvaleTreePatchCutDown); auburnvaleStep.addStep(auburnvaleStates.getIsEmpty(), auburnvaleTreePatchPlant); auburnvaleStep.addStep(auburnvaleStates.getIsHarvestable(), auburnvaleTreePatchClear); auburnvaleStep.addStep(auburnvaleStates.getIsStump(), auburnvaleTreePatchDig); auburnvaleStep.addStep(nor(usingCompostorNothing, auburnvaleStates.getIsProtected()), auburnvaleTreeProtect); - - steps.addStep(and(accessToVarlamore, nor(auburnvaleStates.getIsGrowing())), auburnvaleStep.withId(12)); - - - //kastoriStep, anglersRetreatStep, greatConchStep; - - kastoriStep = new ConditionalStep(this, kastoriFruitTreePatchCheckHealth); - kastoriStep.addStep(kastoriStates.getIsUnchecked(), kastoriFruitTreePatchCheckHealth); - kastoriStep.addStep(kastoriStates.getIsEmpty(), kastoriFruitTreePatchPlant); - kastoriStep.addStep(kastoriStates.getIsHarvestable(), kastoriFruitTreePatchClear); - kastoriStep.addStep(kastoriStates.getIsStump(), kastoriFruitTreePatchDig); - kastoriStep.addStep(nor(usingCompostorNothing, kastoriStates.getIsProtected()), kastoriFruitProtect); - - kastoriStep.addStep(kastoriStates.getIsUnchecked(), kastoriCalquatPatchCheckHealth); - kastoriStep.addStep(kastoriStates.getIsEmpty(), kastoriCalquatPatchPlant); - kastoriStep.addStep(kastoriStates.getIsHarvestable(), kastoriCalquatPatchClear); - kastoriStep.addStep(kastoriStates.getIsStump(), kastoriCalquatPatchDig); - kastoriStep.addStep(nor(usingCompostorNothing, kastoriStates.getIsProtected()), kastoriCalquatProtect); - - steps.addStep(and(accessToVarlamore, nand(kastoriStates.getIsGrowing(), kastoriStates.getIsGrowing())), kastoriStep.withId(13)); + steps.addStep(and(accessToVarlamore, not(auburnvaleStates.getIsGrowing())), auburnvaleStep.withId(12)); + + kastoriFruitStep = (ConditionalStep) new ConditionalStep(this, kastoriFruitTreePatchCheckHealth).withId(131); + kastoriFruitStep.addStep(kastoriFruitStates.getIsUnchecked(), kastoriFruitTreePatchCheckHealth); + kastoriFruitStep.addStep(and(kastoriFruitStates.getIsHarvestable(), not(payingForRemoval)), kastoriFruitTreePatchCutDown); + kastoriFruitStep.addStep(kastoriFruitStates.getIsEmpty(), kastoriFruitTreePatchPlant); + kastoriFruitStep.addStep(kastoriFruitStates.getIsHarvestable(), kastoriFruitTreePatchClear); + kastoriFruitStep.addStep(kastoriFruitStates.getIsStump(), kastoriFruitTreePatchDig); + kastoriFruitStep.addStep(nor(usingCompostorNothing, kastoriFruitStates.getIsProtected()), kastoriFruitProtect); + + kastoriCalquatStep = (ConditionalStep) new ConditionalStep(this, kastoriCalquatPatchCheckHealth).withId(132); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsUnchecked(), kastoriCalquatPatchCheckHealth); + kastoriCalquatStep.addStep(and(kastoriCalquatStates.getIsHarvestable(), not(payingForRemoval)), kastoriCalquatPatchRemove); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsEmpty(), kastoriCalquatPatchPlant); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsHarvestable(), kastoriCalquatPatchClear); + kastoriCalquatStep.addStep(kastoriCalquatStates.getIsStump(), kastoriCalquatPatchDig); + kastoriCalquatStep.addStep(nor(usingCompostorNothing, kastoriCalquatStates.getIsProtected()), kastoriCalquatProtect); + + + kastoriStep = new ReorderableConditionalStep(this, new DetailedQuestStep(this, "Unreachable.")); + kastoriStep.addStep(not(kastoriFruitStates.getIsGrowing()), kastoriFruitStep); + kastoriStep.addStep(not(kastoriCalquatStates.getIsGrowing()), kastoriCalquatStep); + steps.addStep(and(accessToVarlamore, nand(kastoriFruitStates.getIsGrowing(), kastoriCalquatStates.getIsGrowing())), kastoriStep.withId(13)); anglersRetreatStep = new ConditionalStep(this, anglersCheckHealth); anglersRetreatStep.addStep(anglersRetreatStates.getIsUnchecked(), anglersCheckHealth); + anglersRetreatStep.addStep(and(anglersRetreatStates.getIsHarvestable(), not(payingForRemoval)), anglersCutDown); anglersRetreatStep.addStep(anglersRetreatStates.getIsEmpty(), anglersPlant); anglersRetreatStep.addStep(anglersRetreatStates.getIsHarvestable(), anglersClear); anglersRetreatStep.addStep(anglersRetreatStates.getIsStump(), anglersDig); anglersRetreatStep.addStep(nor(usingCompostorNothing, anglersRetreatStates.getIsProtected()), anglersProtect); - - steps.addStep(and(accessToAnglersRetreat, nor(anglersRetreatStates.getIsGrowing())), - anglersRetreatStep.withId(14)); + steps.addStep(and(accessToAnglersRetreat, not(anglersRetreatStates.getIsGrowing())), anglersRetreatStep.withId(14)); greatConchStep = new ConditionalStep(this, greatConchCalquatPatchCheckHealth); greatConchStep.addStep(greatConchStates.getIsUnchecked(), greatConchCalquatPatchCheckHealth); + greatConchStep.addStep(and(greatConchStates.getIsHarvestable(), not(payingForRemoval)), greatConchCalquatPatchRemove); greatConchStep.addStep(greatConchStates.getIsEmpty(), greatConchCalquatPatchPlant); greatConchStep.addStep(greatConchStates.getIsHarvestable(), greatConchCalquatPatchClear); greatConchStep.addStep(greatConchStates.getIsStump(), greatConchCalquatPatchDig); greatConchStep.addStep(nor(usingCompostorNothing, greatConchStates.getIsProtected()), greatConchCalquatProtect); - - steps.addStep(and(accessToGreatConch, nor(greatConchStates.getIsGrowing())), - greatConchStep.withId(15)); + steps.addStep(and(accessToGreatConch, not(greatConchStates.getIsGrowing())), greatConchStep.withId(15)); return steps; } @@ -425,7 +466,8 @@ private void setupConditions() gnomeStrongholdFruitStates = new PatchStates("Gnome Stronghold"); lletyaStates = new PatchStates("Lletya", accessToLletya); farmingGuildFruitStates = new PatchStates("Farming Guild", accessToFarmingGuildFruitTreePatch); - kastoriStates = new PatchStates("Kastori", accessToVarlamore); + kastoriFruitStates = new PatchStates("Kastori", accessToVarlamore); + kastoriCalquatStates = new PatchStates("Kastori", accessToVarlamore); greatConchStates = new PatchStates("Great Conch", accessToGreatConch); westHardwoodStates = new PatchStates("Fossil Island", "West"); @@ -440,7 +482,8 @@ private void setupConditions() gnomeStrongholdFruitStates.getIsGrowing(), or(not(accessToLletya), lletyaStates.getIsGrowing()), or(not(accessToVarlamore), auburnvaleStates.getIsGrowing()), - or(not(accessToVarlamore), kastoriStates.getIsGrowing()), + or(not(accessToVarlamore), kastoriFruitStates.getIsGrowing()), + or(not(accessToVarlamore), kastoriCalquatStates.getIsGrowing()), or(not(accessToFarmingGuildTreePatch), farmingGuildTreeStates.getIsGrowing()), or(not(accessToFarmingGuildFruitTreePatch), farmingGuildFruitStates.getIsGrowing()), or(not(accessToFossilIsland), and(westHardwoodStates.getIsGrowing(), middleHardwoodStates.getIsGrowing(), eastHardwoodStates.getIsGrowing())), @@ -465,7 +508,7 @@ public void setupRequirements() .hideConditioned(new VarbitRequirement(VarbitID.FARMING_BLOCKWEEDS, 2)); coins = new ItemRequirement("Coins to quickly remove trees.", ItemID.COINS) .showConditioned(payingForRemoval); - axe = new ItemRequirement("Any axe you can use", ItemCollections.AXES); + axe = new ItemRequirement("Any axe", ItemCollections.AXES).isNotConsumed().showConditioned(not(payingForRemoval)); TreeSapling treeSaplingEnum = (TreeSapling) FarmingUtils.getEnumFromConfig(configManager, TreeSapling.MAGIC); treeSapling = treeSaplingEnum.getPlantableItemRequirement(itemManager); @@ -578,59 +621,73 @@ private void setupSteps() lumbridgeTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_4, new WorldPoint(3193, 3231, 0), "Speak to Fayeth to clear the patch."); + lumbridgeTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); lumbridgeTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); faladorTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_2, new WorldPoint(3004, 3373, 0), "Speak to Heskel to clear the patch."); + faladorTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); faladorTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); taverleyTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_1, new WorldPoint(2936, 3438, 0), "Speak to Alain to clear the patch."); + taverleyTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); taverleyTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); varrockTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_3_02, new WorldPoint(3229, 3459, 0), "Speak to Treznor to clear the patch."); + varrockTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); varrockTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); gnomeStrongholdTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_GNOME, new WorldPoint(2436, 3415, 0), "Speak to Prissy Scilla to clear the patch."); + gnomeStrongholdTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); gnomeStrongholdTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); farmingGuildTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T2, new WorldPoint(1232, 3736, 0), "Speak to Rosie to clear the patch."); + farmingGuildTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); farmingGuildTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); auburnvaleTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_7, new WorldPoint(1367, 3322, 0), "Speak to Aub to clear the patch."); + auburnvaleTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); auburnvaleTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); lumbridgeTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_4, new WorldPoint(3193, 3231, 0), "Speak to Fayeth to protect the patch."); - lumbridgeTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + lumbridgeTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + lumbridgeTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); faladorTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_2, new WorldPoint(3004, 3373, 0), "Speak to Heskel to protect the patch."); - faladorTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + faladorTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + faladorTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); taverleyTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_1, new WorldPoint(2936, 3438, 0), "Speak to Alain to protect the patch."); - taverleyTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + taverleyTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + taverleyTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); varrockTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_3_02, new WorldPoint(3229, 3459, 0), "Speak to Treznor to protect the patch."); - varrockTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + varrockTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + varrockTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); strongholdTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_GNOME, new WorldPoint(2436, 3415, 0), "Speak to Prissy Scilla to protect the patch."); - strongholdTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + strongholdTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + strongholdTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); farmingGuildTreePayForProtection = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T2, new WorldPoint(1232, 3736, 0), "Speak to Rosie to protect the patch."); - farmingGuildTreePayForProtection.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + farmingGuildTreePayForProtection.conditionToHideInSidebar(not(payingForProtection)); + farmingGuildTreePayForProtection.addDialogSteps(TREE_PROTECTION_DIALOG); auburnvaleTreeProtect = new NpcStep(this, NpcID.FARMING_GARDENER_TREE_7, new WorldPoint(1367, 3322, 0), "Speak to Aub to protect the patch."); - auburnvaleTreeProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + auburnvaleTreeProtect.conditionToHideInSidebar(not(payingForProtection)); + auburnvaleTreeProtect.addDialogSteps(TREE_PROTECTION_DIALOG); // Tree Patch Steps lumbridgeTreePatchCheckHealth = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), @@ -660,6 +717,44 @@ private void setupSteps() auburnvaleTreePatchCheckHealth.conditionToHideInSidebar(new Conditions(LogicType.NOR, accessToVarlamore)); auburnvaleTreePatchCheckHealth.addTeleport(auburnvaleTeleport); + // Tree Cut Down Steps + farmingGuildTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_6, new WorldPoint(1232, 3736, 0), + "Cut down the tree planted in the Farming Guild.", axe); + farmingGuildTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToFarmingGuildTreePatch), payingForRemoval)); + farmingGuildTreePatchCutDown.addTeleport(farmingGuildTeleport); + + lumbridgeTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), + "Cut down the tree planted in Lumbridge.", axe); + lumbridgeTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + lumbridgeTreePatchCutDown.addTeleport(lumbridgeTeleport); + lumbridgeTreePatchCutDown.addSpellHighlight(NormalSpells.LUMBRIDGE_TELEPORT); + lumbridgeTreePatchCutDown.addSpellHighlight(NormalSpells.LUMBRIDGE_HOME_TELEPORT); + + faladorTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_2, new WorldPoint(3004, 3373, 0), + "Cut down the tree planted in Falador.", axe); + faladorTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + faladorTreePatchCutDown.addTeleport(faladorTeleport); + faladorTreePatchCutDown.addSpellHighlight(NormalSpells.FALADOR_TELEPORT); + + taverleyTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_1, new WorldPoint(2936, 3438, 0), + "Cut down the tree planted in Taverley.", axe); + taverleyTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + varrockTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_3, new WorldPoint(3229, 3459, 0), + "Cut down the tree planted in Varrock.", axe); + varrockTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + varrockTreePatchCutDown.addTeleport(varrockTeleport); + varrockTreePatchCutDown.addSpellHighlight(NormalSpells.VARROCK_TELEPORT); + + gnomeStrongholdTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_5, new WorldPoint(2436, 3415, 0), + "Cut down the tree planted in the Tree Gnome Stronghold.", axe); + gnomeStrongholdTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + auburnvaleTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_7, new WorldPoint(1367, 3322, 0), + "Cut down the tree planted at Auburnvale.", axe); + auburnvaleTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToVarlamore), payingForRemoval)); + auburnvaleTreePatchCutDown.addTeleport(auburnvaleTeleport); + // Tree Plant Steps lumbridgeTreePatchPlant = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), "Plant your sapling in the Lumbridge patch.", treeSapling); @@ -701,26 +796,33 @@ private void setupSteps() // Dig lumbridgeTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_4, new WorldPoint(3193, 3231, 0), "Dig up the tree stump in Lumbridge."); + lumbridgeTreePatchDig.conditionToHideInSidebar(payingForRemoval); faladorTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_2, new WorldPoint(3004, 3373, 0), "Dig up the tree stump in Falador."); + faladorTreePatchDig.conditionToHideInSidebar(payingForRemoval); taverleyTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_1, new WorldPoint(2936, 3438, 0), "Dig up the tree stump in Taverley."); + taverleyTreePatchDig.conditionToHideInSidebar(payingForRemoval); varrockTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_3, new WorldPoint(3229, 3459, 0), "Dig up the tree stump in Varrock."); + varrockTreePatchDig.conditionToHideInSidebar(payingForRemoval); gnomeStrongholdTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_5, new WorldPoint(2436, 3415, 0), "Dig up the tree stump in the Tree Gnome Stronghold."); + gnomeStrongholdTreePatchDig.conditionToHideInSidebar(payingForRemoval); farmingGuildTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_6, new WorldPoint(1232, 3736, 0), "Dig up the tree stump in the Farming Guild tree patch."); + farmingGuildTreePatchDig.conditionToHideInSidebar(payingForRemoval); auburnvaleTreePatchDig = new ObjectStep(this, ObjectID.FARMING_TREE_PATCH_7, new WorldPoint(1367, 3322, 0), "Dig up the tree stump in the Auburnvale tree patch."); + auburnvaleTreePatchDig.conditionToHideInSidebar(payingForRemoval); - faladorTreePatchClear.addSubSteps(faladorTreePatchDig, faladorTreeProtect); - taverleyTreePatchClear.addSubSteps(taverleyTreePatchDig, taverleyTreeProtect); - varrockTreePatchClear.addSubSteps(varrockTreePatchDig, varrockTreeProtect); - gnomeStrongholdTreePatchClear.addSubSteps(gnomeStrongholdTreePatchDig, strongholdTreeProtect); - lumbridgeTreePatchClear.addSubSteps(lumbridgeTreePatchDig, lumbridgeTreeProtect); - farmingGuildTreePatchClear.addSubSteps(farmingGuildTreePatchDig, farmingGuildTreePayForProtection); - auburnvaleTreePatchClear.addSubSteps(auburnvaleTreePatchDig, auburnvaleTreeProtect); + faladorTreePatchClear.addSubSteps(faladorTreePatchDig); + taverleyTreePatchClear.addSubSteps(taverleyTreePatchDig); + varrockTreePatchClear.addSubSteps(varrockTreePatchDig); + gnomeStrongholdTreePatchClear.addSubSteps(gnomeStrongholdTreePatchDig); + lumbridgeTreePatchClear.addSubSteps(lumbridgeTreePatchDig); + farmingGuildTreePatchClear.addSubSteps(farmingGuildTreePatchDig); + auburnvaleTreePatchClear.addSubSteps(auburnvaleTreePatchDig); // Fruit Tree Steps @@ -833,106 +935,192 @@ private void setupSteps() greatConchCalquatPatchCheckHealth.addWidgetHighlightWithTextRequirement(187, 3, "Great Conch", true); greatConchCalquatPatchCheckHealth.addSubSteps(greatConchCalquatPatchPlant); + // Fruit Tree Cut Down Steps + gnomeStrongholdFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_1, new WorldPoint(2476, 3446, 0), + "Cut down the fruit tree planted in the Tree Gnome Stronghold.", axe); + gnomeStrongholdFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + gnomeStrongholdFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Gnome Stronghold", true); + + gnomeVillageFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_2, new WorldPoint(2490, 3180, 0), + "Cut down the fruit tree planted outside the Tree Gnome Village.", axe); + gnomeVillageFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + gnomeVillageFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Tree Gnome Village", true); + + brimhavenFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_3, new WorldPoint(2765, 3213, 0), + "Cut down the fruit tree planted in Brimhaven.", axe); + brimhavenFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + brimhavenFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(InterfaceID.MENU, InterfaceID.Menu.LJ_LAYER1 & 0xFFFF, "Brimhaven", true); + brimhavenFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(InterfaceID.CHARTERING_MENU_SIDE, InterfaceID.CharteringMenuSide.LIST_CONTENT & 0xFFFF, "Brimhaven", true); + brimhavenFruitTreePatchCutDown.addWidgetHighlight(new WidgetHighlight(InterfaceID.SAILING_MENU, InterfaceID.SailingMenu.CONTENT & 0xFFFF, 2)); + + catherbyFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_4, new WorldPoint(2860, 3433, 0), + "Cut down the fruit tree planted in Catherby.", axe); + catherbyFruitTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + catherbyFruitTreePatchCutDown.addTeleport(catherbyTeleport); + catherbyFruitTreePatchCutDown.addSpellHighlight(NormalSpells.CAMELOT_TELEPORT); + catherbyFruitTreePatchCutDown.addSpellHighlight(LunarSpells.CATHERBY_TELEPORT); + + lletyaFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_5, new WorldPoint(2347, 3162, 0), + "Cut down the fruit tree planted in Lletya.", axe); + lletyaFruitTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToLletya), payingForRemoval)); + lletyaFruitTreePatchCutDown.addTeleport(crystalTeleport); + + farmingGuildFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_6, new WorldPoint(1242, 3758, 0), + "Cut down the fruit tree planted in the Farming Guild.", axe); + farmingGuildFruitTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToFarmingGuildFruitTreePatch), payingForRemoval)); + farmingGuildFruitTreePatchCutDown.addTeleport(farmingGuildTeleport); + farmingGuildFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Farming Guild", true); + + kastoriFruitTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_7, new WorldPoint(1350, 3057, 0), + "Cut down the fruit tree planted in Kastori.", axe); + kastoriFruitTreePatchCutDown.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToVarlamore), payingForRemoval)); + kastoriFruitTreePatchCutDown.addTeleport(kastoriTeleport); + kastoriFruitTreePatchCutDown.addWidgetHighlightWithTextRequirement(187, 3, "Kastori", true); + + taiBwoWannaiCalquatPatchRemove = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH, new WorldPoint(2795, 3102, 0), + "Pick the fruit off the calquat and clear the patch in Tai Bwo Wannai."); + taiBwoWannaiCalquatPatchRemove.conditionToHideInSidebar(payingForRemoval); + taiBwoWannaiCalquatPatchRemove.addWidgetHighlightWithTextRequirement(187, 3, "Tai Bwo Wannai", true); + + kastoriCalquatPatchRemove = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_2, new WorldPoint(1366, 3033, 0), + "Pick the fruit off the calquat and clear the patch in Kastori."); + kastoriCalquatPatchRemove.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToVarlamore), payingForRemoval)); + kastoriCalquatPatchRemove.addTeleport(kastoriTeleport); + kastoriCalquatPatchRemove.addWidgetHighlightWithTextRequirement(187, 3, "Kastori", true); + + greatConchCalquatPatchRemove = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_3, new WorldPoint(3129, 2406, 0), + "Pick the fruit off the calquat and clear the patch in Great Conch."); + greatConchCalquatPatchRemove.conditionToHideInSidebar(new Conditions(LogicType.OR, new Conditions(LogicType.NOR, accessToGreatConch), payingForRemoval)); + greatConchCalquatPatchRemove.addWidgetHighlightWithTextRequirement(187, 3, "Great Conch", true); + // Clear gnomeStrongholdFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_1, new WorldPoint(2476, 3446, 0), "Pay Bolongo 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + gnomeStrongholdFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); gnomeStrongholdFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); gnomeVillageFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_2, new WorldPoint(2490, 3180, 0), "Pay Gileth 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + gnomeVillageFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); gnomeVillageFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); brimhavenFruitTreePatchClear = new NpcStep(this, NpcID.GARTH, new WorldPoint(2765, 3213, 0), "Pay Garth 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + brimhavenFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); brimhavenFruitTreePatchClear.addWidgetHighlightWithTextRequirement(InterfaceID.MENU, InterfaceID.Menu.LJ_LAYER1 & 0xFFFF, "Brimhaven", true); brimhavenFruitTreePatchClear.addWidgetHighlightWithTextRequirement(InterfaceID.CHARTERING_MENU_SIDE, InterfaceID.CharteringMenuSide.LIST_CONTENT & 0xFFFF, "Brimhaven", true); brimhavenFruitTreePatchClear.addWidgetHighlight(new WidgetHighlight(InterfaceID.SAILING_MENU, InterfaceID.SailingMenu.CONTENT & 0xFFFF, 2)); brimhavenFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); catherbyFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_4, new WorldPoint(2860, 3433, 0), "Pay Ellena 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + catherbyFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); catherbyFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); lletyaFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_TREE_5, new WorldPoint(2347, 3162, 0), "Pay Liliwen 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + lletyaFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); lletyaFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); farmingGuildFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T3, new WorldPoint(1243, 3760, 0), "Pay Nikkie 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + farmingGuildFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); farmingGuildFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); kastoriFruitTreePatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_7, new WorldPoint(1350, 3057, 0), "Pay Ehecatl 200 coins to clear the fruit tree, or pick all the fruit and cut it down."); + kastoriFruitTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); kastoriFruitTreePatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); taiBwoWannaiCalquatPatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT, new WorldPoint(2795, 3102, 0), "Pay Imiago 200 coins to clear the calquat tree, or pick all the fruit and cut it down."); + taiBwoWannaiCalquatPatchClear.conditionToHideInSidebar(not(payingForRemoval)); taiBwoWannaiCalquatPatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); kastoriCalquatPatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_2, new WorldPoint(1366, 3033, 0), "Pay Tziuhtla 200 coins to clear the calquat tree, or pick all the fruit and cut it down."); + kastoriCalquatPatchClear.conditionToHideInSidebar(not(payingForRemoval)); kastoriCalquatPatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); greatConchCalquatPatchClear = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_3, new WorldPoint(3129, 2406, 0), "Pay Guppa 200 coins to clear the calquat tree, or pick all the fruit and cut it down."); + greatConchCalquatPatchClear.conditionToHideInSidebar(not(payingForRemoval)); greatConchCalquatPatchClear.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); strongholdFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_1, new WorldPoint(2476, 3446, 0), "Pay Bolongo to protect the patch."); - strongholdFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + strongholdFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + strongholdFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); villageFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_2, new WorldPoint(2490, 3180, 0), "Pay Gileth to protect the patch."); - villageFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + villageFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + villageFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); brimhavenFruitProtect = new NpcStep(this, NpcID.GARTH, new WorldPoint(2765, 3213, 0), "Pay Garth to protect the patch."); - brimhavenFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + brimhavenFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + brimhavenFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); catherbyFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_4, new WorldPoint(2860, 3433, 0), "Pay Ellena to protect the patch."); - catherbyFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + catherbyFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + catherbyFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); lletyaFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_TREE_5, new WorldPoint(2347, 3162, 0), "Pay Liliwen to protect the patch."); - lletyaFruitProtect.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - " + - "chop my tree down please.", "Yes."); + lletyaFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + lletyaFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); guildFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FARMGUILD_T3, new WorldPoint(1243, 3760, 0), "Pay Nikkie to protect the patch."); - guildFruitProtect.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - " + - "chop my tree down please.", "Yes."); + guildFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + guildFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); kastoriFruitProtect = new NpcStep(this, NpcID.FARMING_GARDENER_FRUIT_7, new WorldPoint(1350, 3057, 0), "Pay Ehecatl to protect the patch."); - kastoriFruitProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + kastoriFruitProtect.conditionToHideInSidebar(not(payingForProtection)); + kastoriFruitProtect.addDialogSteps(TREE_PROTECTION_DIALOG); taiBwoWannaiCalquatProtect = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT, new WorldPoint(2795, 3102, 0), "Pay Imiago to protect the patch."); - taiBwoWannaiCalquatProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + taiBwoWannaiCalquatProtect.conditionToHideInSidebar(not(payingForProtection)); + taiBwoWannaiCalquatProtect.addDialogSteps(TREE_PROTECTION_DIALOG); kastoriCalquatProtect = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_2, new WorldPoint(1366, 3033, 0), "Pay Tziuhtla to protect the patch."); - kastoriCalquatProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + kastoriCalquatProtect.conditionToHideInSidebar(not(payingForProtection)); + kastoriCalquatProtect.addDialogSteps(TREE_PROTECTION_DIALOG); greatConchCalquatProtect = new NpcStep(this, NpcID.FARMING_GARDENER_CALQUAT_3, new WorldPoint(3129, 2406, 0), "Pay Guppa to protect the patch."); - greatConchCalquatProtect.addDialogSteps("Would you chop my tree down for me?","I can't be bothered - I'd rather pay you to do it.", "Here's 200 Coins - chop my tree down please.", "Yes."); + greatConchCalquatProtect.conditionToHideInSidebar(not(payingForProtection)); + greatConchCalquatProtect.addDialogSteps(TREE_PROTECTION_DIALOG); // Dig Fruit Tree Steps gnomeStrongholdFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_1, new WorldPoint(2476, 3446, 0), "Dig up the fruit tree's stump in the Tree Gnome Stronghold."); + gnomeStrongholdFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); gnomeVillageFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_2, new WorldPoint(2490, 3180, 0), "Dig up the fruit tree's stump outside the Tree Gnome Village."); + gnomeVillageFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); brimhavenFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_3, new WorldPoint(2765, 3213, 0), "Dig up the fruit tree's stump in Brimhaven."); + brimhavenFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); catherbyFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_4, new WorldPoint(2860, 3433, 0), "Check the health of the fruit tree planted in Catherby"); + catherbyFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); lletyaFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_5, new WorldPoint(2347, 3162, 0), "Dig up the fruit tree's stump in Lletya."); + lletyaFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); farmingGuildFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_6, new WorldPoint(1242, 3758, 0), "Dig up the fruit tree's stump in the Farming Guild."); + farmingGuildFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); kastoriFruitTreePatchDig = new ObjectStep(this, ObjectID.FARMING_FRUIT_TREE_PATCH_7, new WorldPoint(1350, 3057, 0), "Dig up the fruit tree's stump in Kastori."); + kastoriFruitTreePatchDig.conditionToHideInSidebar(payingForRemoval); taiBwoWannaiCalquatPatchDig = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH, new WorldPoint(2795, 3102, 0), "Dig up the calquat tree's stump in Tai Bwo Wannai."); + taiBwoWannaiCalquatPatchDig.conditionToHideInSidebar(payingForRemoval); kastoriCalquatPatchDig = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_2, new WorldPoint(1366, 3033, 0), "Dig up the calquat tree's stump in Kastori."); + kastoriCalquatPatchDig.conditionToHideInSidebar(payingForRemoval); greatConchCalquatPatchDig = new ObjectStep(this, ObjectID.FARMING_CALQUAT_TREE_PATCH_3, new WorldPoint(3129, 2406, 0), "Dig up the calquat tree's stump in Great Conch."); - - gnomeStrongholdFruitTreePatchClear.addSubSteps(gnomeStrongholdFruitTreePatchDig, strongholdFruitProtect); - gnomeVillageFruitTreePatchClear.addSubSteps(gnomeVillageFruitTreePatchDig, villageFruitProtect); - brimhavenFruitTreePatchClear.addSubSteps(brimhavenFruitTreePatchDig, brimhavenFruitProtect); - catherbyFruitTreePatchClear.addSubSteps(catherbyFruitTreePatchDig, catherbyFruitProtect); - lletyaFruitTreePatchClear.addSubSteps(lletyaFruitTreePatchDig, lletyaFruitProtect); - farmingGuildFruitTreePatchClear.addSubSteps(farmingGuildFruitTreePatchDig, guildFruitProtect); - kastoriFruitTreePatchClear.addSubSteps(kastoriFruitTreePatchDig, kastoriFruitProtect); - taiBwoWannaiCalquatPatchClear.addSubSteps(taiBwoWannaiCalquatPatchDig, taiBwoWannaiCalquatProtect); - kastoriCalquatPatchClear.addSubSteps(kastoriCalquatPatchDig, kastoriCalquatProtect); - greatConchCalquatPatchClear.addSubSteps(greatConchCalquatPatchDig, greatConchCalquatProtect); + greatConchCalquatPatchDig.conditionToHideInSidebar(payingForRemoval); + + gnomeStrongholdFruitTreePatchClear.addSubSteps(gnomeStrongholdFruitTreePatchDig); + gnomeVillageFruitTreePatchClear.addSubSteps(gnomeVillageFruitTreePatchDig); + brimhavenFruitTreePatchClear.addSubSteps(brimhavenFruitTreePatchDig); + catherbyFruitTreePatchClear.addSubSteps(catherbyFruitTreePatchDig); + lletyaFruitTreePatchClear.addSubSteps(lletyaFruitTreePatchDig); + farmingGuildFruitTreePatchClear.addSubSteps(farmingGuildFruitTreePatchDig); + kastoriFruitTreePatchClear.addSubSteps(kastoriFruitTreePatchDig); + taiBwoWannaiCalquatPatchClear.addSubSteps(taiBwoWannaiCalquatPatchDig); + kastoriCalquatPatchClear.addSubSteps(kastoriCalquatPatchDig); + greatConchCalquatPatchClear.addSubSteps(greatConchCalquatPatchDig); // Hardwood Tree Steps westHardwoodTreePatchCheckHealth = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_3, new WorldPoint(3702, 3837, 0), @@ -968,56 +1156,97 @@ private void setupSteps() anglersPlant = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_5, new WorldPoint(2470, 2704, 0), "Plant your sapling on the hardwood tree patch on Anglers' Retreat.", hardwoodSapling); + // Hardwood Tree Cut Down Steps + eastHardwoodTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_1, new WorldPoint(3715, 3835, 0), + "Cut down the hardwood tree planted on the eastern hardwood tree patch on Fossil Island.", axe); + eastHardwoodTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + middleHardwoodTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_2, new WorldPoint(3708, 3833, 0), + "Cut down the hardwood tree planted on the centre hardwood tree patch on Fossil Island.", axe); + middleHardwoodTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + westHardwoodTreePatchCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_3, new WorldPoint(3702, 3837, 0), + "Cut down the hardwood tree planted on the western hardwood tree patch on Fossil Island.", axe); + westHardwoodTreePatchCutDown.conditionToHideInSidebar(payingForRemoval); + + savannahCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_4, new WorldPoint(1687, 2972, 0), + "Cut down the hardwood tree planted in the Avium Savannah.", axe); + savannahCutDown.conditionToHideInSidebar(payingForRemoval); + + anglersCutDown = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_5, new WorldPoint(2470, 2704, 0), + "Cut down the hardwood tree planted in the Anglers' Retreat.", axe); + anglersCutDown.conditionToHideInSidebar(payingForRemoval); + westHardwoodTreePatchClear = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER3, new WorldPoint(3702, 3837, 0), "Pay the brown squirrel to remove the west tree."); + westHardwoodTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); westHardwoodTreePatchClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); middleHardwoodTreePatchClear = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER2, new WorldPoint(3702, 3837, 0), "Pay the black squirrel to remove the middle tree."); + middleHardwoodTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); middleHardwoodTreePatchClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); eastHardwoodTreePatchClear = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER1, new WorldPoint(3702, 3837, 0), "Pay the grey squirrel to remove the east tree."); + eastHardwoodTreePatchClear.conditionToHideInSidebar(not(payingForRemoval)); eastHardwoodTreePatchClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); savannahClear = new NpcStep(this, NpcID.FROG_QUEST_MARCELLUS_FARMER, new WorldPoint(1687, 2972, 0), "Pay Marcellus to clear the tree."); + savannahClear.conditionToHideInSidebar(not(payingForRemoval)); savannahClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); anglersClear = new NpcStep(this, NpcID.FARMING_GARDENER_HARDWOOD_TREE_5, new WorldPoint(2470, 2704, 0), "Pay Argo to clear the tree."); + anglersClear.conditionToHideInSidebar(not(payingForRemoval)); anglersClear.addDialogSteps("Would you chop my tree down for me?", "I can't be bothered - I'd rather pay you to do it.", "Here's 200 " + "Coins - chop my tree down please.", "Yes."); westHardwoodTreePatchDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_3, new WorldPoint(3702, 3837, 0), "Dig up the western hardwood tree's stump on Fossil Island."); + westHardwoodTreePatchDig.conditionToHideInSidebar(payingForRemoval); middleHardwoodTreePatchDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_2, new WorldPoint(3708, 3833, 0), "Dig up the centre hardwood tree's stump on Fossil Island."); + middleHardwoodTreePatchDig.conditionToHideInSidebar(payingForRemoval); eastHardwoodTreePatchDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_1, new WorldPoint(3715, 3835, 0), "Dig up the eastern hardwood tree's stump on Fossil Island."); + eastHardwoodTreePatchDig.conditionToHideInSidebar(payingForRemoval); savannahDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_4, new WorldPoint(1687, 2972, 0), "Dig up the Savannah hardwood tree's stump."); + savannahDig.conditionToHideInSidebar(payingForRemoval); anglersDig = new ObjectStep(this, ObjectID.FARMING_HARDWOOD_TREE_PATCH_5, new WorldPoint(2470,2704, 0), "Dig up the Anglers' Retreat hardwood tree's stump."); + anglersDig.conditionToHideInSidebar(payingForRemoval); westHardwoodProtect = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER3, new WorldPoint(3702, 3837, 0), "Pay the brown squirrel to protect the west tree."); + westHardwoodProtect.conditionToHideInSidebar(not(payingForProtection)); + westHardwoodProtect.addDialogSteps(TREE_PROTECTION_DIALOG); middleHardwoodProtect = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER2, new WorldPoint(3702, 3837, 0), "Pay the black squirrel to protect the middle tree."); + middleHardwoodProtect.conditionToHideInSidebar(not(payingForProtection)); + middleHardwoodProtect.addDialogSteps(TREE_PROTECTION_DIALOG); eastHardwoodProtect = new NpcStep(this, NpcID.FOSSIL_SQUIRREL_GARDENER1, new WorldPoint(3702, 3837, 0), "Pay the grey squirrel to protect the east tree."); + eastHardwoodProtect.conditionToHideInSidebar(not(payingForProtection)); + eastHardwoodProtect.addDialogSteps(TREE_PROTECTION_DIALOG); savannahProtect = new NpcStep(this, NpcID.FROG_QUEST_MARCELLUS_FARMER, new WorldPoint(1687, 2972, 0), "Pay Marcellus to protect the hardwood tree."); + savannahProtect.conditionToHideInSidebar(not(payingForProtection)); + savannahProtect.addDialogSteps(TREE_PROTECTION_DIALOG); anglersProtect = new NpcStep(this, NpcID.FARMING_GARDENER_HARDWOOD_TREE_5, new WorldPoint(2470, 2704, 0), "Pay Argo to protect the hardwood tree."); - - westHardwoodTreePatchClear.addSubSteps(westHardwoodTreePatchDig, westHardwoodProtect); - middleHardwoodTreePatchClear.addSubSteps(middleHardwoodTreePatchDig, middleHardwoodProtect); - eastHardwoodTreePatchClear.addSubSteps(eastHardwoodTreePatchDig, eastHardwoodProtect); - savannahClear.addSubSteps(savannahDig, savannahProtect); - anglersClear.addSubSteps(anglersDig, anglersProtect); + anglersProtect.conditionToHideInSidebar(not(payingForProtection)); + anglersProtect.addDialogSteps(TREE_PROTECTION_DIALOG); + + westHardwoodTreePatchClear.addSubSteps(westHardwoodTreePatchDig); + middleHardwoodTreePatchClear.addSubSteps(middleHardwoodTreePatchDig); + eastHardwoodTreePatchClear.addSubSteps(eastHardwoodTreePatchDig); + savannahClear.addSubSteps(savannahDig); + anglersClear.addSubSteps(anglersDig); } @Subscribe @@ -1033,10 +1262,10 @@ public void onGameTick(GameTick event) farmingWorld.getTabs().get(Tab.TREE), allTreeSaplings, allProtectionItemTree); handleTreePatches(PatchImplementation.FRUIT_TREE, List.of(farmingGuildFruitStates, brimhavenStates, catherbyStates, gnomeStrongholdFruitStates, gnomeVillageStates, lletyaStates, - kastoriStates), + kastoriFruitStates), farmingWorld.getTabs().get(Tab.FRUIT_TREE), allFruitSaplings, allProtectionItemFruitTree); handleTreePatches(PatchImplementation.CALQUAT, - List.of(taiBwoWannaiStates, kastoriStates, greatConchStates), + List.of(taiBwoWannaiStates, kastoriCalquatStates, greatConchStates), farmingWorld.getTabs().get(Tab.FRUIT_TREE), allCalquatSaplings, allProtectionItemCalquat); handleTreePatches(PatchImplementation.HARDWOOD_TREE, List.of(westHardwoodStates, middleHardwoodStates, eastHardwoodStates, savannahStates, anglersRetreatStates), @@ -1058,8 +1287,9 @@ public void handleTreePatches(PatchImplementation implementation, List getConfigs() @Override public List getItemRequirements() { - return Arrays.asList(spade, rake, compost, coins, allTreeSaplings, allFruitSaplings, allHardwoodSaplings, allCalquatSaplings, allProtectionItemTree, allProtectionItemFruitTree, allProtectionItemHardwood, allProtectionItemCalquat); + return Arrays.asList(spade, rake, compost, coins, axe, allTreeSaplings, allFruitSaplings, allHardwoodSaplings, allCalquatSaplings, allProtectionItemTree, allProtectionItemFruitTree, allProtectionItemHardwood, allProtectionItemCalquat); } @Override @@ -1151,70 +1381,97 @@ public List getPanels() // IDEA: Can add ID to each step. onLoad and onConfigChanged it checks id ordering. List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Wait for Herbs", waitForTree).withHideCondition(nor(allGrowing))); + allSteps.add(new PanelDetails("Wait for Trees", waitForTree).withHideCondition(nor(allGrowing))); - PanelDetails farmingGuildPanel = new PanelDetails("Farming Guild", Arrays.asList(farmingGuildTreePatchCheckHealth, farmingGuildTreePatchClear, - farmingGuildTreePatchPlant, farmingGuildFruitTreePatchCheckHealth, farmingGuildFruitTreePatchClear, - farmingGuildTreePatchPlant)).withId(0); + PanelDetails farmingGuildTreePanel = new PanelDetails("Tree Patch", + Arrays.asList(farmingGuildTreePatchCheckHealth, farmingGuildTreePatchCutDown, farmingGuildTreePatchDig, farmingGuildTreePatchClear, farmingGuildTreePatchPlant, farmingGuildTreePayForProtection)).withId(-1); + farmingGuildTreePanel.setLockingStep(farmingGuildTreeStep); + PanelDetails farmingGuildFruitPanel = new PanelDetails("Fruit Tree Patch", + Arrays.asList(farmingGuildFruitTreePatchCheckHealth, farmingGuildFruitTreePatchCutDown, farmingGuildFruitTreePatchDig, farmingGuildFruitTreePatchClear, farmingGuildFruitTreePatchPlant, guildFruitProtect)).withId(-2); + farmingGuildFruitPanel.setLockingStep((farmingGuildFruitStep)); + var farmingGuildPanel = new TopLevelPanelDetails("Farming Guild", + farmingGuildTreePanel, farmingGuildFruitPanel).withId(0); farmingGuildPanel.setLockingStep(farmingGuildStep); - PanelDetails lumbridgePanel = new PanelDetails("Lumbridge", Arrays.asList(lumbridgeTreePatchCheckHealth, lumbridgeTreePatchClear, lumbridgeTreePatchPlant)).withId(1); + PanelDetails lumbridgePanel = new PanelDetails("Lumbridge", Arrays.asList(lumbridgeTreePatchCheckHealth, lumbridgeTreePatchCutDown, lumbridgeTreePatchDig, lumbridgeTreePatchClear, lumbridgeTreePatchPlant, lumbridgeTreeProtect)).withId(1); lumbridgePanel.setLockingStep(lumbridgeStep); - PanelDetails faladorPanel = new PanelDetails("Falador", Arrays.asList(faladorTreePatchCheckHealth, faladorTreePatchClear, faladorTreePatchPlant)).withId(2); + PanelDetails faladorPanel = new PanelDetails("Falador", Arrays.asList(faladorTreePatchCheckHealth, faladorTreePatchCutDown, faladorTreePatchDig, faladorTreePatchClear, faladorTreePatchPlant, faladorTreeProtect)).withId(2); faladorPanel.setLockingStep(faladorStep); - PanelDetails taverleyPanel = new PanelDetails("Taverley", Arrays.asList(taverleyTreePatchCheckHealth, taverleyTreePatchClear, taverleyTreePatchPlant)).withId(3); + PanelDetails taverleyPanel = new PanelDetails("Taverley", Arrays.asList(taverleyTreePatchCheckHealth, taverleyTreePatchCutDown, taverleyTreePatchDig, taverleyTreePatchClear, taverleyTreePatchPlant, taverleyTreeProtect)).withId(3); taverleyPanel.setLockingStep(taverleyStep); - PanelDetails varrockPanel = new PanelDetails("Varrock", Arrays.asList(varrockTreePatchCheckHealth, varrockTreePatchClear, varrockTreePatchPlant)).withId(4); + PanelDetails varrockPanel = new PanelDetails("Varrock", Arrays.asList(varrockTreePatchCheckHealth, varrockTreePatchCutDown, varrockTreePatchDig, varrockTreePatchClear, varrockTreePatchPlant, varrockTreeProtect)).withId(4); varrockPanel.setLockingStep(varrockStep); - PanelDetails gnomeStrongholdPanel = new PanelDetails("Gnome Stronghold", Arrays.asList(gnomeStrongholdFruitTreePatchCheckHealth, gnomeStrongholdFruitTreePatchClear, gnomeStrongholdFruitTreePatchPlant, - gnomeStrongholdTreePatchCheckHealth, gnomeStrongholdTreePatchClear, gnomeStrongholdFruitTreePatchPlant)).withId(5); + PanelDetails gnomeStrongholdFruitPanel = new PanelDetails("Fruit Tree Patch", + Arrays.asList(gnomeStrongholdFruitTreePatchCheckHealth, gnomeStrongholdFruitTreePatchCutDown, gnomeStrongholdFruitTreePatchDig, gnomeStrongholdFruitTreePatchClear, gnomeStrongholdFruitTreePatchPlant, strongholdFruitProtect)).withId(51); + gnomeStrongholdFruitPanel.setLockingStep(strongholdFruitStep); + PanelDetails gnomeStrongholdTreePanel = new PanelDetails("Tree Patch", + Arrays.asList(gnomeStrongholdTreePatchCheckHealth, gnomeStrongholdTreePatchCutDown, gnomeStrongholdTreePatchDig, gnomeStrongholdTreePatchClear, gnomeStrongholdTreePatchPlant, strongholdTreeProtect)).withId(52); + gnomeStrongholdTreePanel.setLockingStep(strongholdTreeStep); + var gnomeStrongholdPanel = new TopLevelPanelDetails("Gnome Stronghold", + gnomeStrongholdFruitPanel, gnomeStrongholdTreePanel).withId(5); gnomeStrongholdPanel.setLockingStep(strongholdStep); PanelDetails villagePanel = new PanelDetails("Tree Gnome Village", Arrays.asList(gnomeVillageFruitTreePatchCheckHealth, - gnomeVillageFruitTreePatchClear, gnomeVillageFruitTreePatchPlant)).withId(6); + gnomeVillageFruitTreePatchCutDown, gnomeVillageFruitTreePatchDig, gnomeVillageFruitTreePatchClear, gnomeVillageFruitTreePatchPlant, villageFruitProtect)).withId(6); villagePanel.setLockingStep(villageStep); - PanelDetails catherbyPanel = new PanelDetails("Catherby", Arrays.asList(catherbyFruitTreePatchCheckHealth, catherbyFruitTreePatchClear, catherbyFruitTreePatchPlant)).withId(7); + PanelDetails catherbyPanel = new PanelDetails("Catherby", Arrays.asList(catherbyFruitTreePatchCheckHealth, catherbyFruitTreePatchCutDown, catherbyFruitTreePatchDig, catherbyFruitTreePatchClear, catherbyFruitTreePatchPlant, catherbyFruitProtect)).withId(7); catherbyPanel.setLockingStep(catherbyStep); - PanelDetails brimhavenPanel = new PanelDetails("Brimhaven", Arrays.asList(brimhavenFruitTreePatchCheckHealth, brimhavenFruitTreePatchClear, brimhavenFruitTreePatchPlant, - taiBwoWannaiCalquatPatchCheckHealth, taiBwoWannaiCalquatPatchClear, taiBwoWannaiCalquatPatchPlant)).withId(8); + PanelDetails brimhavenPanel = new PanelDetails("Brimhaven", Arrays.asList(brimhavenFruitTreePatchCheckHealth, brimhavenFruitTreePatchCutDown, brimhavenFruitTreePatchDig, brimhavenFruitTreePatchClear, brimhavenFruitTreePatchPlant, brimhavenFruitProtect)).withId(81); brimhavenPanel.setLockingStep(brimhavenStep); + PanelDetails taiBwoWannaiPanel = new PanelDetails("Tai Bwo Wannai", Arrays.asList(taiBwoWannaiCalquatPatchCheckHealth, taiBwoWannaiCalquatPatchRemove, taiBwoWannaiCalquatPatchDig, taiBwoWannaiCalquatPatchClear, taiBwoWannaiCalquatPatchPlant, taiBwoWannaiCalquatProtect)).withId(82); + taiBwoWannaiPanel.setLockingStep(taiBwoWannaiStep); + var karamjaPanel = new TopLevelPanelDetails("Karamja", brimhavenPanel, taiBwoWannaiPanel).withId(8); + karamjaPanel.setLockingStep(karamjaStep); - PanelDetails lletyaPanel = new PanelDetails("Lletya", Arrays.asList(lletyaFruitTreePatchCheckHealth, lletyaFruitTreePatchClear, lletyaFruitTreePatchPlant)).withId(9); + PanelDetails lletyaPanel = new PanelDetails("Lletya", Arrays.asList(lletyaFruitTreePatchCheckHealth, lletyaFruitTreePatchCutDown, lletyaFruitTreePatchDig, lletyaFruitTreePatchClear, lletyaFruitTreePatchPlant, lletyaFruitProtect)).withId(9); lletyaPanel.setLockingStep(lletyaStep); - PanelDetails fossilIslandPanel = new PanelDetails("Fossil Island", Arrays.asList(eastHardwoodTreePatchCheckHealth, eastHardwoodTreePatchClear, eastHardwoodTreePatchPlant, - middleHardwoodTreePatchCheckHealth, middleHardwoodTreePatchClear, middleHardwoodTreePatchPlant, - westHardwoodTreePatchCheckHealth, westHardwoodTreePatchClear, westHardwoodTreePatchPlant)).withId(10); + PanelDetails fossilIslandEastPanel = new PanelDetails("East Hardwood Patch", + Arrays.asList(eastHardwoodTreePatchCheckHealth, eastHardwoodTreePatchCutDown, eastHardwoodTreePatchDig, eastHardwoodTreePatchClear, eastHardwoodTreePatchPlant, eastHardwoodProtect) + ).withId(101); + fossilIslandEastPanel.setLockingStep(fossilIslandEastStep); + PanelDetails fossilIslandMiddlePanel = new PanelDetails("Middle Hardwood Patch", + Arrays.asList(middleHardwoodTreePatchCheckHealth, middleHardwoodTreePatchCutDown, middleHardwoodTreePatchDig, middleHardwoodTreePatchClear, middleHardwoodTreePatchPlant, middleHardwoodProtect) + ).withId(102); + fossilIslandMiddlePanel.setLockingStep(fossilIslandMiddleStep); + PanelDetails fossilIslandWestPanel = new PanelDetails("West Hardwood Patch", + Arrays.asList(westHardwoodTreePatchCheckHealth, westHardwoodTreePatchCutDown, westHardwoodTreePatchDig, westHardwoodTreePatchClear, westHardwoodTreePatchPlant, westHardwoodProtect) + ).withId(103); + fossilIslandWestPanel.setLockingStep(fossilIslandWestStep); + var fossilIslandPanel = new TopLevelPanelDetails("Fossil Island", + fossilIslandEastPanel, fossilIslandMiddlePanel, fossilIslandWestPanel).withId(10); fossilIslandPanel.setLockingStep(fossilIslandStep); - PanelDetails savannahPanel = new PanelDetails("Avium Savannah", Arrays.asList(savannahCheckHealth, savannahClear, savannahPlant)).withId(11); + PanelDetails savannahPanel = new PanelDetails("Avium Savannah", Arrays.asList(savannahCheckHealth, savannahCutDown, savannahDig, savannahClear, savannahPlant, savannahProtect)).withId(11); savannahPanel.setLockingStep(savannahStep); - PanelDetails auburnvalePanel = new PanelDetails("Auburnvale", Arrays.asList(auburnvaleTreePatchCheckHealth, auburnvaleTreePatchClear, auburnvaleTreePatchPlant)).withId(12); + PanelDetails auburnvalePanel = new PanelDetails("Auburnvale", Arrays.asList(auburnvaleTreePatchCheckHealth, auburnvaleTreePatchCutDown, auburnvaleTreePatchDig, auburnvaleTreePatchClear, auburnvaleTreePatchPlant, auburnvaleTreeProtect)).withId(12); auburnvalePanel.setLockingStep(auburnvaleStep); - PanelDetails kastoriPanel = new PanelDetails("Kastori", Arrays.asList(kastoriFruitTreePatchCheckHealth, - kastoriFruitTreePatchClear, kastoriFruitTreePatchPlant, kastoriCalquatPatchCheckHealth, - kastoriCalquatPatchClear, kastoriCalquatPatchPlant)).withId(13); + PanelDetails kastoriFruitPanel = new PanelDetails("Fruit Tree Patch", Arrays.asList(kastoriFruitTreePatchCheckHealth, kastoriFruitTreePatchCutDown, kastoriFruitTreePatchDig, kastoriFruitTreePatchClear, kastoriFruitTreePatchPlant, kastoriFruitProtect)).withId(131); + kastoriFruitPanel.setLockingStep(kastoriFruitStep); + PanelDetails kastoriCalquatPanel = new PanelDetails("Calquat Patch", Arrays.asList(kastoriCalquatPatchCheckHealth, kastoriCalquatPatchRemove, kastoriCalquatPatchDig, kastoriCalquatPatchClear, kastoriCalquatPatchPlant, kastoriCalquatProtect)).withId(132); + kastoriCalquatPanel.setLockingStep(kastoriCalquatStep); + var kastoriPanel = new TopLevelPanelDetails("Kastori", kastoriFruitPanel, kastoriCalquatPanel).withId(13); kastoriPanel.setLockingStep(kastoriStep); PanelDetails anglersPanel = new PanelDetails("Anglers' Retreat", Arrays.asList(anglersCheckHealth, - anglersClear, anglersPlant)).withId(14); + anglersCutDown, anglersDig, anglersClear, anglersPlant, anglersProtect)).withId(14); anglersPanel.setLockingStep(anglersRetreatStep); PanelDetails greatConchPanel = new PanelDetails("Great Conch", - Arrays.asList(greatConchCalquatPatchCheckHealth, greatConchCalquatPatchClear, - greatConchCalquatPatchPlant)).withId(15); + Arrays.asList(greatConchCalquatPatchCheckHealth, greatConchCalquatPatchRemove, greatConchCalquatPatchDig, greatConchCalquatPatchClear, + greatConchCalquatPatchPlant, greatConchCalquatProtect)).withId(15); greatConchPanel.setLockingStep(greatConchStep); - TopLevelPanelDetails farmRunSidebar = new TopLevelPanelDetails("Tree Run", farmingGuildPanel, lumbridgePanel, faladorPanel, taverleyPanel, - varrockPanel, gnomeStrongholdPanel, villagePanel, catherbyPanel, brimhavenPanel, lletyaPanel, fossilIslandPanel, savannahPanel, auburnvalePanel, + var farmRunSidebar = new TopLevelPanelDetails("Tree Run", farmingGuildPanel, lumbridgePanel, faladorPanel, taverleyPanel, + varrockPanel, gnomeStrongholdPanel, villagePanel, catherbyPanel, karamjaPanel, lletyaPanel, fossilIslandPanel, savannahPanel, auburnvalePanel, kastoriPanel, anglersPanel, greatConchPanel); allSteps.add(farmRunSidebar); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java index 9f44d8b9a6..6ab3754e78 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/knightswaves/KnightWaves.java @@ -44,7 +44,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java index 08eec560ee..c32c524cda 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/mischelpers/strongholdofsecurity/StrongholdOfSecurity.java @@ -31,26 +31,28 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.CombatLevelRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class StrongholdOfSecurity extends BasicQuestHelper { static final String[] CORRECT_ANSWERS = { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java index 9deed8869e..fd151c9d68 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/aporcineofinterest/APorcineOfInterest.java @@ -36,62 +36,60 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class APorcineOfInterest extends BasicQuestHelper { - //Items Required - ItemRequirement rope, slashItem, reinforcedGoggles, combatGear, hoof; - - //Items Recommended - ItemRequirement draynorTeleport, faladorFarmTeleport; + // Required items + ItemRequirement rope; + ItemRequirement slashItem; + ItemRequirement combatGear; - Requirement inCave; + // Recommended items + ItemRequirement draynorTeleport; + ItemRequirement faladorFarmTeleport; - DetailedQuestStep readNotice, talkToSarah, useRopeOnHole, enterHole, investigateSkeleton, talkToSpria, enterHoleAgain, killSourhog, - enterHoleForFoot, cutOffFoot, returnToSarah, returnToSpria; + // Mid-quest item requirements + ItemRequirement reinforcedGoggles; + ItemRequirement hoof; - //Zones + // Zones Zone cave; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, readNotice); - steps.put(5, talkToSarah); - steps.put(10, useRopeOnHole); - - ConditionalStep investigateCave = new ConditionalStep(this, enterHole); - investigateCave.addStep(inCave, investigateSkeleton); - - steps.put(15, investigateCave); - - steps.put(20, talkToSpria); + // Miscellaneous requirements + Requirement inCave; - ConditionalStep goKillSourhog = new ConditionalStep(this, enterHoleAgain); - goKillSourhog.addStep(inCave, killSourhog); + // Steps + ObjectStep readNotice; + NpcStep talkToSarah; + ObjectStep useRopeOnHole; + ObjectStep enterHole; + ObjectStep investigateSkeleton; + NpcStep talkToSpria; + ObjectStep enterHoleAgain; + NpcStep killSourhog; + ObjectStep enterHoleForFoot; + ObjectStep cutOffFoot; + NpcStep returnToSarah; + NpcStep returnToSpria; - steps.put(25, goKillSourhog); - ConditionalStep getFootSteps = new ConditionalStep(this, enterHoleForFoot); - getFootSteps.addStep(hoof, returnToSarah); - getFootSteps.addStep(inCave, cutOffFoot); - - steps.put(30, getFootSteps); - steps.put(35, returnToSpria); - return steps; + @Override + protected void setupZones() + { + cave = new Zone(new WorldPoint(3152, 9669, 0), new WorldPoint(3181, 9720, 0)); } @Override @@ -102,6 +100,10 @@ protected void setupRequirements() slashItem = new ItemRequirement("A knife or slash weapon", ItemID.KNIFE).isNotConsumed(); slashItem.setTooltip("Except abyssal whip, abyssal tentacle, noxious halberd, or dragon claws."); + // This is not intended to be a full list, but rather just a reasonable list of slash weapons a user might bring. + // This does not fit super well into an item collection since it's not reusable. + slashItem.addAlternates(ItemID.DRAGON_SCIMITAR, ItemID.RUNE_SCIMITAR, ItemID.ADAMANT_SCIMITAR, ItemID.MITHRIL_SCIMITAR, ItemID.STEEL_SCIMITAR, ItemID.IRON_SCIMITAR, ItemID.BRONZE_SCIMITAR); + slashItem.addAlternates(ItemID.DRAGON_LONGSWORD, ItemID.RUNE_LONGSWORD, ItemID.ADAMANT_LONGSWORD, ItemID.MITHRIL_LONGSWORD, ItemID.STEEL_LONGSWORD, ItemID.IRON_LONGSWORD, ItemID.BRONZE_LONGSWORD); reinforcedGoggles = new ItemRequirement("Reinforced goggles", ItemID.SLAYER_REINFORCED_GOGGLES, 1, true).isNotConsumed(); reinforcedGoggles.setTooltip("You can get another pair from Spria"); @@ -110,22 +112,12 @@ protected void setupRequirements() combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); hoof = new ItemRequirement("Sourhog foot", ItemID.PORCINE_SOURHOG_TROPHY); - hoof.setTooltip("You can get another from Sourhog's corpse in his cave"); // Recommended draynorTeleport = new ItemRequirement("Teleport to north Draynor", ItemID.TELETAB_DRAYNOR); draynorTeleport.addAlternates(ItemCollections.AMULET_OF_GLORIES); faladorFarmTeleport = new ItemRequirement("Teleport to Falador Farm", ItemCollections.EXPLORERS_RINGS); - } - @Override - protected void setupZones() - { - cave = new Zone(new WorldPoint(3152, 9669, 0), new WorldPoint(3181, 9720, 0)); - } - - public void setupConditions() - { inCave = new ZoneRequirement(cave); } @@ -153,7 +145,7 @@ public void setupSteps() enterHoleForFoot = new ObjectStep(this, ObjectID.PORCINE_HOLE, new WorldPoint(3151, 3348, 0), "Climb down into the Strange Hole east of Draynor Manor.", slashItem); cutOffFoot = new ObjectStep(this, ObjectID.PORCINE_DEAD_SOURHOG, "Cut off Sourhog's foot.", slashItem); - ((ObjectStep) cutOffFoot).addAlternateObjects(ObjectID.PORCINE_DEAD_SOURHOG_9); + cutOffFoot.addAlternateObjects(ObjectID.PORCINE_DEAD_SOURHOG_9); cutOffFoot.addSubSteps(enterHoleForFoot); returnToSarah = new NpcStep(this, NpcID.FARMING_SHOPKEEPER_1, new WorldPoint(3033, 3293, 0), "Return to Sarah in the South Falador Farm.", hoof); @@ -162,22 +154,65 @@ public void setupSteps() returnToSpria = new NpcStep(this, NpcID.PORCINE_SPRIA, new WorldPoint(3092, 3267, 0), "Return to Spria in Draynor Village."); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, readNotice); + steps.put(5, talkToSarah); + steps.put(10, useRopeOnHole); + + var investigateCave = new ConditionalStep(this, enterHole); + investigateCave.addStep(inCave, investigateSkeleton); + + steps.put(15, investigateCave); + + steps.put(20, talkToSpria); + + var goKillSourhog = new ConditionalStep(this, enterHoleAgain); + goKillSourhog.addStep(inCave, killSourhog); + + steps.put(25, goKillSourhog); + + var getFootSteps = new ConditionalStep(this, enterHoleForFoot); + getFootSteps.addStep(hoof.alsoCheckBank(), returnToSarah); + getFootSteps.addStep(inCave, cutOffFoot); + + steps.put(30, getFootSteps); + steps.put(35, returnToSpria); + + return steps; + } + @Override public List getItemRequirements() { - return Arrays.asList(rope, slashItem, combatGear); + return List.of( + rope, + slashItem, + combatGear + ); } @Override public List getItemRecommended() { - return Arrays.asList(draynorTeleport, faladorFarmTeleport); + return List.of( + draynorTeleport, + faladorFarmTeleport + ); } @Override public List getCombatRequirements() { - return Collections.singletonList("Sourhog (level 37)"); + return List.of( + "Sourhog (level 37)" + ); } @Override @@ -189,28 +224,52 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.SLAYER, 1000)); + return List.of( + new ExperienceReward(Skill.SLAYER, 1000) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Coins", ItemID.COINS, 5000)); + return List.of( + new ItemReward("Coins", ItemID.COINS, 5000) + ); } @Override public List getUnlockRewards() { - return Arrays.asList(new UnlockReward("30 Slayer Points"), new UnlockReward("Access to Sourhog Cave"), new UnlockReward("Sourhogs can be assigned as a slayer task by Spria")); + return List.of( + new UnlockReward("30 Slayer Points"), + new UnlockReward("Access to Sourhog Cave"), + new UnlockReward("Sourhogs can be assigned as a slayer task by Spria") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(readNotice, talkToSarah, useRopeOnHole, - enterHole, investigateSkeleton, talkToSpria, enterHoleAgain, killSourhog, cutOffFoot, returnToSarah, - returnToSpria), rope, slashItem, combatGear)); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Helping Sarah", List.of( + readNotice, + talkToSarah, + useRopeOnHole, + enterHole, + investigateSkeleton, + talkToSpria, + enterHoleAgain, + killSourhog, + cutOffFoot, + returnToSarah, + returnToSpria + ), List.of( + rope, + slashItem, + combatGear + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java index 78415423df..3311a96adf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/bearyoursoul/BearYourSoul.java @@ -79,7 +79,7 @@ protected void setupRequirements() { dustyKeyOr70AgilOrKeyMasterTeleport = new KeyringRequirement("Dusty key, or another way to get into the deep Taverley Dungeon", - configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + KeyringCollection.DUSTY_KEY).isNotConsumed(); spade = new ItemRequirement("Spade", ItemID.SPADE).isNotConsumed(); damagedSoulBearer = new ItemRequirement("Damaged soul bearer", ItemID.ARCEUUS_SOULBEARER_DAMAGED); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java index 47de8ce578..e3846db5da 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/belowicemountain/BelowIceMountain.java @@ -34,27 +34,30 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestPointRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcEmoteStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.emote.QuestEmote; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class BelowIceMountain extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java index 83dd2522d6..5253b48f53 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/beneathcursedsands/BeneathCursedSands.java @@ -227,7 +227,7 @@ public Map loadSteps() steps.put(78, returnToZahur); steps.put(80, talkToZahur); - ConditionalStep chemistryPuzzle = new ConditionalStep(this, warmUpChemistryEquipment); + ConditionalStep chemistryPuzzle = new ConditionalStep(this, warmUpChemistryEquipment, "Warm up Zahur's Chemistry Equipment."); chemistryPuzzle.addStep(new Conditions(inChemistryPuzzle, chemistryValveLeftStepZero, new Conditions(LogicType.NAND, chemistryValveMiddleAtMaximum)), chemistryValveIncreaseMiddle); chemistryPuzzle.addStep(new Conditions(inChemistryPuzzle, chemistryValveLeftStepZero, chemistryValveMiddleAtMaximum, new Conditions(LogicType.NAND, chemistryValveRightAtMaximum)), chemistryValveIncreaseRight); chemistryPuzzle.addStep(new Conditions(inChemistryPuzzle, chemistryValveLeftStepZero, chemistryValveMiddleAtMaximum, chemistryValveRightAtMaximum), chemistryValveDecreaseRight); @@ -273,8 +273,7 @@ protected void setupRequirements() waterskins.addAlternates(ItemID.WATER_SKIN3, ItemID.WATER_SKIN2, ItemID.WATER_SKIN1); waterskins.setTooltip("Used for protection against the desert heat"); antipoison = new ItemRequirement("Antipoison", ItemCollections.ANTIPOISONS); - accessToFairyRings = new ItemRequirement("Access to Fairy Rings", ItemID.DRAMEN_STAFF).isNotConsumed(); - accessToFairyRings.addAlternates(ItemID.LUNAR_MOONCLAN_LIMINAL_STAFF); + accessToFairyRings = new ItemRequirement("Access to Fairy Rings", ItemCollections.FAIRY_STAFF).isNotConsumed(); pharaohsSceptre = new ItemRequirement("Pharaoh's sceptre", ItemCollections.PHAROAH_SCEPTRE).isNotConsumed(); pharaohsSceptre.setTooltip("When visiting Necropolis during the quest, you can unlock the direct teleport by using 'Commune' on the Obelisk."); food = new ItemRequirement("Food", -1, -1); @@ -600,7 +599,7 @@ public List getPanels() Collections.singletonList(meleeCombatGear), Arrays.asList(waterskins, food))); allSteps.add(new PanelDetails("The Ruins of Ullek", Arrays.asList(talkToMaisaExploreCliffs, goFromCampsiteToRuinsOfUllek, inspectFurnace, useCoalOnFurnace, useTinderboxOnFurnace, searchWell, readStoneTablet, digForChest, openChest, craftEmblem, useEmblemOnPillar, confirmScarabRotation, enterDungeonToFightScarabMages, fightScarabMages, climbDownStairsAgain, pullLever, pullSecondLever, enterRiddleDoor), Arrays.asList(meleeCombatGear, coal, tinderbox, spade, ironBar), Arrays.asList(food, antipoison, waterskins))); allSteps.add(new PanelDetails("Riddle of the Tomb", Arrays.asList(solveTombRiddle, enterTombDoor, talkToSpirit, takeRustyKey))); - allSteps.add(new PanelDetails("The Champion of Scabaras", Arrays.asList(unlockBossDoor, fightChampionOfScabaras, talkToScabarasHighPriest), Arrays.asList(rangedCombatGear, food, rustyKey))); + allSteps.add(new PanelDetails("The Champion of Scabaras", Arrays.asList(unlockBossDoor, fightChampionOfScabaras, talkToScabarasHighPriest), Arrays.asList(rangedCombatGear, food, rustyKey), Collections.singletonList(antipoison))); allSteps.add(new PanelDetails("Cure for the Pox", Arrays.asList(talkToMaisaInNardah, purchaseBeef, attemptSteppingStones, pickLilyOfElid, takeLilyToZahur, talkToZahur, chemistryPuzzleWrapped, bringCureToPriest), Arrays.asList(meat, waterskins))); allSteps.add(new PanelDetails("Fight with the Menaphite Akh", Arrays.asList(prepareFightMenaphiteAkh, defeatMenaphiteAkh, finishQuest), Arrays.asList(meleeCombatGear, waterskins))); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java index ce4261b542..599a40d694 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/biohazard/Biohazard.java @@ -34,14 +34,27 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -50,10 +63,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class Biohazard extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java index 519d968d12..83034fa512 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/blackknightfortress/BlackKnightFortress.java @@ -7,26 +7,28 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestPointRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class BlackKnightFortress extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java index ecd69d4c0b..8b1e3003ad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/childrenofthesun/ChildrenOfTheSun.java @@ -28,21 +28,29 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.MultiNpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class ChildrenOfTheSun extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java index 4c082429a5..b235536b89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clientofkourend/ClientOfKourend.java @@ -31,6 +31,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; @@ -39,19 +40,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class ClientOfKourend extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java index 46acb955f2..2ff138277c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/clocktower/ClockTower.java @@ -34,6 +34,10 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -41,20 +45,22 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class ClockTower extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java index 4ad5754e8c..f04f5f3252 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/cooksassistant/CooksAssistant.java @@ -29,6 +29,9 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -36,8 +39,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -45,13 +56,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class CooksAssistant extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java index 4fdea31910..547898726d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/creatureoffenkenstrain/CreatureOfFenkenstrain.java @@ -151,7 +151,9 @@ protected void setupRequirements() silverBar = new ItemRequirement("Silver bar", ItemID.SILVER_BAR); bronzeWire = new ItemRequirement("Bronze wire", ItemID.BRONZECRAFTWIRE, 3); needle = new ItemRequirement("Needle", ItemID.NEEDLE).isNotConsumed(); + needle.setTooltip("Costume needle cannot be used as a substitute"); thread = new ItemRequirement("Thread", ItemID.THREAD, 5); + thread.setTooltip("Costume needle cannot be used as a substitute"); spade = new ItemRequirement("Spade", ItemID.SPADE).isNotConsumed(); coins = new ItemRequirement("Coins at least", ItemCollections.COINS, 100); pickledBrain = new ItemRequirement("Pickled Brain", ItemID.FENK_BRAIN); @@ -268,7 +270,7 @@ public void setupSteps() marbleAmulet.highlighted(), obsidianAmulet.highlighted()); - goDownstairsForStar = new ObjectStep(this, ObjectID.FENK_STAIRS_LV1_TOP, new WorldPoint(3573, 3553, 1), + goDownstairsForStar = new ObjectStep(this, ObjectID.FENK_STAIRS_LV1_TOP, new WorldPoint(3537, 3553, 1), "Go back to the ground floor."); talkToGardenerForHead = new NpcStep(this, NpcID.FENK_GARDENER, new WorldPoint(3548, 3562, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java index 97ce8a564d..2a4a10435c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/currentaffairs/CurrentAffairs.java @@ -34,13 +34,25 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.BoardShipStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.SailStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -49,14 +61,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; - public class CurrentAffairs extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java index 8388fcbd67..08816c59f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathontheisle/DeathOnTheIsle.java @@ -37,6 +37,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -45,7 +47,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -54,14 +64,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; - /** * The quest guide for the "Death on the Isle" OSRS quest *

@@ -499,6 +501,7 @@ public void setupSteps() accuseAdala.addDialogStep("Accuse Adala."); fightAdala = new NpcStep(this, NpcID.DOTI_ADALA_MASK_INSIDE, new WorldPoint(1446, 2933, 2), "Fight Adala. You cannot lose this fight."); + fightAdala.addAlternateNpcs(NpcID.DOTI_ADALA_BOSS); accuseAdala.addSubSteps(fightAdala); speakToSuspects = new ConditionalStep(this, accuseAdala); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java index 793be31c67..894d00748c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deathtothedorgeshuun/DeathToTheDorgeshuun.java @@ -48,7 +48,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java index bed24ba5eb..c9f5b58de0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/DemonSlayer.java @@ -30,26 +30,28 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class DemonSlayer extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java index 92ddb2cc21..d377e5721b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/demonslayer/IncantationStep.java @@ -27,13 +27,12 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.HashMap; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.Widget; -import java.util.HashMap; - public class IncantationStep extends ConditionalStep { private final HashMap words = new HashMap<>() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java index d3b3351819..d2e1f0448a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasure/DesertTreasure.java @@ -49,6 +49,7 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.api.NullItemID; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -58,7 +59,6 @@ import net.runelite.api.gameval.VarbitID; import java.util.*; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class DesertTreasure extends BasicQuestHelper @@ -428,7 +428,7 @@ public void setupSteps() talkToArchaeologistAgainAfterTranslation = new NpcStep(this, NpcID.FOURDIAMONDS_INDIANA_VIS, new WorldPoint(3177, 3043, 0), "Talk to the Archaeologist again."); talkToArchaeologistAgainAfterTranslation.addDialogStep("Help him"); talkToArchaeologistAgainAfterTranslation.addTeleport(bedabinTeleport); - buyDrink = new NpcStep(this, NpcID.FOURDIAMONDS_BARTENDER, new WorldPoint(3159, 2978, 0), "Buy a drink from the pub in the Bandit Camp, then talk to the Bartender again.", coins650); + buyDrink = new NpcStep(this, NpcID.FOURDIAMONDS_BARTENDER, new WorldPoint(3159, 2978, 0), "Unequip any god-related items you have on, or else you'll be attacked by bandits. Go buy a drink from the pub in the Bandit Camp, then talk to the Bartender again.", coins650); buyDrink.addDialogStep("Buy a drink"); buyDrink.addDialogStep("Buy a beer"); talkToBartender = new NpcStep(this, NpcID.FOURDIAMONDS_BARTENDER, new WorldPoint(3159, 2978, 0), "Talk to the bartender in the Bandit Camp again."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java index b37cd43295..1c2a8b1d31 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/DesertTreasureII.java @@ -64,7 +64,9 @@ import java.util.*; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class DesertTreasureII extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java index b53c01c74e..709bf37e78 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/PerseriyaSteps.java @@ -47,7 +47,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Prayer; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.Arrays; import java.util.List; @@ -451,9 +455,7 @@ protected void setupConditions() natureAxonPresent = new NpcRequirement(NpcID.DT2_SCAR_MAZE_3_PATHING_NPC, "Abyssal Axon (Nature)"); completedAxonRoom = new VarbitRequirement(VarbitID.DT2_SCAR_MAZE_CHALLENGE_1_DONE, 1); - nothingInHands = and(new NoItemRequirement("Weapon", ItemSlots.WEAPON), - new NoItemRequirement("Shield", ItemSlots.SHIELD)); - ((Conditions) nothingInHands).setText("Nothing equipped in your hands"); + nothingInHands = new NoItemRequirement("Nothing equipped in your hands.", ItemSlots.EMPTY_HANDS); inNorthOfAbyssRoom2 = new ZoneRequirement(northAbyssRoom2P1, northAbyssRoom2P2, northAbyssRoom2P3, northAbyssRoom2P4, northAbyssRoom2P5); inNerveRoom = new ZoneRequirement(nerveRoom1, nerveRoom2, nerveRoom3); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java index 19ddc89833..de5cb1dfd0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deserttreasureii/WhispererSteps.java @@ -1371,7 +1371,7 @@ protected void setupSteps() fightWhispererSidebar.addText("Corrupted seeds: Activate the blackstone fragment in your inventory. Avoid the dark green seeds, and step on the light green ones."); fightWhispererSidebar.addText("Screech: Pillars appear, which you must hide behind to avoid damage."); fightWhispererSidebar.addText("After each special attack, the Whisperer fire out a binding spell if you are within 10 tiles of her, dealing Melee damage."); - fightWhispererSidebar.addText("When she hits 0 health, she will heal back to 100, and start attacking rapidly with random ranged and magic attacks. Finish her off."); + fightWhispererSidebar.addText("When she hits 0 health, she will heal back to 100, and start attacking rapidly, starting with ranged, and alternating every two attacks until the fight ends. Finish her off."); fightWhispererSidebar.addSubSteps(enterTheCathedral, enterRuinsOfCamdozaalFight, descendDownRopeFight); searchEntrails = new ObjectStep(getQuestHelper(), ObjectID.WHISPERER_MEDALLION_LOC, new WorldPoint(2656, 6370, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java index 54925d6b55..0e586106b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/deviousminds/DeviousMinds.java @@ -170,10 +170,9 @@ public void setupSteps() talkToMonk2 = new NpcStep(this, NpcID.DEVIOUS_MONK_HOODED_VISABLE, new WorldPoint(3406, 3494, 0), "Return to the monk near the Paterdomus temple with the bow-sword.", bowSword); talkToMonk2.addDialogStep("Yep, got it right here for you."); - makeIllumPouch = new DetailedQuestStep(this, "Use the Orb on the Large/Colossal Pouch.", orb, largePouch); - + makeIllumPouch = new DetailedQuestStep(this, "Use the Orb on the Large/Colossal Pouch. You will also be going to Entrana via the Abyss, so you must bank all combat gear.", orb, largePouch); teleToAbyss = new NpcStep(this, NpcID.RCU_ZAMMY_MAGE1B, new WorldPoint(3106, 3556, 0), - "Teleport with the Mage of Zamorak IN THE WILDERNESS to the Abyss. You will be attacked by " + + "Teleport with the Mage of Zamorak IN THE WILDERNESS (other players can attack you here) to the Abyss. You will be attacked by " + "monsters upon entering, and your prayer drained to 0!", illumPouch, noEquipment); enterLawRift = new ObjectStep(this, ObjectID.ABYSS_EXIT_TO_LAW, new WorldPoint(3049, 4839, 0), "Enter the central area through a gap/passage/eyes. Enter the Law Rift.", illumPouch, noEquipment); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java index 4172c26e46..5dc9bbf948 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/doricsquest/DoricsQuest.java @@ -35,33 +35,24 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; -import java.util.*; - public class DoricsQuest extends BasicQuestHelper { - //Items Required - ItemRequirement clay, copper, iron; - - //NPC Steps - QuestStep talkToDoric; - - @Override - public Map loadSteps() - { - initializeRequirements(); - setupSteps(); - Map steps = new HashMap<>(); + // Required items + ItemRequirement clay; + ItemRequirement copper; + ItemRequirement iron; - steps.put(0, talkToDoric); - steps.put(10, talkToDoric); - - return steps; - } + // Steps + NpcStep talkToDoric; @Override protected void setupRequirements() @@ -75,25 +66,41 @@ public void setupSteps() { talkToDoric = new NpcStep(this, NpcID.DORIC, new WorldPoint(2951, 3451, 0), "Bring Doric north of Falador all the required items. You can mine them all in the Dwarven Mines, or buy them from the Grand Exchange.", clay, copper, iron); talkToDoric.addDialogStep("I wanted to use your anvils."); + talkToDoric.addDialogStep("Yes."); talkToDoric.addDialogStep("Yes, I will get you the materials."); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToDoric); + steps.put(10, talkToDoric); + + return steps; + } + + @Override public List getGeneralRecommended() { - ArrayList req = new ArrayList<>(); - req.add(new SkillRequirement(Skill.MINING, 15, true, "15 Mining to get ores yourself")); - return req; + return List.of( + new SkillRequirement(Skill.MINING, 15, true, "15 Mining to get ores yourself") + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(clay); - reqs.add(copper); - reqs.add(iron); - return reqs; + return List.of( + clay, + copper, + iron + ); } @Override @@ -105,27 +112,40 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.MINING, 1300)); + return List.of( + new ExperienceReward(Skill.MINING, 1300) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Coins", ItemID.COINS, 180)); + return List.of( + new ItemReward("Coins", ItemID.COINS, 180) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Use of Doric's Anvil")); + return List.of( + new UnlockReward("Use of Doric's Anvil") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); + var sections = new ArrayList(); + + sections.add(new PanelDetails("Help Doric", List.of( + talkToDoric + ), List.of( + clay, + copper, + iron + ))); - allSteps.add(new PanelDetails("Help Doric", Collections.singletonList(talkToDoric), clay, copper, iron)); - return allSteps; + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java index 2fceb71686..d5e7af0eff 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dragonslayer/DragonSlayer.java @@ -45,7 +45,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java index 80cc332f19..1f8b5c5037 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/druidicritual/DruidicRitual.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -36,19 +37,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - /** * The quest guide for the "Druidic Ritual" OSRS quest *

diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java index 7e6ee12102..8c2869f0d9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/dwarfcannon/DwarfCannon.java @@ -30,6 +30,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetPresenceRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -37,18 +39,23 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.WidgetStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class DwarfCannon extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java index 8f0b2679b2..8975eb83aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopi/ElementalWorkshopI.java @@ -49,7 +49,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.ArrayList; import java.util.Arrays; @@ -150,7 +154,7 @@ protected void setupRequirements() slashedBook = new ItemRequirement("Slashed book", ItemID.ELEMENTAL_WORKSHOP_SHIELD_BOOK_SLASHED); slashedBook.setTooltip("If you've lost it you can get another by searching the bookcase in the building south of " + "the odd wall"); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY); + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY); batteredKey.setTooltip("If you've lost it you can get another by searching the bookcase in the building south of " + "the odd wall"); elementalOre = new ItemRequirement("Elemental ore", ItemID.ELEMENTAL_WORKSHOP_ORE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java index fb8073b2e4..321ba648f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/elementalworkshopii/ElementalWorkshopII.java @@ -67,7 +67,7 @@ public class ElementalWorkshopII extends BasicQuestHelper ItemRequirement camelotTeleport, digsiteTeleport; ItemRequirement elementalOre, elementalBar, mindBar, primedBar, beatenBook, scroll, key, craneSchematic, claw, - smallCog, mediumCog, largeCog, pipe; + smallCog, mediumCog, largeCog, pipe, slashedBook; Requirement magic20; @@ -256,7 +256,7 @@ protected void setupRequirements() pickaxe = new ItemRequirement("Any pickaxe", ItemCollections.PICKAXES).isNotConsumed(); hammer = new ItemRequirement("Hammer", ItemCollections.HAMMER).isNotConsumed(); coal = new ItemRequirement("Coal", ItemID.COAL, 8); - batteredKey = new KeyringRequirement("Battered Key", configManager, KeyringCollection.BATTERED_KEY); + batteredKey = new KeyringRequirement("Battered Key", KeyringCollection.BATTERED_KEY); batteredKey.setTooltip("You can get another by searching the bookcase in the house south of the elemental " + "workshop's entrance"); @@ -266,9 +266,9 @@ protected void setupRequirements() elementalOre = new ItemRequirement("Elemental ore", ItemID.ELEMENTAL_WORKSHOP_ORE); elementalOre.addAlternates(ItemID.ELEMENTAL_WORKSHOP_BAR); - elementalBar = new ItemRequirement("Elemental metal", ItemID.ELEMENTAL_WORKSHOP_BAR); + elementalBar = new ItemRequirement("Elemental metal. Bring an additional elemental metal if you want to smith a mind shield after this quest", ItemID.ELEMENTAL_WORKSHOP_BAR); mindBar = new ItemRequirement("Primed mind bar", ItemID.ELEM_MIND_BAR); - primedBar = new ItemRequirement("Primed bar", ItemID.ELEM_PRIMED_BAR); + primedBar = new ItemRequirement("Primed bar. Bring an additional primed bar if you want to smith a mind shield after this quest", ItemID.ELEM_PRIMED_BAR); beatenBook = new ItemRequirement("Beaten book", ItemID.ELEMENTAL_WORKSHOP_HELM_BOOK); beatenBook.setTooltip("You can get another from a bookcase in the Exam Center"); @@ -287,6 +287,10 @@ protected void setupRequirements() pipe = new ItemRequirement("Pipe", ItemID.ELEM2_SPARE_PIPE); magic20 = new SkillRequirement(Skill.MAGIC, 20, true); + + slashedBook = new ItemRequirement("Slashed book if you want to smith a mind shield after this quest", ItemID.ELEMENTAL_WORKSHOP_SHIELD_BOOK_SLASHED); + slashedBook.setTooltip("If you've lost it you can get another by searching the bookcase in the building south of " + + "the odd wall"); } @Override @@ -424,7 +428,7 @@ public void setupSteps() readScroll = new DetailedQuestStep(this, "Read the scroll.", scroll.highlighted()); enterWorkshop = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_SPIRALSTAIRSTOP, new WorldPoint(2711, 3498, 0), - "Enter the elemental workshop.", batteredKey, beatenBook); + "Enter the elemental workshop.", Arrays.asList(batteredKey, beatenBook), Collections.singletonList(slashedBook)); searchMachinery = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_2_BOILER_MULTI, new WorldPoint(2715, 9903, 0), ""); @@ -444,6 +448,7 @@ public void setupSteps() mineRock = new NpcStep(this, NpcID.ELEM1_QIP_EARTH_ELEMENTAL_ROCK_VERSION_ROCK, new WorldPoint(2703, 9894, 0), "You need 2 elemental bars. Mine one of the elemental rocks in the west room, ready to fight a level 35.", true, pickaxe); + mineRock.addText("If you want to smith a mind shield after this quest, get a third elemental ore and also smelt it into a bar."); killRock = new NpcStep(this, NpcID.ELEM1_QIP_EARTH_ELEMENTAL_ROCK_VERSION, new WorldPoint(2703, 9897, 0), "Kill the rock elemental that appeared."); pickUpOre = new ItemStep(this, "Pick up the elemental ore.", elementalOre); @@ -520,7 +525,7 @@ public void setupSteps() raiseCraneFromBar = new ObjectStep(this, ObjectID.ELEM2_FIRE_LEVER_2, new WorldPoint(1953, 5148, 2), "Pull the south west lever to raise the claw once more."); pullLeverToMoveToPress = new ObjectStep(this, ObjectID.ELEM2_LEVER_3WAY, new WorldPoint(1953, 5151, 2), - "Pull the central lever to move the jig to the press."); + "Pull the central lever to activate the press."); lowerPress = new ObjectStep(this, ObjectID.ELEM2_EARTH_LEVER_1, new WorldPoint(1950, 5153, 2), "Pull the west lever to move the jig to the press."); pullLeverToMoveToTank = new ObjectStep(this, ObjectID.ELEM2_LEVER_3WAY, new WorldPoint(1953, 5151, 2), @@ -558,6 +563,7 @@ public void setupSteps() pullLeverToMoveToLava = new ObjectStep(this, ObjectID.ELEM2_LEVER_3WAY, new WorldPoint(1953, 5151, 2), "Pull the central lever to move the jig back to the start."); pickUpBar = new NpcStep(this, NpcID.ELEM2_CART_NPC_FLAT_BAR_DRY, new WorldPoint(1954, 5147, 2), "Pick up the primed bar."); + pickUpBar.addText("If you want to smith a mind shield after this quest, repeat this process one more time."); goDownToBasement = new ObjectStep(this, ObjectID.ELEM2_STAIRS_DOOR_OPEN_NO_HATCH, new WorldPoint(1949, 5159, 2), "Go down from the priming room."); @@ -568,11 +574,13 @@ public void setupSteps() "Sit in the extractor chair.", magic20); takeMindBar = new ObjectStep(this, ObjectID.ELEM_EXTRACTOR_GUN, new WorldPoint(1962, 5148, 0), "Take the mind bar."); + takeMindBar.addText("If you want to smith a mind shield after this quest, repeat this process one more time."); goUpFromBasement = new ObjectStep(this, ObjectID.ELEM2_STAIRS2, new WorldPoint(1949, 5160, 0), "Go up the stairs."); makeMindHelmet = new ObjectStep(this, ObjectID.ELEMENTAL_WORKSHOP_WORKBENCH, new WorldPoint(2717, 9888, 0), - "Use the mind bar on one of the workbenches in the central room.", mindBar.highlighted(), hammer, + "Use the mind bar on one of the workbenches in the central room with the beaten book in your inventory.", mindBar.highlighted(), hammer, beatenBook); + makeMindHelmet.addText("If you want to smith a mind shield after this quest, use the remaining mind bar on one of the workbenches with the slashed book in your inventory."); makeMindHelmet.addIcon(ItemID.ELEM_MIND_BAR); goToWorkshopTopFloor = new ConditionalStep(this, enterWorkshop); @@ -605,7 +613,7 @@ public List getItemRequirements() @Override public List getItemRecommended() { - return Arrays.asList(digsiteTeleport, camelotTeleport); + return Arrays.asList(digsiteTeleport, camelotTeleport, slashedBook); } @Override @@ -656,8 +664,8 @@ public ArrayList getPanels() ArrayList allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Starting off", Arrays.asList(searchBookcase, readBook, readScroll))); - allSteps.add(new PanelDetails("Unlocking the Hatch", Arrays.asList(getKey, unlockHatch), batteredKey, pickaxe, - coal.quantity(8), hammer)); + allSteps.add(new PanelDetails("Unlocking the Hatch", Arrays.asList(getKey, unlockHatch), Arrays.asList(batteredKey, pickaxe, + coal.quantity(8), hammer, beatenBook), Collections.singletonList(slashedBook))); allSteps.add(new PanelDetails("Repairing the crane", Arrays.asList(takeSchematics, goMakeClaw, goRepairCrane))); allSteps.add(new PanelDetails("Repairing the workshop", Arrays.asList(goSortTubes, getCogsAndPipe, goRepairPipe, goPlaceCogs))); @@ -666,10 +674,10 @@ public ArrayList getPanels() pullLeverToMoveToPress, lowerPress, pullLeverToMoveToTank, pullLeverToOpenTankDoor, turnCorkscrew, turnCorkscrewAgain, pullLeverToCloseTankDoor, turnWestValve, turnEastValve, turnEastValveAgain, turnWestValveAgain, pullLeverToOpenTankDoorAgain, turnCorkscrewToRetrieve, turnCorkscrewToRetrieveAgain, pullLeverToCloseTankDoorAgain, pullLeverToMoveToFan, pullFanLever, - pullFanLeverAgain, pullLeverToMoveToLava, pickUpBar), elementalBar)); + pullFanLeverAgain, pullLeverToMoveToLava, pickUpBar), Collections.singletonList(elementalBar))); allSteps.add(new PanelDetails("Making a Mind Helm", Arrays.asList(goDownToBasement, useBarOnGun, operateHat, - takeMindBar, goMakeMindHelmet), primedBar, hammer, beatenBook)); + takeMindBar, goMakeMindHelmet), Arrays.asList(primedBar, hammer, beatenBook), Collections.singletonList(slashedBook))); return allSteps; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java index b1a5569109..39713541b0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enakhraslament/EnakhrasLament.java @@ -51,10 +51,7 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class EnakhrasLament extends BasicQuestHelper { @@ -265,7 +262,10 @@ protected void setupRequirements() camelHead.setHighlightInInventory(true); breadOrCake = new ItemRequirement("Bread or cake", ItemID.BREAD); - breadOrCake.addAlternates(ItemID.CAKE); + // Excluded mud pie, botanical pie, mushroom pie, dragonfruit pie as unsure if those would work due to inedibility and/or newness of pie + breadOrCake.addAlternates(ItemID.CAKE, ItemID.CHOCOLATE_CAKE, ItemID.REDBERRY_PIE, ItemID.MEAT_PIE, ItemID.APPLE_PIE, ItemID.GARDEN_PIE, ItemID.FISH_PIE, ItemID.ADMIRAL_PIE, ItemID.WILD_PIE, ItemID.SUMMER_PIE); + breadOrCake.addAlternates(ItemID.PLAIN_PIZZA, ItemID.MEAT_PIZZA, ItemID.ANCHOVIE_PIZZA, ItemID.PINEAPPLE_PIZZA); + breadOrCake.addAlternates(ItemID.POTATO_BUTTER, ItemID.POTATO_CHILLI_CARNE, ItemID.POTATO_CHEESE, ItemID.POTATO_EGG_TOMATO, ItemID.POTATO_MUSHROOM_ONION, ItemID.POTATO_TUNA_SWEETCORN); breadOrCake.setHighlightInInventory(true); breadOrCake.setDisplayMatchedItemName(true); @@ -469,7 +469,8 @@ public void setupSteps() goUpFromPuzzleRoom = new ObjectStep(this, ObjectID.ENAKH_TEMPLE_LADDERUP, new WorldPoint(3104, 9332, 1), "Go up the ladder."); passBarrier.addSubSteps(goUpFromPuzzleRoom); - castCrumbleUndead = new NpcStep(this, NpcID.ENAKH_BONEGUARD, new WorldPoint(3104, 9307, 2), "Cast crumble undead on the Boneguard.", earth2, + castCrumbleUndead = new NpcStep(this, NpcID.ENAKH_BONEGUARD, new WorldPoint(3104, 9307, 2), "Cast crumble undead on the Boneguard. " + + "Make sure you take off any armour or weapons which give you a negative magic attack bonus or else you might splash.", earth2, airRuneOrStaff, chaos, onNormals); goDownToFinalRoom = new ObjectStep(this, ObjectID.ENAKH_TEMPLE_PILLAR_LADDER_TOP, new WorldPoint(3105, 9300, 2), "Climb down the stone ladder past " + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java index 823408f905..db91052f07 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/enlightenedjourney/EnlightenedJourney.java @@ -196,7 +196,7 @@ public void setupSteps() "Bowl."); talkToAugusteWithBranches = new ObjectStep(this, ObjectID.ZEP_MULTI_BASKET_ENTRANA, new WorldPoint(2807, 3356, 0), - "Get 12 willow branches and use them to make the basket.", willowBranches12.highlighted()); + "Get 12 willow branches and use them on the platform next to Auguste to make the basket.", willowBranches12.highlighted()); talkToAugusteWithBranches.addIcon(ItemID.WILLOW_BRANCH); talkToAugusteWithLogsAndTinderbox = new NpcStep(this, NpcID.ZEP_PICCARD, new WorldPoint(2809, 3354, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java index f02e3723d9..8804eb7698 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytalei/FairytaleI.java @@ -216,6 +216,7 @@ public void setupSteps() "you're right!"); talkToFarmers = new NpcStep(this, NpcID.ELSTAN, "Talk to 5 farmers, then return to Martin in Draynor Village. The recommended 5 are:"); + talkToFarmers.addText("If you don't already have one, a secateurs can be purchased from Sarah in South Falador Farm"); talkToFarmers.addText("Frizzy in Port Sarim."); talkToFarmers.addText("Elstan north west of Draynor."); talkToFarmers.addText("Heskel in Falador Park."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java index e582ddf6ba..26ea977cd5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fairytaleii/FairytaleII.java @@ -266,10 +266,10 @@ public void setupSteps() dramenOrLunarStaff.equipped()); goToHideout = new ObjectStep(this, ObjectID.FAIRYRING_HOMEHUB, new WorldPoint(2412, 4434, 0), - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); goToHideoutSurface = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); goToHideout.addSubSteps(goToHideoutSurface); //varp 817 2->112->133->31 for each destination @@ -285,20 +285,20 @@ public void setupSteps() pickpocketGodfather.addSubSteps(returnToZanarisFromBase, goToZanarisToPickpocket); goToHideoutWithSec = new ObjectStep(this, ObjectID.FAIRYRING_HOMEHUB, new WorldPoint(2412, 4434, 0), - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate, queensSecateurs); goToHideoutSurfaceWithSec = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate, queensSecateurs); giveSecateursToNuff = new NpcStep(this, NpcID.FAIRY_NUFF2, new WorldPoint(2355, 4455, 0), "Give Fairy Nuff the Queen's Secateurs.", queensSecateurs); goToHideoutAfterSec = new ObjectStep(this, ObjectID.FAIRYRING_HOMEHUB, new WorldPoint(2412, 4434, 0), - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); goToHideoutSurfaceAfterSec = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); talkToNuffAfterSec = new NpcStep(this, NpcID.FAIRY_NUFF2, new WorldPoint(2355, 4455, 0), "Talk to Fairy Nuff."); @@ -327,7 +327,7 @@ public void setupSteps() gorakClawPowder.highlighted(), magicEssenceUnf.highlighted(), herbReq); goToHideout2 = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate, magicEssence); ((ObjectStep) goToHideout2).addAlternateObjects(ObjectID.FAIRYRING_HOMEHUB); @@ -336,7 +336,7 @@ public void setupSteps() usePotionOnQueen.addIcon(ItemID._3DOSEMAGICESS); goToHideoutToFinish = new ObjectStep(this, ObjectID.FAIRYRING_MINORHUB, - "Use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); + "While carrying Nuff's certificate, use the Fairy Rings to travel to A.I.R., D.L.R., D.J.Q. then A.J.S.", dramenOrLunarStaff.equipped(), fairyCertificate); ((ObjectStep) goToHideoutToFinish).addAlternateObjects(ObjectID.FAIRYRING_HOMEHUB); talkToQueen = new NpcStep(this, NpcID.FAIRY_QUEEN2, new WorldPoint(2354, 4455, 0), "Talk to the Fairy Queen."); @@ -414,7 +414,7 @@ public ArrayList getPanels() allSteps.add(new PanelDetails("Making a cure", Arrays.asList(goToCkp, waitForStarFlower, pickStarFlower, goToDir, killGorak, pickupGorakClaw, useStarFlowerOnVial, usePestleOnClaw, usePowderOnPotion, - goToHideout2, usePotionOnQueen, talkToQueen), dramenOrLunarStaff, vialOfWater, pestleAndMortar)); + goToHideout2, usePotionOnQueen, talkToQueen), dramenOrLunarStaff, vialOfWater, pestleAndMortar, fairyCertificate)); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java index 8d6552c90a..4376f9b050 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/fightarena/FightArena.java @@ -32,6 +32,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -41,19 +42,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class FightArena extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java index 3c6629d302..aa59562de7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/forgettabletale/ForgettableTale.java @@ -69,7 +69,7 @@ public class ForgettableTale extends BasicQuestHelper Requirement inKelgdagrim, inWolfUnderground, inPubUpstairs, inConsortium, inPuzzleRoom, givenBeerToDrunkenDwarf, rowdyDwarfMadeRequest, gotRowdySeed, gotKhorvakSeed, gotGaussSeed, plotRaked, keldaGrowing, keldaGrown, - addedWater, addedYeast, addedHop, addedMalt, keldaBrewed, keldaInBarrel, handsFree, shieldFree; + addedWater, addedYeast, addedHop, addedMalt, keldaBrewed, keldaInBarrel, handsFree; Requirement inPurple, inYellow, inBlue, inGreen, inSilver, inWhite, inBrown; @@ -448,8 +448,7 @@ public void setupConditions() inSilver = new VarbitRequirement(VarbitID.GIANTDWARF_CURRENT_COMPANY, 6); // Silver Cog inBrown = new VarbitRequirement(VarbitID.GIANTDWARF_CURRENT_COMPANY, 7); // Brown Engine - handsFree = new NoItemRequirement("No weapon equipped", ItemSlots.WEAPON); - shieldFree = new NoItemRequirement("No shield equipped", ItemSlots.SHIELD); + handsFree = new NoItemRequirement("No weapon or shield equipped", ItemSlots.EMPTY_HANDS); // 837 = 1, entered first puzzle // 839 = 1, cutscene entering done @@ -654,7 +653,7 @@ else if (inBrown.check(client)) goDownFromDirector = new ObjectStep(this, ObjectID.DWARF_KELDAGRIM_WIDE_STAIRS_UPPER, new WorldPoint(2895, 10210, 1), "Go downstairs."); takeSecretCart = new ObjectStep(this, ObjectID.KELDAGRIM_TRAIN_CART, new WorldPoint(2919, 10164, 0), - "", handsFree, shieldFree); + "", handsFree); searchBox1 = new ObjectStep(this, ObjectID.KELDAGRIM_TRACK_JUNCTION_CARD_BOX, new WorldPoint(1862, 4954, 1), "Search the box."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java index 8a33e11140..2fcf1cf347 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gardenoftranquility/GardenOfTranquillity.java @@ -457,7 +457,7 @@ public void setupSteps() wateringCan.highlighted()); talkToAlthric = new NpcStep(this, NpcID.BROTHER_ALTHRIC, new WorldPoint(3052, 3502, 0), - "Talk to Brother Altheric in the Edgeville Monastery.", ringOfCharosA.equipped()); + "Talk to Brother Althric in the Edgeville Monastery.", ringOfCharosA.equipped()); talkToAlthric.addDialogSteps("[Charm] These are the most beautiful rosebushes I've ever seen."); useCharosOnWell = new ObjectStep(this, ObjectID.WELL, new WorldPoint(3085, 3503, 0), "Use the Ring of charos(a) on the well in Edgeville.", ringOfCharosA.highlighted()); @@ -571,7 +571,7 @@ public void setupSteps() talkToEllmariaAfterGrown = new NpcStep(this, NpcID.QUEEN_ELLAMARIA, new WorldPoint(3230, 3478, 0), "Talk to Ellamaria once everything's finished growing."); - talkToRoald = new NpcStep(this, NpcID.KING_ROALD_CUTSCENE, new WorldPoint(3221, 3473, 0), + talkToRoald = new NpcStep(this, NpcID.KING_ROALD, new WorldPoint(3221, 3473, 0), "Talk to King Roald in Varrock Castle, watch the cutscene, then finish the dialog with Ellamaria to finish" + " the quest!", ringOfCharosA.equipped()); talkToRoald.addDialogSteps("Ask King Roald to follow me.", "[Charm] Of course, your majesty - please forgive " + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java index 25d3ace8fa..83a56940a5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/gertrudescat/GertrudesCat.java @@ -29,7 +29,9 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -37,20 +39,21 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class GertrudesCat extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java index 8208a58865..2bad7e60a2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ghostsahoy/DyeShipSteps.java @@ -38,15 +38,12 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.text.Rs2TextSanitizer; -import lombok.extern.slf4j.Slf4j; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; -@Slf4j public class DyeShipSteps extends DetailedOwnerStep { boolean coloursKnown = false; @@ -99,54 +96,36 @@ private void updateCurrentColours() { return; } - String normalized = Rs2TextSanitizer.normalizeGameText(text); - String[] splitOnNewLines = normalized.split("
"); - boolean handledLines = false; + String[] splitOnNewLines = text.split("
"); if (splitOnNewLines.length > 1) { for (String splitOnNewLine : splitOnNewLines) { - if (updateCurrentColoursFromString(Rs2TextSanitizer.stripTagsToSpace(splitOnNewLine))) - { - handledLines = true; - } + updateCurrentColoursFromString(splitOnNewLine); } } - if (handledLines) - { - return; - } - String plain = Rs2TextSanitizer.stripTagsToSpace(normalized); - String[] splitText = plain.split("dye the "); + String[] splitText = text.split("dye the "); if (splitText.length < 2) { - if (log.isDebugEnabled()) - { - int h = plain.hashCode(); - int len = plain.length(); - String prefix = plain.length() > 60 ? plain.substring(0, 60) + "…" : plain; - log.debug("DyeShipSteps: expected 'dye the ' in objectbox text; len={} hash={} prefix='{}'", len, Integer.toHexString(h), prefix); - } return; } updateCurrentColoursFromString(splitText[1]); } - private boolean updateCurrentColoursFromString(String text) + private void updateCurrentColoursFromString(String text) { String[] shapeAndColour = text.split(" (emblem|of the flag) "); if (shapeAndColour.length < 2) { - return false; + return; } String shape = shapeAndColour[0]; String colour = shapeAndColour[1]; shape = shape.replace("The ", ""); colour = colour.replace("is ", ""); currentColours.put(shape, FlagColour.findByKey(colour)); - return true; } public void updateSteps() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java index 899c5a3926..1327f9eb07 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/goblindiplomacy/GoblinDiplomacy.java @@ -26,17 +26,24 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -44,62 +51,47 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class GoblinDiplomacy extends BasicQuestHelper { - //Required items - ItemRequirement goblinMailThree, orangeDye, blueDye, goblinMail, goblinMailTwo, blueArmour, orangeArmour, mailReq; - - Requirement isUpstairs, hasUpstairsArmour, hasWestArmour, hasNorthArmour; - - QuestStep talkToGeneral1, talkToGeneral2, talkToGeneral3, goUpLadder, searchUpLadder, goDownLadder, searchWestHut, searchBehindGenerals, - dyeOrange, dyeBlue, getCrate2, getCrate3; - - //Zones + // Required items + ItemRequirement goblinMailThree; + ItemRequirement orangeDye; + ItemRequirement blueDye; + + // Mid-quest item requirements + ItemRequirement goblinMail; + ItemRequirement goblinMailTwo; + ItemRequirement blueArmour; + ItemRequirement orangeArmour; + ItemRequirement mailReq; + + // Zones Zone upstairs; + // Miscellaneous requirements + ZoneRequirement isUpstairs; + VarbitRequirement hasUpstairsArmour; + VarbitRequirement hasWestArmour; + VarbitRequirement hasNorthArmour; + + // Steps + NpcStep talkToGeneral1; + NpcStep talkToGeneral2; + NpcStep talkToGeneral3; + ObjectStep goUpLadder; + ObjectStep searchUpLadder; + ObjectStep goDownLadder; + ObjectStep searchWestHut; + ObjectStep searchBehindGenerals; + DetailedQuestStep dyeOrange; + DetailedQuestStep dyeBlue; + DetailedQuestStep getCrate2; + DetailedQuestStep getCrate3; + @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - ConditionalStep lootArmour = new ConditionalStep(this, goUpLadder); - lootArmour.addStep(new Conditions(isUpstairs, hasUpstairsArmour), goDownLadder); - lootArmour.addStep(new Conditions(hasUpstairsArmour, hasWestArmour), searchBehindGenerals); - lootArmour.addStep(hasUpstairsArmour, searchWestHut); - lootArmour.addStep(isUpstairs, searchUpLadder); - - ConditionalStep prepareForQuest = new ConditionalStep(this, lootArmour); - prepareForQuest.addStep(new Conditions(goblinMail, blueArmour), dyeOrange); - prepareForQuest.addStep(new Conditions(LogicType.OR, goblinMailThree, new Conditions(hasUpstairsArmour, hasWestArmour, - hasNorthArmour)), dyeBlue); - - ConditionalStep step1 = new ConditionalStep(this, prepareForQuest); - step1.addStep(new Conditions(goblinMail, blueArmour, orangeArmour), talkToGeneral1); - - steps.put(0, step1); - steps.put(3, step1); - - ConditionalStep prepareBlueArmour = new ConditionalStep(this, lootArmour); - prepareBlueArmour.addStep(new Conditions(LogicType.OR, goblinMailTwo, new Conditions(hasUpstairsArmour, hasWestArmour, - hasNorthArmour)), dyeBlue); - - ConditionalStep step2 = new ConditionalStep(this, prepareBlueArmour); - step2.addStep(blueArmour, talkToGeneral2); - - steps.put(4, step2); - - ConditionalStep step3 = new ConditionalStep(this, lootArmour); - step3.addStep(new Conditions(LogicType.OR, goblinMail, new Conditions(hasUpstairsArmour, hasWestArmour, - hasNorthArmour)), talkToGeneral3); - - steps.put(5, step3); - - return steps; + upstairs = new Zone(new WorldPoint(2952, 3495, 2), new WorldPoint(2959, 3498, 2)); } @Override @@ -123,26 +115,16 @@ protected void setupRequirements() blueArmour = new ItemRequirement("Blue goblin mail", ItemID.GOBLIN_ARMOUR_DARKBLUE); orangeArmour = new ItemRequirement("Orange goblin mail", ItemID.GOBLIN_ARMOUR_ORANGE); - } - public void setupConditions() - { isUpstairs = new ZoneRequirement(upstairs); hasUpstairsArmour = new VarbitRequirement(VarbitID.GOBDIP_CRATE3_SEARCHED, 1); hasWestArmour = new VarbitRequirement(VarbitID.GOBDIP_CRATE2_SEARCHED, 1); hasNorthArmour = new VarbitRequirement(VarbitID.GOBDIP_CRATE1_SEARCHED, 1); } - @Override - protected void setupZones() - { - upstairs = new Zone(new WorldPoint(2952, 3495, 2), new WorldPoint(2959, 3498, 2)); - } - public void setupSteps() { - goUpLadder = new ObjectStep(this, ObjectID.GOBLIN_LADDER_BOTTOM, new WorldPoint(2954, 3497, 0), "You need three goblin mails, which you can find around the Goblin " + - "Village. The first is up the ladder in a crate in the south of the village."); + goUpLadder = new ObjectStep(this, ObjectID.GOBLIN_LADDER_BOTTOM, new WorldPoint(2954, 3497, 0), "You need three goblin mails, which you can find around the Goblin Village. The first is up the ladder in a crate in the south of the village."); searchUpLadder = new ObjectStep(this, ObjectID.GOBLIN_OUTPOST_LARGE_CRATE_ARMOUR3, new WorldPoint(2955, 3498, 2), "Search the crate up the ladder."); goUpLadder.addSubSteps(searchUpLadder); goDownLadder = new ObjectStep(this, ObjectID.GOBLIN_LADDER_TOP, new WorldPoint(2954, 3497, 2), "Go back down the ladder."); @@ -158,10 +140,11 @@ public void setupSteps() dyeOrange = new DetailedQuestStep(this, "Use the orange dye on one of the goblin mail.", orangeDye, goblinMail); talkToGeneral1 = new NpcStep(this, NpcID.GENERAL_BENTNOZE_RED, new WorldPoint(2958, 3512, 0), "Talk to one of the Goblin Generals in Goblin Village.", orangeArmour); - talkToGeneral1.addDialogStep("So how is life for the goblins?"); - talkToGeneral1.addDialogStep("Yes, Wartface looks fat"); talkToGeneral1.addDialogStep("Do you want me to pick an armour colour for you?"); talkToGeneral1.addDialogStep("What about a different colour?"); + talkToGeneral1.addDialogStep("Yes."); + talkToGeneral1.addDialogStep("So how is life for the goblins?"); + talkToGeneral1.addDialogStep("Yes, Wartface looks fat"); talkToGeneral1.addDialogStep("I have some orange armour here."); talkToGeneral2 = new NpcStep(this, NpcID.GENERAL_BENTNOZE_RED, new WorldPoint(2958, 3512, 0), "Talk to one of the Goblin Generals in Goblin Village again.", blueArmour); @@ -174,14 +157,54 @@ public void setupSteps() talkToGeneral3.addDialogStep("I have some brown armour here."); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + var lootArmour = new ConditionalStep(this, goUpLadder); + lootArmour.addStep(and(isUpstairs, hasUpstairsArmour), goDownLadder); + lootArmour.addStep(and(hasUpstairsArmour, hasWestArmour), searchBehindGenerals); + lootArmour.addStep(hasUpstairsArmour, searchWestHut); + lootArmour.addStep(isUpstairs, searchUpLadder); + + var prepareForQuest = new ConditionalStep(this, lootArmour); + prepareForQuest.addStep(and(goblinMail, blueArmour), dyeOrange); + prepareForQuest.addStep(or(goblinMailThree, and(hasUpstairsArmour, hasWestArmour, hasNorthArmour)), dyeBlue); + + var step1 = new ConditionalStep(this, prepareForQuest); + step1.addStep(and(goblinMail, blueArmour, orangeArmour), talkToGeneral1); + + steps.put(0, step1); + steps.put(3, step1); + + var prepareBlueArmour = new ConditionalStep(this, lootArmour); + prepareBlueArmour.addStep(or(goblinMailTwo, and(hasUpstairsArmour, hasWestArmour, hasNorthArmour)), dyeBlue); + + var step2 = new ConditionalStep(this, prepareBlueArmour); + step2.addStep(blueArmour, talkToGeneral2); + + steps.put(4, step2); + + var step3 = new ConditionalStep(this, lootArmour); + step3.addStep(or(goblinMail, and(hasUpstairsArmour, hasWestArmour, hasNorthArmour)), talkToGeneral3); + + steps.put(5, step3); + + return steps; + } + @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(blueDye); - reqs.add(orangeDye); - reqs.add(mailReq); - return reqs; + return List.of( + blueDye, + orangeDye, + mailReq + ); } @Override @@ -193,24 +216,42 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.CRAFTING, 200)); + return List.of( + new ExperienceReward(Skill.CRAFTING, 200) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("A Gold Bar", ItemID.GOLD_BAR, 1)); + return List.of( + new ItemReward("A Gold Bar", ItemID.GOLD_BAR, 1) + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - PanelDetails getArmours = new PanelDetails("Prepare goblin mail", - Arrays.asList(goUpLadder, getCrate2, getCrate3, dyeBlue, dyeOrange), blueDye, orangeDye, goblinMailThree); - allSteps.add(getArmours); - - allSteps.add(new PanelDetails("Present the armours", Arrays.asList(talkToGeneral1, talkToGeneral2, talkToGeneral3))); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Prepare goblin mail", List.of( + goUpLadder, + getCrate2, + getCrate3, + dyeBlue, + dyeOrange + ), List.of( + blueDye, + orangeDye, + goblinMailThree + ))); + + sections.add(new PanelDetails("Present the armours", List.of( + talkToGeneral1, + talkToGeneral2, + talkToGeneral3 + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java index 4a337966ef..ae7d3678c9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/grimtales/GrimTales.java @@ -167,7 +167,8 @@ protected void setupRequirements() tarrominUnfHighlight = new ItemRequirement("Tarromin potion (unf)", ItemID.TARROMINVIAL); tarrominUnfHighlight.setHighlightInInventory(true); - dibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).isNotConsumed(); + var knowsBarbarianPlanting = new VarbitRequirement(VarbitID.BRUT_FARMING_PLANTING, 3); + dibber = new ItemRequirement("Seed dibber", ItemID.DIBBER).hideConditioned(knowsBarbarianPlanting).isNotConsumed(); can = new ItemRequirement("Watering can with at least 1 use", ItemCollections.WATERING_CANS).isNotConsumed(); can.setTooltip("Gricollers' can is also valid. "); axe = new ItemRequirement("Any axe", ItemCollections.AXES).isNotConsumed(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java index d945cd5e5c..edae421f0e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hauntedmine/HauntedMine.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; @@ -293,7 +297,7 @@ public void setupSteps() pullLeverG = new ObjectStep(this, ObjectID.HAUNTEDMINE_POINT_LEVER7, new WorldPoint(2769, 4533, 0), "Pull the marked lever."); pullLeverH = new ObjectStep(this, ObjectID.HAUNTEDMINE_POINT_LEVER8, new WorldPoint(2770, 4533, 0), "Pull the marked lever."); - solvePuzzle = new DetailedQuestStep(this, "Pull levers until the tracks are lined up to take the cart to the north east corner."); + solvePuzzle = new DetailedQuestStep(this, "Pull levers until the tracks are lined up to take the cart to the north west corner (the panel's map UI shows north as pointing to the right)."); solvePuzzle.addSubSteps(pullLeverA, pullLeverB, pullLeverC, pullLeverD, pullLeverE, pullLeverF, pullLeverG, pullLeverH); useKeyOnValve = new ObjectStep(this, ObjectID.HAUNTEDMINE_LIFT_VALVE, new WorldPoint(2808, 4496, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java index 73dd07c317..d400971199 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/hazeelcult/HazeelCult.java @@ -31,6 +31,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -38,7 +40,17 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.MultiNpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -46,11 +58,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class HazeelCult extends BasicQuestHelper { // Recommended items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java index a8a70fd117..78e7348ff1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/heroesquest/HeroesQuest.java @@ -198,8 +198,8 @@ protected void setupRequirements() fishingRod.addAlternates(ItemID.OILY_FISHING_ROD); fishingBait = new ItemRequirement("Fishing bait", ItemID.FISHING_BAIT); jailKey = new ItemRequirement("Jail key", ItemID.JAIL_KEY).isNotConsumed(); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); - dustyKeyHint = new KeyringRequirement("Dusty key (obtainable in quest)", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).isNotConsumed(); + dustyKeyHint = new KeyringRequirement("Dusty key (obtainable in quest)", KeyringCollection.DUSTY_KEY).isNotConsumed(); harralanderUnf = new ItemRequirement("Harralander potion (unf)", ItemID.HARRALANDERVIAL); pickaxe = new ItemRequirement("Any pickaxe", ItemID.BRONZE_PICKAXE).isNotConsumed(); pickaxe.addAlternates(ItemCollections.PICKAXES); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java index e31e9b165c..b7e6b1d2e0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/holygrail/HolyGrail.java @@ -38,12 +38,24 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -51,13 +63,6 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class HolyGrail extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java index e7673923e4..4c90a01025 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/impcatcher/ImpCatcher.java @@ -33,18 +33,21 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class ImpCatcher extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java index edbb3e5c4c..3cfa329b5b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/junglepotion/JunglePotion.java @@ -36,7 +36,15 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -44,33 +52,61 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class JunglePotion extends BasicQuestHelper { - //Items Required - ItemRequirement grimySnakeWeed, snakeWeed, grimyArdrigal, ardrigal, grimySitoFoil, sitoFoil, grimyVolenciaMoss, volenciaMoss, - roguesPurse, grimyRoguesPurse; - - QuestStep startQuest, finishQuest; - - ObjectStep getSnakeWeed, getArdrigal, getSitoFoil, getVolenciaMoss, enterCave, getRoguePurseHerb; - - ConditionalStep cleanAndReturnSnakeWeed, cleanAndReturnArdrigal, cleanAndReturnSitoFoil, cleanAndReturnVolenciaMoss, - getRoguesPurse, cleanAndReturnRoguesPurse; - + // Recommended items + ItemRequirement food; + ItemRequirement antipoison; + ItemRequirement karaTele; + + // Mid-quest item requirements + ItemRequirement grimySnakeWeed; + ItemRequirement snakeWeed; + ItemRequirement grimyArdrigal; + ItemRequirement ardrigal; + ItemRequirement grimySitoFoil; + ItemRequirement sitoFoil; + ItemRequirement grimyVolenciaMoss; + ItemRequirement volenciaMoss; + ItemRequirement roguesPurse; + ItemRequirement grimyRoguesPurse; + + // Zones + Zone undergroundZone; + + // Miscellaneous requirements ZoneRequirement isUnderground; + // Steps + NpcStep startQuest; + ObjectStep getSnakeWeed; + ConditionalStep cleanAndReturnSnakeWeed; + ObjectStep getArdrigal; + ConditionalStep cleanAndReturnArdrigal; + ObjectStep getSitoFoil; + ConditionalStep cleanAndReturnSitoFoil; + ObjectStep getVolenciaMoss; + ConditionalStep cleanAndReturnVolenciaMoss; + ObjectStep enterCave; + ObjectStep getRoguePurseHerb; + ConditionalStep getRoguesPurse; + ConditionalStep cleanAndReturnRoguesPurse; + NpcStep finishQuest; + @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - return getSteps(); + undergroundZone = new Zone(new WorldPoint(2824, 9462, 0), new WorldPoint(2883, 9533, 0)); } @Override protected void setupRequirements() { + food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); + antipoison = new ItemRequirement("Antipoison", ItemCollections.ANTIPOISONS); + karaTele = new ItemRequirement("Teleport to Karamja (Glory/house teleport)", ItemID.NZONE_TELETAB_BRIMHAVEN); + karaTele.addAlternates(ItemCollections.AMULET_OF_GLORIES); + grimySnakeWeed = new ItemRequirement("Grimy Snake Weed", ItemID.UNIDENTIFIED_SNAKE_WEED); grimySnakeWeed.setHighlightInInventory(true); snakeWeed = new ItemRequirement("Snake Weed", ItemID.SNAKE_WEED); @@ -90,116 +126,53 @@ protected void setupRequirements() grimyRoguesPurse = new ItemRequirement("Grimy Rogues Purse", ItemID.UNIDENTIFIED_ROGUES_PURSE); grimyRoguesPurse.setHighlightInInventory(true); roguesPurse = new ItemRequirement("Rogues Purse", ItemID.ROGUES_PURSE); - } - @Override - protected void setupZones() - { - //2824,9462,0 - //2883, 9533, 0 - Zone undergroundZone = new Zone(new WorldPoint(2824, 9462, 0), new WorldPoint(2883, 9533, 0)); isUnderground = new ZoneRequirement(undergroundZone); } - private Map getSteps() - { - Map steps = new HashMap<>(); - - steps.put(0, startQuestStep()); - steps.put(1, getSnakeWeed()); - steps.put(2, returnSnakeWeed()); - steps.put(3, getArdrigal()); - steps.put(4, returnArdigal()); - steps.put(5, getSitoFoil()); - steps.put(6, returnSitoFoil()); - steps.put(7, getVolenciaMoss()); - steps.put(8, returnVolenciaMoss()); - steps.put(9, getRoguesPurse()); - steps.put(10, returnRoguesPurse()); - steps.put(11, finishQuestStep()); - return steps; - } - - private QuestStep startQuestStep() - { - startQuest = talkToTrufitus("Talk to Trufitus in Tai Bwo Wannai on Karamja."); - startQuest.addDialogSteps("It's a nice village, where is everyone?"); - startQuest.addDialogSteps("Me? How can I help?"); - startQuest.addDialogSteps("It sounds like just the challenge for me."); - return startQuest; - } - - private QuestStep returnArdigal() - { - return cleanAndReturnArdrigal = getReturnHerbStep("Ardrigal", grimyArdrigal, ardrigal); - } - - private QuestStep returnSnakeWeed() - { - return cleanAndReturnSnakeWeed = getReturnHerbStep("Snake Weed", grimySnakeWeed, snakeWeed); - } - - private QuestStep returnSitoFoil() - { - return cleanAndReturnSitoFoil = getReturnHerbStep("Sito Foil", grimySitoFoil, sitoFoil); - } - - private QuestStep returnVolenciaMoss() - { - return cleanAndReturnVolenciaMoss = getReturnHerbStep("Volencia Moss", grimyVolenciaMoss, volenciaMoss); - } - - private QuestStep returnRoguesPurse() - { - cleanAndReturnRoguesPurse = getReturnHerbStep("Rogues Purse", grimyRoguesPurse, roguesPurse); - cleanAndReturnRoguesPurse.addStep(isUnderground, new ObjectStep(this, - ObjectID.JP_CAVEROCKSOUT, new WorldPoint(2830, 9522, 0), "Climb out of the cave.")); - return cleanAndReturnRoguesPurse; - } - private ConditionalStep getReturnHerbStep(String herbName, ItemRequirement grimyHerb, ItemRequirement cleanHerb) { NpcStep returnHerb = talkToTrufitus("", cleanHerb); returnHerb.addDialogSteps("Of course!"); - DetailedQuestStep cleanGrimyHerb = new DetailedQuestStep(this, "", grimyHerb); + var cleanGrimyHerb = new DetailedQuestStep(this, "", grimyHerb); - ConditionalStep cleanAndReturnHerb = new ConditionalStep(this, cleanGrimyHerb, "Clean and return the " + herbName + " to Trufitus."); + var cleanAndReturnHerb = new ConditionalStep(this, cleanGrimyHerb, "Clean and return the " + herbName + " to Trufitus."); cleanAndReturnHerb.addStep(cleanHerb, returnHerb); return cleanAndReturnHerb; } - private QuestStep getSnakeWeed() + private NpcStep talkToTrufitus(String text, Requirement... requirements) { - getSnakeWeed = new ObjectStep(this, ObjectID.SNAKE_VINE_FULL, new WorldPoint(2763, 3044, 0), - "Search a marshy jungle vine south of Tai Bwo Wannai for some snake weed."); - getSnakeWeed.addText("If you want to do Zogre Flesh Eaters or Legends' Quest grab one for each as you will need them later."); - return getSnakeWeed; + return new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), text, requirements); } - private QuestStep getArdrigal() + private void setupSteps() { - getArdrigal = new ObjectStep(this, ObjectID.ARDRIGAL_PALM_FULL, new WorldPoint(2871, 3116, 0), - "Search the palm trees north east of Tai Bwo Wannai for an Ardrigal herb."); + startQuest = talkToTrufitus("Talk to Trufitus in Tai Bwo Wannai on Karamja."); + startQuest.addDialogStep("It's a nice village, where is everyone?"); + startQuest.addDialogStep("Me? How can I help?"); + startQuest.addDialogStep("It sounds like just the challenge for me."); + startQuest.addDialogStep("Yes."); + + getSnakeWeed = new ObjectStep(this, ObjectID.SNAKE_VINE_FULL, new WorldPoint(2763, 3044, 0), "Search a marshy jungle vine south of Tai Bwo Wannai for some snake weed."); + getSnakeWeed.addText("If you want to do Zogre Flesh Eaters or Legends' Quest grab one for each as you will need them later."); + + cleanAndReturnSnakeWeed = getReturnHerbStep("Snake Weed", grimySnakeWeed, snakeWeed); + + getArdrigal = new ObjectStep(this, ObjectID.ARDRIGAL_PALM_FULL, new WorldPoint(2871, 3116, 0), "Search the palm trees north east of Tai Bwo Wannai for an Ardrigal herb."); getArdrigal.addText("If you want to do Legends' Quest grab one extra as you will need it later."); - return getArdrigal; - } - private QuestStep getSitoFoil() - { - return getSitoFoil = new ObjectStep(this, ObjectID.SITO_SOIL_FULL, new WorldPoint(2791, 3047, 0), - "Search the scorched earth in the south of Tai Bwo Wannai for a Sito Foil herb."); - } + cleanAndReturnArdrigal = getReturnHerbStep("Ardrigal", grimyArdrigal, ardrigal); - private QuestStep getVolenciaMoss() - { - getVolenciaMoss = new ObjectStep(this, ObjectID.VOLENCIA_MOSS_ROCK_FULL, new WorldPoint(2851, 3036, 0), - "Search the rock for a Volencia Moss herb at the mine south east of Tai Bwo Wannai."); + getSitoFoil = new ObjectStep(this, ObjectID.SITO_SOIL_FULL, new WorldPoint(2791, 3047, 0), "Search the scorched earth in the south of Tai Bwo Wannai for a Sito Foil herb."); + + cleanAndReturnSitoFoil = getReturnHerbStep("Sito Foil", grimySitoFoil, sitoFoil); + + getVolenciaMoss = new ObjectStep(this, ObjectID.VOLENCIA_MOSS_ROCK_FULL, new WorldPoint(2851, 3036, 0), "Search the rock for a Volencia Moss herb at the mine south east of Tai Bwo Wannai."); getVolenciaMoss.addText("If you plan on doing Fairy Tale I then take an extra."); - return getVolenciaMoss; - } - private QuestStep getRoguesPurse() - { + cleanAndReturnVolenciaMoss = getReturnHerbStep("Volencia Moss", grimyVolenciaMoss, volenciaMoss); + enterCave = new ObjectStep(this, ObjectID.POTHOLE_CAVE_ENTRANCE, new WorldPoint(2825, 3119, 0), "Enter the cave to the north by clicking on the rocks."); enterCave.addDialogStep("Yes, I'll enter the cave."); @@ -212,51 +185,62 @@ private QuestStep getRoguesPurse() getRoguesPurse.addStep(isUnderground, getRoguePurseHerb); getRoguesPurse.addSubSteps(enterCave); - return getRoguesPurse; - } - private QuestStep finishQuestStep() - { + cleanAndReturnRoguesPurse = getReturnHerbStep("Rogues Purse", grimyRoguesPurse, roguesPurse); + cleanAndReturnRoguesPurse.addStep(isUnderground, new ObjectStep(this, ObjectID.JP_CAVEROCKSOUT, new WorldPoint(2830, 9522, 0), "Climb out of the cave.")); + finishQuest = talkToTrufitus("Talk to Trufitus to finish the quest."); - return finishQuest; } - private NpcStep talkToTrufitus(String text, Requirement... requirements) + @Override + public Map loadSteps() { - return new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), text, requirements); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, startQuest); + steps.put(1, getSnakeWeed); + steps.put(2, cleanAndReturnSnakeWeed); + steps.put(3, getArdrigal); + steps.put(4, cleanAndReturnArdrigal); + steps.put(5, getSitoFoil); + steps.put(6, cleanAndReturnSitoFoil); + steps.put(7, getVolenciaMoss); + steps.put(8, cleanAndReturnVolenciaMoss); + steps.put(9, getRoguesPurse); + steps.put(10, cleanAndReturnRoguesPurse); + steps.put(11, finishQuest); + + return steps; } @Override - public List getCombatRequirements() + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Survive against level 53 Jogres and level 46 Harpie Bug Swarms."); - return reqs; + return List.of( + new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED), + new SkillRequirement(Skill.HERBLORE, 3, false) + ); } - //Recommended @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - ItemRequirement food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); - - reqs.add(food); - reqs.add(new ItemRequirement("Antipoison", ItemCollections.ANTIPOISONS)); - ItemRequirement karaTele = new ItemRequirement("Teleport to Karamja (Glory/house teleport)", - ItemID.NZONE_TELETAB_BRIMHAVEN); - karaTele.addAlternates(ItemCollections.AMULET_OF_GLORIES); - reqs.add(karaTele); - return reqs; + return List.of( + food, + antipoison, + karaTele + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.HERBLORE, 3, false)); - return req; + return List.of( + "Survive against level 53 Jogres and level 46 Harpie Bug Swarms." + ); } @Override @@ -268,38 +252,47 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.HERBLORE, 775)); + return List.of( + new ExperienceReward(Skill.HERBLORE, 775) + ); } @Override public List getPanels() { - List steps = new ArrayList<>(); - - PanelDetails startingPanel = new PanelDetails("Starting quest", - Collections.singletonList(startQuest)); - steps.add(startingPanel); - - PanelDetails snakeWeedPanel = new PanelDetails("Snake Weed", - Arrays.asList(getSnakeWeed, cleanAndReturnSnakeWeed)); - steps.add(snakeWeedPanel); - - PanelDetails ardrigalPanel = new PanelDetails("Ardrigal", - Arrays.asList(getArdrigal, cleanAndReturnArdrigal)); - steps.add(ardrigalPanel); - - PanelDetails sitoFoilpanel = new PanelDetails("Sito Foil", - Arrays.asList(getSitoFoil, cleanAndReturnSitoFoil)); - steps.add(sitoFoilpanel); - - PanelDetails volenciaMossPanel = new PanelDetails("Volencia Moss", - Arrays.asList(getVolenciaMoss, cleanAndReturnVolenciaMoss)); - steps.add(volenciaMossPanel); - - PanelDetails roguesPursePanel = new PanelDetails("Rogues Purse", - Arrays.asList(enterCave, getRoguePurseHerb, cleanAndReturnRoguesPurse)); - steps.add(roguesPursePanel); - - return steps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + startQuest + ))); + + sections.add(new PanelDetails("Snake Weed", List.of( + getSnakeWeed, + cleanAndReturnSnakeWeed + ))); + + sections.add(new PanelDetails("Ardrigal", List.of( + getArdrigal, + cleanAndReturnArdrigal + ))); + + sections.add(new PanelDetails("Sito Foil", List.of( + getSitoFoil, + cleanAndReturnSitoFoil + ))); + + sections.add(new PanelDetails("Volencia Moss", List.of( + getVolenciaMoss, + cleanAndReturnVolenciaMoss + ))); + + sections.add(new PanelDetails("Rogues Purse", List.of( + enterCave, + getRoguePurseHerb, + cleanAndReturnRoguesPurse, + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java index 593527e112..7dec619302 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/landofthegoblins/LandOfTheGoblins.java @@ -65,7 +65,7 @@ public class LandOfTheGoblins extends BasicQuestHelper { Requirement noPet; ItemRequirement lightSource, toadflaxPotionUnf, goblinMail, yellowDye, blueDye, orangeDye, purpleDye, blackDye, fishingRod, rawSlimyEel, coins, combatGear; - ItemRequirement tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing, salveAmulet; + ItemRequirement tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing; CombatLevelRequirement recommendedCombatLevel; ItemRequirement pharmakosBerryHighlight, toadflaxUnfHighlight, goblinPotion, goblinPotionHighlight, noEquippedItems, dorgeshKaanSphere, blackGoblinMail, huzamogaarbKey, hemensterWhitefish, pestleAndMortar, vial, @@ -379,7 +379,6 @@ protected void setupRequirements() draynorTeleport = new ItemRequirement("Draynor Village teleport", ItemCollections.AMULET_OF_GLORIES, 2); draynorTeleport.setChargedItem(true); explorersRing = new ItemRequirement("Explorer's ring 3 or 4", Arrays.asList(ItemID.LUMBRIDGE_RING_HARD, ItemID.LUMBRIDGE_RING_ELITE)); - salveAmulet = new ItemRequirement("Salve amulet or Salve amulet (e)", ItemCollections.SALVE_AMULET); pharmakosBerryHighlight = new ItemRequirement("Pharmakos berries", ItemID.LOTG_PHARMAKOS_BERRY); pharmakosBerryHighlight.setHighlightInInventory(true); @@ -679,7 +678,7 @@ public ArrayList getItemRequirements() @Override public ArrayList getItemRecommended() { - return new ArrayList<>(Arrays.asList(tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing, salveAmulet)); + return new ArrayList<>(Arrays.asList(tinderbox, dorgeshKaanSphereRec, dramenStaff, skillsNecklace, combatBracelet, lumbridgeTeleport, draynorTeleport, explorersRing)); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java index 3e83f50119..020c14df1d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/lostcity/LostCity.java @@ -33,104 +33,102 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class LostCity extends BasicQuestHelper { - //Items Required - ItemRequirement knife, axe, combatGear, teleport, bronzeAxe, dramenBranch, dramenStaff, dramenStaffEquipped; + // Required items + ItemRequirement axe; + ItemRequirement knife; - Requirement onEntrana, inDungeon, shamusNearby, bronzeAxeNearby, dramenSpiritNearby; + // Recommended items + ItemRequirement combatGear; + ItemRequirement teleport; - DetailedQuestStep talkToWarrior, chopTree, talkToShamus, goToEntrana, goDownHole, getAxe, pickupAxe, attemptToCutDramen, killDramenSpirit, cutDramenBranch, - teleportAway, craftBranch, enterZanaris, getAnotherBranch; + // Mid-quest item requirements + ItemRequirement bronzeOrIronAxe; + ItemRequirement dramenBranch; + ItemRequirement dramenStaff; + ItemRequirement dramenStaffEquipped; - //Zones - Zone entrana, entranaDungeon; + // Zones + Zone entrana; + Zone entranaDungeon; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); + // Miscellaneous requirements + ZoneRequirement onEntrana; + ZoneRequirement inDungeon; + NpcCondition shamusNearby; + Conditions axeNearby; + NpcCondition dramenSpiritNearby; - steps.put(0, talkToWarrior); + // Steps + NpcStep talkToWarrior; - ConditionalStep findShamus = new ConditionalStep(this, chopTree); - findShamus.addStep(shamusNearby, talkToShamus); + ObjectStep chopTree; + NpcStep talkToShamus; - steps.put(1, findShamus); + NpcStep goToEntrana; + ObjectStep goDownHole; + DetailedQuestStep getAxe; + DetailedQuestStep pickupAxe; + ObjectStep attemptToCutDramen; + NpcStep killDramenSpirit; - ConditionalStep killingTheSpirit = new ConditionalStep(this, goToEntrana); - killingTheSpirit.addStep(new Conditions(inDungeon, dramenSpiritNearby), killDramenSpirit); - killingTheSpirit.addStep(new Conditions(inDungeon, bronzeAxe), attemptToCutDramen); - killingTheSpirit.addStep(new Conditions(inDungeon, bronzeAxeNearby), pickupAxe); - killingTheSpirit.addStep(inDungeon, getAxe); - killingTheSpirit.addStep(onEntrana, goDownHole); + ObjectStep cutDramenBranch; + DetailedQuestStep teleportAway; + DetailedQuestStep craftBranch; + ObjectStep enterZanaris; + DetailedQuestStep getAnotherBranch; - steps.put(2, killingTheSpirit); - - ConditionalStep finishQuest = new ConditionalStep(this, getAnotherBranch); - finishQuest.addStep(new Conditions(inDungeon, dramenStaff), teleportAway); - finishQuest.addStep(dramenStaff, enterZanaris); - finishQuest.addStep(new Conditions(inDungeon, dramenBranch), teleportAway); - finishQuest.addStep(dramenBranch, craftBranch); - finishQuest.addStep(new Conditions(inDungeon, bronzeAxe), cutDramenBranch); - finishQuest.addStep(new Conditions(inDungeon, bronzeAxeNearby), pickupAxe); - finishQuest.addStep(inDungeon, getAxe); - finishQuest.addStep(onEntrana, goDownHole); - - steps.put(3, finishQuest); - - steps.put(4, finishQuest); - - steps.put(5, finishQuest); - - return steps; + @Override + protected void setupZones() + { + entrana = new Zone(new WorldPoint(2798, 3327, 0), new WorldPoint(2878, 3394, 1)); + entranaDungeon = new Zone(new WorldPoint(2817, 9722, 0), new WorldPoint(2879, 9784, 0)); } @Override protected void setupRequirements() { - knife = new ItemRequirement("Knife", ItemID.KNIFE).isNotConsumed(); - bronzeAxe = new ItemRequirement("Bronze axe", ItemID.BRONZE_AXE).isNotConsumed(); axe = new ItemRequirement("Any axe", ItemID.BRONZE_AXE).isNotConsumed(); axe.addAlternates(ItemCollections.AXES); + knife = new ItemRequirement("Knife", ItemID.KNIFE).isNotConsumed(); + combatGear = new ItemRequirement("Runes, or a way of dealing damage which you can smuggle onto Entrana. Runes for Crumble Undead (level 39 Magic) are best", -1, -1).isNotConsumed(); combatGear.setDisplayItemId(ItemID.SKULL); teleport = new ItemRequirement("Teleport, preferably to Lumbridge. Home teleport will work if off cooldown", ItemID.RING_OF_ELEMENTS_CHARGED); teleport.addAlternates(ItemID.POH_TABLET_LUMBRIDGETELEPORT); + + bronzeOrIronAxe = new ItemRequirement("Bronze or Iron axe", ItemID.BRONZE_AXE).isNotConsumed(); + bronzeOrIronAxe.addAlternates(ItemID.IRON_AXE); dramenBranch = new ItemRequirement("Dramen branch", ItemID.DRAMEN_BRANCH); dramenStaff = new ItemRequirement("Dramen staff", ItemID.DRAMEN_STAFF); - dramenStaffEquipped = new ItemRequirement("Dramen staff", ItemID.DRAMEN_STAFF, 1, true); - } + dramenStaffEquipped = dramenStaff.equipped(); - @Override - protected void setupZones() - { - entrana = new Zone(new WorldPoint(2798, 3327, 0), new WorldPoint(2878, 3394, 1)); - entranaDungeon = new Zone(new WorldPoint(2817, 9722, 0), new WorldPoint(2879, 9784, 0)); - } - - public void setupConditions() - { onEntrana = new ZoneRequirement(entrana); inDungeon = new ZoneRequirement(entranaDungeon); shamusNearby = new NpcCondition(NpcID.ZANARISLEPRECHAUN); - bronzeAxeNearby = new ItemOnTileRequirement(ItemID.BRONZE_AXE); + axeNearby = or(new ItemOnTileRequirement(ItemID.BRONZE_AXE), new ItemOnTileRequirement(ItemID.IRON_AXE)); dramenSpiritNearby = new NpcCondition(NpcID.TREE_SPIRIT); } @@ -141,59 +139,118 @@ public void setupSteps() talkToWarrior.addDialogStep("What makes you think it's out here?"); talkToWarrior.addDialogStep("If it's hidden how are you planning to find it?"); talkToWarrior.addDialogStep("Looks like you don't know either."); + talkToWarrior.addDialogStep("Yes."); + chopTree = new ObjectStep(this, ObjectID.LEPRECHAUNTREE, new WorldPoint(3139, 3213, 0), "Try cutting the tree just to the west.", axe); chopTree.addDialogStep("I've been in that shed, I didn't see a city."); + talkToShamus = new NpcStep(this, NpcID.ZANARISLEPRECHAUN, new WorldPoint(3138, 3212, 0), "Talk to Shamus."); talkToShamus.addDialogStep("I've been in that shed, I didn't see a city."); + goToEntrana = new NpcStep(this, NpcID.SHIPMONK1_C, new WorldPoint(3047, 3236, 0), "Bank all weapons and armour you have (including the axe), and go to Port Sarim to get a boat to Entrana.", combatGear); + goDownHole = new ObjectStep(this, ObjectID.ENTRANALADDERTOP, new WorldPoint(2820, 3374, 0), "Climb down the ladder on the north side of the island. Once you go down, you can only escape via teleport."); goDownHole.addDialogStep("Well that is a risk I will have to take."); - getAxe = new DetailedQuestStep(this, new WorldPoint(2843, 9760, 0), "Kill zombies until one drops a bronze axe."); - pickupAxe = new DetailedQuestStep(this, "Pick up the bronze axe", bronzeAxe); - attemptToCutDramen = new ObjectStep(this, ObjectID.DRAMENTREE, new WorldPoint(2861, 9735, 0), "Attempt to cut a branch from the Dramen tree. Be prepared for a Tree Spirit (level 101) to appear, which you can safespot behind nearby fungus.", bronzeAxe); + + getAxe = new DetailedQuestStep(this, new WorldPoint(2843, 9760, 0), "Kill zombies until one drops an axe."); + pickupAxe = new DetailedQuestStep(this, "Pick up the axe", bronzeOrIronAxe); + getAxe.addSubSteps(pickupAxe); + + attemptToCutDramen = new ObjectStep(this, ObjectID.DRAMENTREE, new WorldPoint(2861, 9735, 0), "Attempt to cut a branch from the Dramen tree. Be prepared for a Tree Spirit (level 101) to appear, which you can safespot behind nearby fungus.", bronzeOrIronAxe); + killDramenSpirit = new NpcStep(this, NpcID.TREE_SPIRIT, new WorldPoint(2859, 9734, 0), "Kill the Tree Spirit. They can be safespotted behind nearby fungi to the east."); + killDramenSpirit.addSafeSpots(new WorldPoint(2856, 9730, 0)); + cutDramenBranch = new ObjectStep(this, ObjectID.DRAMENTREE, new WorldPoint(2861, 9735, 0), "Cut at least one branch from the Dramen tree. It's recommended you cut at least 4 branches so you don't have to return in future quests."); + teleportAway = new DetailedQuestStep(this, "Teleport away with the branches, preferably to Lumbridge.", dramenBranch); teleportAway.addTeleport(teleport); - getAnotherBranch = new DetailedQuestStep(this, "If you've lost your Dramen branch/staff, you will need to return to Entrana and cut another. You will not need to defeat the Tree Spirit again."); - craftBranch = new DetailedQuestStep(this, "Use a knife on the dramen branch to craft a dramen staff.", knife, dramenBranch); - enterZanaris = new ObjectStep(this, ObjectID.ZANARISDOOR, new WorldPoint(3202, 3169, 0), "Enter the shed south of Lumbridge with your Dramen Staff equipped.", dramenStaffEquipped); + + getAnotherBranch = new DetailedQuestStep(this, "If you've lost your Dramen branch/staff, you will need to return to Entrana and cut another. You will not need to defeat the Tree Spirit again.", dramenBranch); + goToEntrana.addSubSteps(getAnotherBranch); + + craftBranch = new DetailedQuestStep(this, "Use a knife on the dramen branch to craft a dramen staff.", knife.highlighted(), dramenBranch.highlighted()); + + enterZanaris = new ObjectStep(this, ObjectID.ZANARISDOOR, new WorldPoint(3202, 3169, 0), "Enter the shed south of Lumbridge with your Dramen Staff equipped.", dramenStaffEquipped.highlighted()); } @Override - public List getCombatRequirements() + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToWarrior); + + var findShamus = new ConditionalStep(this, chopTree); + findShamus.addStep(shamusNearby, talkToShamus); + + steps.put(1, findShamus); + + var killingTheSpirit = new ConditionalStep(this, goToEntrana); + killingTheSpirit.addStep(and(inDungeon, dramenSpiritNearby), killDramenSpirit); + killingTheSpirit.addStep(and(inDungeon, bronzeOrIronAxe), attemptToCutDramen); + killingTheSpirit.addStep(and(inDungeon, axeNearby), pickupAxe); + killingTheSpirit.addStep(inDungeon, getAxe); + killingTheSpirit.addStep(onEntrana, goDownHole); + + steps.put(2, killingTheSpirit); + + var finishQuest = new ConditionalStep(this, getAnotherBranch); + finishQuest.addStep(and(inDungeon, dramenStaff), teleportAway); + finishQuest.addStep(dramenStaff.alsoCheckBank(), enterZanaris); + finishQuest.addStep(and(inDungeon, dramenBranch), teleportAway); + finishQuest.addStep(dramenBranch.alsoCheckBank(), craftBranch); + finishQuest.addStep(and(inDungeon, bronzeOrIronAxe), cutDramenBranch); + finishQuest.addStep(and(inDungeon, axeNearby), pickupAxe); + finishQuest.addStep(inDungeon, getAxe); + finishQuest.addStep(onEntrana, goDownHole); + + steps.put(3, finishQuest); + + steps.put(4, finishQuest); + + steps.put(5, finishQuest); + + return steps; + } + + @Override + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Multiple zombies (level 25) (can be safespotted)"); - reqs.add("Dramen Tree Spirit (level 101) (can be safespotted)"); - return reqs; + return List.of( + new SkillRequirement(Skill.CRAFTING, 31, true), + new SkillRequirement(Skill.WOODCUTTING, 36, true) + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(axe); - reqs.add(knife); - return reqs; + return List.of( + axe, + knife + ); } @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - reqs.add(combatGear); - reqs.add(teleport); - return reqs; + return List.of( + combatGear, + teleport + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new SkillRequirement(Skill.CRAFTING, 31, true)); - req.add(new SkillRequirement(Skill.WOODCUTTING, 36, true)); - return req; + return List.of( + "Multiple zombies (level 25) (can be safespotted)", + "Dramen Tree Spirit (level 101) (can be safespotted)" + ); } @Override @@ -205,22 +262,51 @@ public QuestPointReward getQuestPointReward() @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to Zanaris."), - new UnlockReward("Ability to craft Cosmic Runes"), - new UnlockReward("Ability to buy and wield Dragon Daggers & Longswords")); + return List.of( + new UnlockReward("Access to Zanaris."), + new UnlockReward("Ability to craft Cosmic Runes"), + new UnlockReward("Ability to buy and wield Dragon Daggers & Longswords") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToWarrior), axe)); - allSteps.add(new PanelDetails("Finding Shamus", Arrays.asList(chopTree, talkToShamus))); - allSteps.add(new PanelDetails("Getting a Dramen branch", Arrays.asList(goToEntrana, goDownHole, getAxe, attemptToCutDramen, killDramenSpirit, - cutDramenBranch, teleportAway), List.of(), List.of(combatGear, teleport))); - allSteps.add(new PanelDetails("Entering Zanaris", Arrays.asList(craftBranch, enterZanaris), knife)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToWarrior + ), List.of( + axe + ))); + + sections.add(new PanelDetails("Finding Shamus", List.of( + chopTree, + talkToShamus + ))); + + sections.add(new PanelDetails("Getting a Dramen branch", List.of( + goToEntrana, + goDownHole, + getAxe, + attemptToCutDramen, + killDramenSpirit, + cutDramenBranch, + teleportAway + ), List.of( + // No requirements + ), List.of( + combatGear, + teleport + ))); + + sections.add(new PanelDetails("Entering Zanaris", List.of( + craftBranch, + enterZanaris + ), List.of( + knife + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java index 2cb99b031c..435a4e3cee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/makinghistory/MakingHistory.java @@ -150,7 +150,7 @@ protected void setupRequirements() portPhasmatysEntry.setTooltip(ectoTokens.getTooltip()); ringOfDueling = new ItemRequirement("Ring of Dueling", ItemCollections.RING_OF_DUELINGS); - enchantedKey = new KeyringRequirement("Enchanted key", configManager, KeyringCollection.ENCHANTED_KEY); + enchantedKey = new KeyringRequirement("Enchanted key", KeyringCollection.ENCHANTED_KEY); enchantedKey.setTooltip("You can get another from the silver merchant in East Ardougne's market"); enchantedKeyHighlighted = new ItemRequirement("Enchanted key", ItemID.MAKINGHISTORY_KEY); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java index 44595dcca7..bed2c7f0d9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/merlinscrystal/MerlinsCrystal.java @@ -32,25 +32,28 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; public class MerlinsCrystal extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java index c1481e5898..414c9e5160 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/misthalinmystery/MisthalinMystery.java @@ -29,6 +29,7 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -37,17 +38,24 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.WidgetStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class MisthalinMystery extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java index 0eab1b1219..506249ce60 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessi/MonkeyMadnessI.java @@ -768,7 +768,7 @@ public void setupSteps() )); killZombie = new NpcStep(this, NpcID.MM_TRANSMOGRIFICATION_SMALL_ZOMBIE_MONKEY, new WorldPoint(2808, 9201, 0), "Kill a zombie monkey for their bones.", true, zombieBones); - killGorilla = new NpcStep(this, NpcID.MM_RELIGIOUS_GUARD, new WorldPoint(2801, 2785, 0), "Kill a gorilla in the temple for their bones.", + killGorilla = new NpcStep(this, NpcID.MM_RELIGIOUS_GUARD, new WorldPoint(2801, 2785, 0), "Kill a gorilla in the temple for their bones. If they can attack you they will heal on hit, so it's recommended to safespot or flinch one.", true, gorillaBones); ((NpcStep) killGorilla).addAlternateNpcs(NpcID.MM_RELIGIOUS_TRAPDOOR_GUARD); killGorilla.setLinePoints(Arrays.asList( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java index 7de82ad5d8..0ba1c6e419 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monkeymadnessii/AgilityDungeonSteps.java @@ -42,9 +42,13 @@ import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; + import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; import java.util.*; @@ -417,7 +421,7 @@ public void checkSection5Successes() { return; } - WorldPoint currentPosition = Rs2Player.getWorldLocation(); + WorldPoint currentPosition = player.getWorldLocation(); for (int i = 0; i < fifthSectionMap.length; i++) { MM2Route[] pathsFromNode = fifthSectionMap[i].getPaths(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java index adfb1bf830..2129cca22e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/monksfriend/MonksFriend.java @@ -24,28 +24,31 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.monksfriend; +import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class MonksFriend extends BasicQuestHelper { // Required items @@ -89,12 +92,9 @@ protected void setupRequirements() log = new ItemRequirement("Logs", ItemID.LOGS); jugOfWater = new ItemRequirement("Jug of Water", ItemID.JUG_WATER); + jugOfWater.setTooltip("You can find one in the Yanille cooking shop"); blanket = new ItemRequirement("Child's blanket", ItemID.CHILDS_BLANKET); - ardougneCloak = new ItemRequirement("Ardougne cloak 1 or higher for teleports to the monastery", ItemID.CERT_ARRAVCERTIFICATE).isNotConsumed(); - } - - public void setupConditions() - { + ardougneCloak = new ItemRequirement("Ardougne cloak 1 or higher for teleports to the monastery", ItemCollections.ARDOUGNE_CLOAK).isNotConsumed(); } public void setupSteps() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java index 8656228c9a..1818879a21 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mountaindaughter/MountainDaughter.java @@ -44,7 +44,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java index d078424a57..4bc1e51ca4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendparti/MourningsEndPartI.java @@ -396,7 +396,7 @@ public void setupSteps() askAboutToads = new NpcStep(this, NpcID.MOURNER_HIDEOUT_GNOME_HEAD, new WorldPoint(2035, 4630, 0), "Ask the gnome about ammo."); getToads = new DetailedQuestStep(this, new WorldPoint(2599, 2966, 0), - "You need to make some dyed toads. Go to Feldip Hills, use a dye on your empty bellows, then use the " + + "You need to make some dyed toads. Go to Feldip Hills (AKS), use a dye on your empty bellows, then use the " + "bellows to inflate a toad. Get at least one toad of each colour.", redToad, yellowToad, greenToad, blueToad); loadGreenToad = new DetailedQuestStep(this, "Add a green toad to the fixed device.", greenToad.highlighted(), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java index 9fe790e908..897b4cd3d6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/mourningsendpartii/MourningsEndPartII.java @@ -425,7 +425,7 @@ protected void setupRequirements() ItemCollections.PRAYER_POTIONS, -1); food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); - newKey = new KeyringRequirement("New Key", configManager, KeyringCollection.NEW_KEY); + newKey = new KeyringRequirement("New Key", KeyringCollection.NEW_KEY); newKey.setTooltip("You can get another from Essyllt's desk"); edernsJournal = new ItemRequirement("Edern's journal", ItemID.MOURNING_EDERNS_JOURNAL); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java index dc9ceec725..7439a54df9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/murdermystery/MurderMystery.java @@ -31,6 +31,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -39,17 +42,23 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; public class MurderMystery extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java index dff3eeb43c..e3647a41ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/myarmsbigadventure/MyArmsBigAdventure.java @@ -385,7 +385,7 @@ public void setupSteps() talkToMyArmAfterBaby = new NpcStep(this, NpcID.MYARM_FIXED, new WorldPoint(2829, 3695, 0), "Talk to My Arm. Be prepared to fight the Giant Roc.", combatGear, spade); - killGiantRoc = new NpcStep(this, NpcID.MYARM_GIANT_ROC, "Kill the Giant Roc. Use protected from ranged, and keep your distance. You can dodge the boulders it throws."); + killGiantRoc = new NpcStep(this, NpcID.MYARM_GIANT_ROC, "Kill the Giant Roc. Use protect from missiles, and keep your distance. You can dodge the boulders it throws."); talkToMyArmAfterHarvest = new NpcStep(this, NpcID.MYARM_FIXED, new WorldPoint(2829, 3695, 0), "Talk to My Arm."); giveSpade = new NpcStep(this, NpcID.MYARM_FIXED, new WorldPoint(2829, 3695, 0), "Give My Arm a spade.", spadeHighlight); giveSpade.addIcon(ItemID.SPADE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java index 1cb97897df..ac557aae16 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/naturespirit/NatureSpirit.java @@ -43,7 +43,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -52,113 +60,84 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class NatureSpirit extends BasicQuestHelper { - //Items Required - ItemRequirement ghostspeak, silverSickle, washingBowl, mirror, journal, druidicSpell, druidPouch, blessedSickle, - spellCard, mirrorHighlighted, journalHighlighted, mushroom, mushroomHighlighted, druidPouchFull; - - //Items Recommended - ItemRequirement combatGear, salveTele; - - Requirement inUnderground, fillimanNearby, mirrorNearby, usedMushroom, onOrange, - usedCard, inGrotto, natureSpiritNearby, ghastNearby, prayerPoints; - - QuestStep goDownToDrezel, talkToDrezel, leaveDrezel, enterSwamp, tryToEnterGrotto, talkToFilliman, takeWashingBowl, - takeMirror, useMirrorOnFilliman, searchGrotto, useJournalOnFilliman, goBackDownToDrezel, talkToDrezelForBlessing, - castSpellAndGetMushroom, useMushroom, useSpellCard, standOnOrange, tellFillimanToCast, enterGrotto, searchAltar, - blessSickle, fillPouches, killGhasts, killGhast, enterGrottoAgain, touchAltarAgain, talkToNatureSpiritToFinish, - spawnFillimanForRitual, talkToFillimanInGrotto; - - //Zones - Zone underground, orangeStone, grotto; + // Required items + ItemRequirement ghostspeak; + ItemRequirement silverSickle; + + // Recommended items + ItemRequirement combatGear; + ItemRequirement salveTele; + + // Mid-quest requirements + ItemRequirement washingBowl; + ItemRequirement mirror; + ItemRequirement journal; + ItemRequirement druidicSpell; + ItemRequirement druidPouch; + ItemRequirement blessedSickle; + ItemRequirement spellCard; + ItemRequirement mirrorHighlighted; + ItemRequirement journalHighlighted; + ItemRequirement mushroom; + ItemRequirement mushroomHighlighted; + ItemRequirement druidPouchFull; + + // Zones + Zone underground; + Zone orangeStone; + Zone grotto; + + // Miscellaneous requirements + ZoneRequirement inUnderground; + NpcCondition fillimanNearby; + ItemOnTileRequirement mirrorNearby; + Conditions usedMushroom; + ZoneRequirement onOrange; + Conditions usedCard; + ZoneRequirement inGrotto; + NpcCondition natureSpiritNearby; + NpcCondition ghastNearby; + PrayerPointRequirement prayerPoints; + + // Steps + ObjectStep goDownToDrezel; + NpcStep talkToDrezel; + ObjectStep leaveDrezel; + ObjectStep enterSwamp; + ObjectStep tryToEnterGrotto; + NpcStep talkToFilliman; + DetailedQuestStep takeWashingBowl; + DetailedQuestStep takeMirror; + NpcStep useMirrorOnFilliman; + ObjectStep searchGrotto; + NpcStep useJournalOnFilliman; + ObjectStep goBackDownToDrezel; + NpcStep talkToDrezelForBlessing; + DetailedQuestStep castSpellAndGetMushroom; + ObjectStep useMushroom; + ObjectStep useSpellCard; + DetailedQuestStep standOnOrange; + NpcStep tellFillimanToCast; + ObjectStep enterGrotto; + ObjectStep searchAltar; + NpcStep blessSickle; + DetailedQuestStep fillPouches; + NpcStep killGhasts; + NpcStep killGhast; + ObjectStep enterGrottoAgain; + ObjectStep touchAltarAgain; + NpcStep talkToNatureSpiritToFinish; + ObjectStep spawnFillimanForRitual; + NpcStep talkToFillimanInGrotto; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - ConditionalStep startQuest = new ConditionalStep(this, goDownToDrezel); - startQuest.addStep(inUnderground, talkToDrezel); - - steps.put(0, startQuest); - - ConditionalStep goEnterSwamp = new ConditionalStep(this, enterSwamp); - goEnterSwamp.addStep(inUnderground, leaveDrezel); - steps.put(1, goEnterSwamp); - steps.put(2, goEnterSwamp); - steps.put(3, goEnterSwamp); - steps.put(4, goEnterSwamp); - steps.put(5, goEnterSwamp); - - ConditionalStep goTalkToFilliman = new ConditionalStep(this, tryToEnterGrotto); - goTalkToFilliman.addStep(fillimanNearby, talkToFilliman); - steps.put(10, goTalkToFilliman); - steps.put(15, goTalkToFilliman); - - ConditionalStep showFillimanReflection = new ConditionalStep(this, takeWashingBowl); - showFillimanReflection.addStep(new Conditions(mirror, fillimanNearby), useMirrorOnFilliman); - showFillimanReflection.addStep(mirror, tryToEnterGrotto); - showFillimanReflection.addStep(mirrorNearby, takeMirror); - steps.put(20, showFillimanReflection); - - ConditionalStep goGetJournal = new ConditionalStep(this, searchGrotto); - goGetJournal.addStep(new Conditions(journal, fillimanNearby), useJournalOnFilliman); - goGetJournal.addStep(journal, tryToEnterGrotto); - steps.put(25, goGetJournal); - - ConditionalStep goOfferHelp = new ConditionalStep(this, tryToEnterGrotto); - goOfferHelp.addStep(fillimanNearby, useJournalOnFilliman); - steps.put(30, goOfferHelp); - - ConditionalStep getBlessed = new ConditionalStep(this, goBackDownToDrezel); - getBlessed.addStep(inUnderground, talkToDrezelForBlessing); - steps.put(35, getBlessed); - - ConditionalStep performRitual = new ConditionalStep(this, castSpellAndGetMushroom); - performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby, onOrange), tellFillimanToCast); - performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby), standOnOrange); - performRitual.addStep(new Conditions(usedMushroom, usedCard), spawnFillimanForRitual); - performRitual.addStep(usedMushroom, useSpellCard); - performRitual.addStep(mushroom, useMushroom); - steps.put(40, performRitual); - steps.put(45, performRitual); - steps.put(50, performRitual); - steps.put(55, performRitual); - - ConditionalStep goTalkInGrotto = new ConditionalStep(this, enterGrotto); - goTalkInGrotto.addStep(new Conditions(inGrotto, fillimanNearby), talkToFillimanInGrotto); - goTalkInGrotto.addStep(inGrotto, searchAltar); - steps.put(60, goTalkInGrotto); - - ConditionalStep goBlessSickle = new ConditionalStep(this, enterGrotto); - goBlessSickle.addStep(new Conditions(inGrotto, natureSpiritNearby), blessSickle); - goBlessSickle.addStep(inGrotto, searchAltar); - steps.put(65, goBlessSickle); - steps.put(70, goBlessSickle); - - ConditionalStep goKillGhasts = new ConditionalStep(this, fillPouches); - // TODO: Fix ghast changing form not counting towards becoming nearby - goKillGhasts.addStep(ghastNearby, killGhast); - goKillGhasts.addStep(druidPouchFull, killGhasts); - steps.put(75, goKillGhasts); - steps.put(80, goKillGhasts); - steps.put(85, goKillGhasts); - steps.put(90, goKillGhasts); - steps.put(95, goKillGhasts); - steps.put(100, goKillGhasts); - - ConditionalStep finishOff = new ConditionalStep(this, enterGrottoAgain); - finishOff.addStep(new Conditions(inGrotto, natureSpiritNearby), talkToNatureSpiritToFinish); - finishOff.addStep(inGrotto, touchAltarAgain); - steps.put(105, finishOff); - - return steps; + underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); + orangeStone = new Zone(new WorldPoint(3440, 3335, 0), new WorldPoint(3440, 3335, 0)); + grotto = new Zone(new WorldPoint(3435, 9733, 0), new WorldPoint(3448, 9746, 0)); } @Override @@ -184,23 +163,10 @@ protected void setupRequirements() spellCard.addAlternates(ItemID.BLOOM_SPELL); spellCard.setTooltip("You can get another spell from Filliman"); mushroom = new ItemRequirement("Mort myre fungus", ItemID.MORTMYREMUSHROOM); - mushroomHighlighted = new ItemRequirement("Mort myre fungus", ItemID.MORTMYREMUSHROOM); - mushroomHighlighted.setHighlightInInventory(true); + mushroomHighlighted = mushroom.highlighted(); salveTele = new ItemRequirement("Salve Graveyard Teleports", ItemID.TELETAB_SALVE, 2); combatGear = new ItemRequirement("Combat gear to kill the ghasts", -1, -1).isNotConsumed(); combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); - } - - @Override - protected void setupZones() - { - underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); - orangeStone = new Zone(new WorldPoint(3440, 3335, 0), new WorldPoint(3440, 3335, 0)); - grotto = new Zone(new WorldPoint(3435, 9733, 0), new WorldPoint(3448, 9746, 0)); - } - - public void setupConditions() - { inUnderground = new ZoneRequirement(underground); onOrange = new ZoneRequirement(orangeStone); inGrotto = new ZoneRequirement(grotto); @@ -223,12 +189,13 @@ public void setupConditions() public void setupSteps() { goDownToDrezel = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Talk to Drezel under the Paterdomus Temple."); - ((ObjectStep) (goDownToDrezel)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + goDownToDrezel.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); talkToDrezel = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Talk to Drezel under the Paterdomus Temple."); talkToDrezel.addDialogSteps("Well, what is it, I may be able to help?", "Yes."); talkToDrezel.addSubSteps(goDownToDrezel); leaveDrezel = new ObjectStep(this, ObjectID.PIP_UNDERGROUND_WALL_SIDE_WITHPORTAL, new WorldPoint(3440, 9886, 0), "Enter the Mort Myre from the north gate."); enterSwamp = new ObjectStep(this, ObjectID.MORTMYRE_METALGATECLOSED_L, new WorldPoint(3444, 3458, 0), "Enter the Mort Myre from the north gate.", ghostspeak); + enterSwamp.addSubSteps(leaveDrezel); tryToEnterGrotto = new ObjectStep(this, ObjectID.GROTTO_DOOR_DRUIDICSPIRIT, new WorldPoint(3440, 3337, 0), "Attempt to enter the Grotto in the south of Mort Myre.", ghostspeak); tryToEnterGrotto.addDialogStep("How long have you been a ghost?"); talkToFilliman = new NpcStep(this, NpcID.FILLIMAN_TARLOCK_SPIRIT, new WorldPoint(3440, 3336, 0), "Talk to Filliman Tarlock.", ghostspeak); @@ -242,12 +209,13 @@ public void setupSteps() useJournalOnFilliman = new NpcStep(this, NpcID.FILLIMAN_TARLOCK_SPIRIT, new WorldPoint(3440, 3336, 0), "Use the journal on Filliman Tarlock.", ghostspeak, journalHighlighted); useJournalOnFilliman.addIcon(ItemID.FILLIMAN_JOURNAL); useJournalOnFilliman.addDialogStep("How can I help?"); - goBackDownToDrezel = new ObjectStep(this, ObjectID.PIPEASTSIDETRAPDOOR, new WorldPoint(3422, 3485, 0), "Talk to Drezel to get blessed."); - ((ObjectStep) (goBackDownToDrezel)).addAlternateObjects(ObjectID.PIPEASTSIDETRAPDOOR_OPEN); - talkToDrezelForBlessing = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Talk to Drezel under the Paterdomus Temple."); + goBackDownToDrezel = new ObjectStep(this, ObjectID.PIPEASTSIDETRAPDOOR, new WorldPoint(3422, 3485, 0), "Return to Drezel under the Paterdomus Temple to get blessed."); + goBackDownToDrezel.addAlternateObjects(ObjectID.PIPEASTSIDETRAPDOOR_OPEN); + talkToDrezelForBlessing = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Return to Drezel under the Paterdomus Temple to get blessed."); talkToDrezelForBlessing.addSubSteps(goBackDownToDrezel); talkToDrezelForBlessing.addSubSteps(goBackDownToDrezel); - castSpellAndGetMushroom = new DetailedQuestStep(this, "Cast the druidic spell next to a rotten log in Mort Myre to grow a mushroom. Pick it. If you already have, open the quest journal to re-sync your state.", druidicSpell); + castSpellAndGetMushroom = new ObjectStep(this, ObjectID.LOG_DRUIDICSPIRIT2, "Cast the druidic spell next to a rotten log in Mort Myre to grow a mushroom. Pick it. If you already have, open the quest journal to re-sync your state.", druidicSpell); + castSpellAndGetMushroom.addDialogStep("Could I have another bloom scroll please?"); useMushroom = new ObjectStep(this, ObjectID.STONEDISC_DS_NATURE, new WorldPoint(3439, 3336, 0), "Use the mushroom on the brown stone outside the grotto. If you already have, search it instead.", mushroomHighlighted); useMushroom.addIcon(ItemID.MORTMYREMUSHROOM); useSpellCard = new ObjectStep(this, ObjectID.STONEDISC_DS_SPIRIT, new WorldPoint(3441, 3336, 0), "Use the used spell on the gray stone outside the grotto. If you already have, search it instead.", spellCard); @@ -265,7 +233,7 @@ public void setupSteps() blessSickle = new NpcStep(this, NpcID.FILLIMAN_TARLOCK_NS, new WorldPoint(3441, 9738, 0), "Talk to the Nature Spirit in the grotto to bless your sickle.", ghostspeak, silverSickle); fillPouches = new DetailedQuestStep(this, "Right-click 'bloom' the blessed sickle next to rotten logs for mort myre fungi. Use these to fill the druid pouch.", blessedSickle, prayerPoints - , druidPouch); + , druidPouch); killGhasts = new NpcStep(this, NpcID.GHAST_INVIS, "Use the filled druid pouch on a ghast to make it attackable and kill it. You'll need to kill 3.", druidPouchFull); killGhast = new NpcStep(this, NpcID.GHAST_VIS, "Kill the ghast.", druidPouchFull); killGhasts.addSubSteps(killGhast); @@ -276,36 +244,132 @@ public void setupSteps() } @Override - public List getItemRequirements() + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + var startQuest = new ConditionalStep(this, goDownToDrezel); + startQuest.addStep(inUnderground, talkToDrezel); + steps.put(0, startQuest); + + var goEnterSwamp = new ConditionalStep(this, enterSwamp); + goEnterSwamp.addStep(inUnderground, leaveDrezel); + steps.put(1, goEnterSwamp); + steps.put(2, goEnterSwamp); + steps.put(3, goEnterSwamp); + steps.put(4, goEnterSwamp); + steps.put(5, goEnterSwamp); + + var goTalkToFilliman = new ConditionalStep(this, tryToEnterGrotto); + goTalkToFilliman.addStep(fillimanNearby, talkToFilliman); + steps.put(10, goTalkToFilliman); + steps.put(15, goTalkToFilliman); + + var showFillimanReflection = new ConditionalStep(this, takeWashingBowl); + showFillimanReflection.addStep(new Conditions(mirror, fillimanNearby), useMirrorOnFilliman); + showFillimanReflection.addStep(mirror, tryToEnterGrotto); + showFillimanReflection.addStep(mirrorNearby, takeMirror); + steps.put(20, showFillimanReflection); + + var goGetJournal = new ConditionalStep(this, searchGrotto); + goGetJournal.addStep(new Conditions(journal, fillimanNearby), useJournalOnFilliman); + goGetJournal.addStep(journal, tryToEnterGrotto); + steps.put(25, goGetJournal); + + var goOfferHelp = new ConditionalStep(this, tryToEnterGrotto); + goOfferHelp.addStep(fillimanNearby, useJournalOnFilliman); + steps.put(30, goOfferHelp); + + var getBlessed = new ConditionalStep(this, goBackDownToDrezel); + getBlessed.addStep(inUnderground, talkToDrezelForBlessing); + steps.put(35, getBlessed); + + var performRitual = new ConditionalStep(this, castSpellAndGetMushroom); + performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby, onOrange), tellFillimanToCast); + performRitual.addStep(new Conditions(usedMushroom, usedCard, fillimanNearby), standOnOrange); + performRitual.addStep(new Conditions(usedMushroom, usedCard), spawnFillimanForRitual); + performRitual.addStep(usedMushroom, useSpellCard); + performRitual.addStep(mushroom, useMushroom); + steps.put(40, performRitual); + steps.put(45, performRitual); + steps.put(50, performRitual); + steps.put(55, performRitual); + + var goTalkInGrotto = new ConditionalStep(this, enterGrotto); + goTalkInGrotto.addStep(new Conditions(inGrotto, fillimanNearby), talkToFillimanInGrotto); + goTalkInGrotto.addStep(inGrotto, searchAltar); + steps.put(60, goTalkInGrotto); + + var goBlessSickle = new ConditionalStep(this, enterGrotto); + goBlessSickle.addStep(new Conditions(inGrotto, natureSpiritNearby), blessSickle); + goBlessSickle.addStep(inGrotto, searchAltar); + steps.put(65, goBlessSickle); + steps.put(70, goBlessSickle); + + var goKillGhasts = new ConditionalStep(this, fillPouches); + // TODO: Fix ghast changing form not counting towards becoming nearby + goKillGhasts.addStep(ghastNearby, killGhast); + goKillGhasts.addStep(druidPouchFull, killGhasts); + steps.put(75, goKillGhasts); + steps.put(80, goKillGhasts); + steps.put(85, goKillGhasts); + steps.put(90, goKillGhasts); + steps.put(95, goKillGhasts); + steps.put(100, goKillGhasts); + + var finishOff = new ConditionalStep(this, enterGrottoAgain); + finishOff.addStep(new Conditions(inGrotto, natureSpiritNearby), talkToNatureSpiritToFinish); + finishOff.addStep(inGrotto, touchAltarAgain); + steps.put(105, finishOff); + + return steps; + } + + + @Override + public List getGeneralRequirements() { - return Arrays.asList(ghostspeak, silverSickle); + return List.of( + new QuestRequirement(QuestHelperQuest.THE_RESTLESS_GHOST, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.PRIEST_IN_PERIL, QuestState.FINISHED) + ); } @Override - public List getItemRecommended() + public List getItemRequirements() { - return Arrays.asList(salveTele, combatGear); + return List.of( + ghostspeak, + silverSickle + ); } @Override - public List getNotes() + public List getItemRecommended() { - return Collections.singletonList("Whilst in Mort Myre, the Ghasts will occasionally rot the food in your inventory."); + return List.of( + salveTele, + combatGear + ); } @Override public List getCombatRequirements() { - return Collections.singletonList("3 Ghasts (level 30)"); + return List.of( + "3 Ghasts (level 30)" + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.THE_RESTLESS_GHOST, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.PRIEST_IN_PERIL, QuestState.FINISHED)); - return req; + return List.of( + "Whilst in Mort Myre, the Ghasts will occasionally rot the food in your inventory." + ); } @Override @@ -317,33 +381,70 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Arrays.asList( - new ExperienceReward(Skill.CRAFTING, 3000), - new ExperienceReward(Skill.DEFENCE, 2000), - new ExperienceReward(Skill.HITPOINTS, 2000)); + return List.of( + new ExperienceReward(Skill.CRAFTING, 3000), + new ExperienceReward(Skill.DEFENCE, 2000), + new ExperienceReward(Skill.HITPOINTS, 2000) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to Mort Myre Swamp"), - new UnlockReward("Ability to fight Ghasts.")); + return List.of( + new UnlockReward("Access to Mort Myre Swamp"), + new UnlockReward("Ability to fight Ghasts.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Start the quest", - Arrays.asList(talkToDrezel, enterSwamp, tryToEnterGrotto, talkToFilliman, takeWashingBowl, - takeMirror, useMirrorOnFilliman, searchGrotto, useJournalOnFilliman), ghostspeak, silverSickle, prayerPoints)); - allSteps.add(new PanelDetails("Helping Filliman", - Arrays.asList(talkToDrezelForBlessing, castSpellAndGetMushroom, useMushroom, useSpellCard, standOnOrange, - tellFillimanToCast, enterGrotto, searchAltar, talkToFillimanInGrotto, blessSickle), ghostspeak, silverSickle)); - allSteps.add(new PanelDetails("Killing Ghasts", - Arrays.asList(fillPouches, killGhasts, enterGrottoAgain, talkToNatureSpiritToFinish), ghostspeak, blessedSickle, prayerPoints)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Start the quest", List.of( + talkToDrezel, + enterSwamp, + tryToEnterGrotto, + talkToFilliman, + takeWashingBowl, + takeMirror, + useMirrorOnFilliman, + searchGrotto, + useJournalOnFilliman + ), List.of( + ghostspeak, + silverSickle, + prayerPoints + ))); + + sections.add(new PanelDetails("Helping Filliman", List.of( + talkToDrezelForBlessing, + castSpellAndGetMushroom, + useMushroom, + useSpellCard, + standOnOrange, + tellFillimanToCast, + enterGrotto, + searchAltar, + talkToFillimanInGrotto, + blessSickle + ), List.of( + ghostspeak, + silverSickle + ))); + + sections.add(new PanelDetails("Killing Ghasts", List.of( + fillPouches, + killGhasts, + enterGrottoAgain, + talkToNatureSpiritToFinish + ), List.of( + ghostspeak, + blessedSickle, + prayerPoints + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java index ecea6eb355..b4760fc6bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/ObservatoryQuest.java @@ -30,6 +30,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -37,18 +39,23 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; public class ObservatoryQuest extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/StarSignAnswer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/StarSignAnswer.java deleted file mode 100644 index 89661aad86..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/observatoryquest/StarSignAnswer.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2021, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.helpers.quests.observatoryquest; - -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.VarbitChanged; -import net.runelite.api.gameval.NpcID; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestVarPlayer; -import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; - -import java.util.HashMap; - -public class StarSignAnswer extends NpcStep -{ - HashMap starSign = new HashMap<>(); - int currentValue = -1; - - public StarSignAnswer(QuestHelper questHelper) - { - super(questHelper, NpcID.OBSERVATORY_PROFESSOR, new WorldPoint(2440, 3159, - 1), "Tell the professor the constellation you observed."); - starSign.put(0, "Aquarius"); - starSign.put(1, "Capricorn"); - starSign.put(2, "Sagittarius"); - starSign.put(3, "Scorpio"); - starSign.put(4, "Libra"); - starSign.put(5, "Virgo"); - starSign.put(6, "Leo"); - starSign.put(7, "Cancer"); - starSign.put(8, "Gemini"); - starSign.put(9, "Taurus"); - starSign.put(10, "Aries"); - starSign.put(11, "Pisces"); - } - - @Override - public void startUp() - { - super.startUp(); - updateCorrectChoice(); - } - - @Override - public void onVarbitChanged(VarbitChanged varbitChanged) - { - super.onVarbitChanged(varbitChanged); - updateCorrectChoice(); - } - - private void updateCorrectChoice() - { - addDialogSteps("Talk about the Observatory quest."); - int currentStep = client.getVarpValue(QuestVarPlayer.QUEST_OBSERVATORY_QUEST.getId()); - if (currentStep < 2) - { - return; - } - - int newValue = client.getVarbitValue(3828); - if (currentValue != newValue) - { - currentValue = newValue; - String constellation = starSign.get(newValue); - setText("Tell the professor you observed " + constellation + "."); - addDialogStep(constellation); - } - - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java index 18224d1ca4..b273261a7c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/onesmallfavour/OneSmallFavour.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.onesmallfavour; +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; @@ -32,16 +33,32 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.TileStep; +import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -50,265 +67,302 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class OneSmallFavour extends BasicQuestHelper { - //Items Required - ItemRequirement steelBars4, steelBars3, steelBar, bronzeBar, ironBar, chisel, guam2, guam, marrentill, harralander, hammer, hammerHighlight, emptyCup, pigeonCages5, pot, hotWaterBowl, softClay, - opal, jade, sapphire, redTopaz, bluntAxe, herbalTincture, guthixRest, uncutSapphire, cupOfWater, - uncutOpal, uncutJade, uncutRedTopaz, stodgyMattress, mattress, animateRockScroll, animateRockScrollHighlight, ironOxide, brokenVane1, brokenVane2, brokenVane3, ornament, - weathervanePillar, directionals, weatherReport, unfiredPotLid, potLid, potWithLid, breathingSalts, chickenCages5, sharpenedAxe, redMahog; - - ItemRequirement guamTea, guam2Tea, harrTea, marrTea, guamMarrTea, guamHarrTea, harrMarrTea, guam2MarrTea, - guam2HarrTea, guamHarrMarrTea, herbTeaMix; - - //Items Recommended - ItemRequirement draynorVillageTeleports, lumbridgeTeleports, varrockTeleports, taverleyOrFaladorTeleports, camelotTeleports, fishingGuildAndDwarvenMineTeleports, ardougneTeleports, khazardTeleports, feldipHillsTeleports, pickaxe; - - Requirement inSanfewRoom, inHamBase, inDwarvenMine, inGoblinCave, lamp1Empty, lamp1Full, lamp2Empty, lamp2Full, - lamp3Empty, lamp3Full, lamp4Empty, lamp4Full, lamp5Empty, lamp5Full, lamp6Empty, lamp6Full, lamp7Empty, lamp7Full, lamp8Empty, lamp8Full, allEmpty, allFull, inScrollSpot, - slagilithNearby, petraNearby, inSeersVillageUpstairs, onRoof, addedOrnaments, addedDirectionals, addedWeathervanePillar, hasOrUsedOrnament, hasOrUsedDirectionals, - hasOrUsedWeathervanePillar; - - DetailedQuestStep talkToYanni, talkToJungleForester, talkToBrian, talkToAggie, goDownToJohanhus, talkToJohanhus, talkToFred, talkToSeth, talkToHorvik, - talkToApoth, talkToTassie, goDownToHammerspike, talkToHammerspike, goUpToSanfew, talkToSanfew, makeGuthixRest, talkToBleemadge, talkToArhein, talkToPhantuwti, enterGoblinCave, - searchWall, talkToCromperty, talkToTindel, talkToRantz, talkToGnormadium, talkToBleemadgeNoTea, take1, take2, take3, take4, take5, take6, take7, take8, - cutSaph, cutJade, cutTopaz, cutOpal, put1, put2, put3, put4, put5, put6, put7, put8, talkToGnormadiumAgain, returnToRantz, returnToTindel, returnToCromperty, getPigeonCages, - enterGoblinCaveAgain, standNextToSculpture, readScroll, killSlagilith, readScrollAgain, talkToPetra, returnToPhantuwti, goUpLadder, goUpToRoof, searchVane, useHammerOnVane, - goDownFromRoof, goDownLadderToSeers, useVane123OnAnvil, useVane2OnAnvil, useVane3OnAnvil, goBackUpLadder, goBackUpToRoof, useVane1, useVane2, useVane3, - goFromRoofToPhantuwti, goDownLadderToPhantuwti, finishWithPhantuwti, returnToArhein, returnToBleemadge, returnToSanfew, goDownToHammerspikeAgain, returnToHammerspike, - killGangMembers, talkToHammerspikeFinal, returnToTassie, spinPotLid, pickUpPot, firePotLid, usePotLidOnPot, returnToApothecary, returnToHorvik, talkToHorvikFinal, returnToSeth, - returnDownToJohnahus, returnToJohnahus, returnToAggie, returnToBrian, returnToForester, returnToYanni, returnUpToSanfew, returnToPhantuwti2, useVane12OnAnvil, useVane13OnAnvil, - useVane23OnAnvil, useVane1OnAnvil, fixAllLamps, searchVaneAgain; - - DetailedQuestStep useBowlOnCup, useHerbsOnCup; - - //Zones - Zone sanfewRoom, hamBase, dwarvenMine, goblinCave, scrollSpot, seersVillageUpstairs, roof; - - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToYanni); - steps.put(5, talkToJungleForester); - - steps.put(10, talkToBrian); - steps.put(15, talkToBrian); - - steps.put(20, talkToAggie); - - ConditionalStep goTalkToJohanhus = new ConditionalStep(this, goDownToJohanhus); - goTalkToJohanhus.addStep(inHamBase, talkToJohanhus); - - steps.put(25, goTalkToJohanhus); - steps.put(30, goTalkToJohanhus); - steps.put(35, goTalkToJohanhus); - steps.put(40, goTalkToJohanhus); - - steps.put(45, talkToFred); - steps.put(50, talkToSeth); - steps.put(55, talkToHorvik); - steps.put(60, talkToApoth); - steps.put(62, talkToApoth); - steps.put(63, talkToApoth); - - steps.put(65, talkToTassie); - - ConditionalStep goTalkToHammerspike = new ConditionalStep(this, goDownToHammerspike); - goTalkToHammerspike.addStep(inDwarvenMine, talkToHammerspike); - steps.put(70, goTalkToHammerspike); - - ConditionalStep goTalkToSanfew = new ConditionalStep(this, goUpToSanfew); - goTalkToSanfew.addStep(inSanfewRoom, talkToSanfew); - - steps.put(75, goTalkToSanfew); - - ConditionalStep makeGuthixRestForGnome = new ConditionalStep(this, useBowlOnCup); - makeGuthixRestForGnome.addStep(guthixRest, talkToBleemadge); - makeGuthixRestForGnome.addStep(new Conditions(LogicType.OR, herbTeaMix, cupOfWater), useHerbsOnCup); - - steps.put(80, makeGuthixRestForGnome); - steps.put(81, makeGuthixRestForGnome); - steps.put(82, makeGuthixRestForGnome); - steps.put(83, makeGuthixRestForGnome); - steps.put(84, makeGuthixRestForGnome); - - steps.put(86, talkToBleemadgeNoTea); - - steps.put(88, talkToArhein); - - steps.put(90, talkToPhantuwti); - - ConditionalStep investigateWall = new ConditionalStep(this, enterGoblinCave); - investigateWall.addStep(inGoblinCave, searchWall); - - steps.put(95, investigateWall); - - steps.put(100, talkToCromperty); - - steps.put(105, talkToTindel); - - steps.put(110, talkToRantz); - - steps.put(115, talkToGnormadium); - - ConditionalStep repairLights = new ConditionalStep(this, take1); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty, sapphire), put8); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty), cutSaph); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full), take8); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty, opal), put7); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty), cutOpal); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full), take7); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty, redTopaz), - put6); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty), cutTopaz); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full), take6); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty, jade), put5); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty), cutJade); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Full), take5); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Empty, sapphire), put4); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full, lamp4Empty), cutSaph); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Full), take4); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Empty, opal), put3); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full, lamp3Empty), cutOpal); - repairLights.addStep(new Conditions(lamp1Full, lamp2Full), take3); - repairLights.addStep(new Conditions(lamp1Full, lamp2Empty, redTopaz), put2); - repairLights.addStep(new Conditions(lamp1Full, lamp2Empty), cutTopaz); - repairLights.addStep(lamp1Full, take2); - repairLights.addStep(new Conditions(lamp1Empty, jade), put1); - repairLights.addStep(lamp1Empty, cutJade); - - steps.put(120, repairLights); - - steps.put(125, talkToGnormadiumAgain); - - steps.put(130, returnToRantz); - - steps.put(135, returnToTindel); - - steps.put(140, returnToCromperty); - - ConditionalStep fightSlagilith = new ConditionalStep(this, getPigeonCages); - fightSlagilith.addStep(slagilithNearby, killSlagilith); - fightSlagilith.addStep(inScrollSpot, readScroll); - fightSlagilith.addStep(inGoblinCave, standNextToSculpture); - fightSlagilith.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); - - steps.put(145, fightSlagilith); - steps.put(150, fightSlagilith); - - ConditionalStep freePetra = new ConditionalStep(this, getPigeonCages); - freePetra.addStep(petraNearby, talkToPetra); - freePetra.addStep(inScrollSpot, readScroll); - freePetra.addStep(inGoblinCave, standNextToSculpture); - freePetra.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); + // Required items + ItemRequirement steelBars4; + ItemRequirement bronzeBar; + ItemRequirement ironBar; + ItemRequirement chisel; + ItemRequirement guam2; + ItemRequirement marrentill; + ItemRequirement harralander; + ItemRequirement hammer; + ItemRequirement emptyCup; + ItemRequirement pot; + ItemRequirement hotWaterBowl; + + // Recommended items + ItemRequirement draynorVillageTeleports; + ItemRequirement lumbridgeTeleports; + ItemRequirement varrockTeleports; + ItemRequirement taverleyOrFaladorTeleports; + ItemRequirement camelotTeleports; + ItemRequirement fishingGuildAndDwarvenMineTeleports; + ItemRequirement ardougneTeleports; + ItemRequirement khazardTeleports; + ItemRequirement feldipHillsTeleports; + ItemRequirement pickaxe; + ItemRequirement opal2; + ItemRequirement jade2; + ItemRequirement redTopaz2; + ItemRequirement coins3000; + ItemRequirement combatGear; + + // Mid-quest item requirements + ItemRequirement opal; + ItemRequirement jade; + ItemRequirement redTopaz; + ItemRequirement sapphire; + ItemRequirement softClay; + ItemRequirement bluntAxe; + ItemRequirement herbalTincture; + ItemRequirement guthixRest; + ItemRequirement uncutSapphire; + ItemRequirement cupOfWater; + ItemRequirement uncutOpal; + ItemRequirement uncutJade; + ItemRequirement uncutRedTopaz; + ItemRequirement stodgyMattress; + ItemRequirement mattress; + ItemRequirement animateRockScroll; + ItemRequirement animateRockScrollHighlight; + ItemRequirement ironOxide; + ItemRequirement brokenVane1; + ItemRequirement brokenVane2; + ItemRequirement brokenVane3; + ItemRequirement ornament; + ItemRequirement weathervanePillar; + ItemRequirement directionals; + ItemRequirement weatherReport; + ItemRequirement unfiredPotLid; + ItemRequirement potLid; + ItemRequirement potWithLid; + ItemRequirement breathingSalts; + ItemRequirement chickenCages5; + ItemRequirement sharpenedAxe; + ItemRequirement redMahog; + ItemRequirement steelBars3; + ItemRequirement steelBar; + ItemRequirement guam; + ItemRequirement hammerHighlight; + ItemRequirement pigeonCages5; + ItemRequirement guamTea; + ItemRequirement guam2Tea; + ItemRequirement harrTea; + ItemRequirement marrTea; + ItemRequirement guamMarrTea; + ItemRequirement guamHarrTea; + ItemRequirement harrMarrTea; + ItemRequirement guam2MarrTea; + ItemRequirement guam2HarrTea; + ItemRequirement guamHarrMarrTea; + ItemRequirement herbTeaMix; + + // Zones + Zone sanfewRoom; + Zone hamBase; + Zone dwarvenMine; + Zone goblinCave; + Zone scrollSpot; + Zone seersVillageUpstairs; + Zone roof; + + // Miscellaneous requirements + ZoneRequirement inSanfewRoom; + ZoneRequirement inHamBase; + ZoneRequirement inDwarvenMine; + ZoneRequirement inGoblinCave; + VarbitRequirement lamp1Empty; + VarbitRequirement lamp1Full; + VarbitRequirement lamp2Empty; + VarbitRequirement lamp2Full; + VarbitRequirement lamp3Empty; + VarbitRequirement lamp3Full; + VarbitRequirement lamp4Empty; + VarbitRequirement lamp4Full; + VarbitRequirement lamp5Empty; + VarbitRequirement lamp5Full; + VarbitRequirement lamp6Empty; + VarbitRequirement lamp6Full; + VarbitRequirement lamp7Empty; + VarbitRequirement lamp7Full; + VarbitRequirement lamp8Empty; + VarbitRequirement lamp8Full; + VarbitRequirement allFull; + ZoneRequirement inScrollSpot; + NpcCondition slagilithNearby; + NpcCondition petraNearby; + ZoneRequirement inSeersVillageUpstairs; + ZoneRequirement onRoof; + VarbitRequirement addedOrnaments; + VarbitRequirement addedDirectionals; + VarbitRequirement addedWeathervanePillar; + Conditions hasOrUsedOrnament; + Conditions hasOrUsedDirectionals; + Conditions hasOrUsedWeathervanePillar; + FreeInventorySlotRequirement freeSlots3; + + // Steps + NpcStep talkToYanni; + + NpcStep talkToJungleForester; + + NpcStep talkToBrian; + + NpcStep talkToAggie; + + ObjectStep goDownToJohanhus; + NpcStep talkToJohanhus; + + NpcStep talkToFred; + + NpcStep talkToSeth; + + NpcStep talkToHorvik; + + NpcStep talkToApoth; + + NpcStep talkToTassie; + + ObjectStep goDownToHammerspike; + NpcStep talkToHammerspike; + + ObjectStep goUpToSanfew; + NpcStep talkToSanfew; + + DetailedQuestStep useBowlOnCup; + DetailedQuestStep useHerbsOnCup; + DetailedQuestStep makeGuthixRest; + NpcStep talkToBleemadge; + + NpcStep talkToBleemadgeNoTea; + + NpcStep talkToArhein; + + NpcStep talkToPhantuwti; + + ObjectStep enterGoblinCave; + ObjectStep searchWall; + + NpcStep talkToCromperty; + + NpcStep talkToTindel; + + NpcStep talkToRantz; + + NpcStep talkToGnormadium; - steps.put(152, freePetra); - steps.put(155, freePetra); + ObjectStep take1; + ObjectStep take2; + ObjectStep take3; + ObjectStep take4; + ObjectStep take5; + ObjectStep take6; + ObjectStep take7; + ObjectStep take8; + DetailedQuestStep cutSaph; + DetailedQuestStep cutJade; + DetailedQuestStep cutTopaz; + DetailedQuestStep cutOpal; + ObjectStep put1; + ObjectStep put2; + ObjectStep put3; + ObjectStep put4; + ObjectStep put5; + ObjectStep put6; + ObjectStep put7; + ObjectStep put8; + DetailedQuestStep fixAllLamps; - steps.put(160, returnToPhantuwti); - steps.put(165, returnToPhantuwti2); - steps.put(170, returnToPhantuwti2); + NpcStep talkToGnormadiumAgain; - ConditionalStep repairVane = new ConditionalStep(this, goUpLadder); - repairVane.addStep(onRoof, searchVane); - repairVane.addStep(inSeersVillageUpstairs, goUpToRoof); - - steps.put(175, repairVane); + NpcStep returnToRantz; - ConditionalStep hitVane = new ConditionalStep(this, goUpLadder); - hitVane.addStep(onRoof, useHammerOnVane); - hitVane.addStep(inSeersVillageUpstairs, goUpToRoof); + NpcStep returnToTindel; - steps.put(176, hitVane); + NpcStep returnToCromperty; - ConditionalStep getVaneBits = new ConditionalStep(this, goUpLadder); - getVaneBits.addStep(onRoof, searchVaneAgain); - getVaneBits.addStep(inSeersVillageUpstairs, goUpToRoof); + DetailedQuestStep getPigeonCages; + ObjectStep enterGoblinCaveAgain; + DetailedQuestStep standNextToSculpture; + DetailedQuestStep readScroll; + NpcStep killSlagilith; - steps.put(177, getVaneBits); + DetailedQuestStep readScrollAgain; + NpcStep talkToPetra; - ConditionalStep repairVaneParts = new ConditionalStep(this, useVane123OnAnvil); + NpcStep returnToPhantuwti; - repairVaneParts.addStep(new Conditions(addedOrnaments, addedDirectionals, weathervanePillar, onRoof), useVane3); - repairVaneParts.addStep(new Conditions(addedOrnaments, directionals, onRoof), useVane2); - repairVaneParts.addStep(new Conditions(ornament, onRoof), useVane1); - repairVaneParts.addStep(onRoof, goDownFromRoof); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar, inSeersVillageUpstairs), goBackUpToRoof); - repairVaneParts.addStep(inSeersVillageUpstairs, goDownLadderToSeers); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar), goBackUpLadder); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedOrnament), useVane3OnAnvil); - repairVaneParts.addStep(new Conditions(hasOrUsedOrnament, hasOrUsedWeathervanePillar), useVane1OnAnvil); - repairVaneParts.addStep(new Conditions(hasOrUsedDirectionals, hasOrUsedWeathervanePillar), useVane2OnAnvil); - repairVaneParts.addStep(hasOrUsedOrnament, useVane13OnAnvil); - repairVaneParts.addStep(hasOrUsedWeathervanePillar, useVane12OnAnvil); - repairVaneParts.addStep(hasOrUsedDirectionals, useVane23OnAnvil); + NpcStep returnToPhantuwti2; - steps.put(180, repairVaneParts); + ObjectStep goUpLadder; + ObjectStep goUpToRoof; + ObjectStep searchVane; - ConditionalStep reportBackToPhantuwti = new ConditionalStep(this, finishWithPhantuwti); - reportBackToPhantuwti.addStep(inSeersVillageUpstairs, goDownLadderToPhantuwti); - reportBackToPhantuwti.addStep(onRoof, goFromRoofToPhantuwti); + ObjectStep useHammerOnVane; - steps.put(185, reportBackToPhantuwti); + ObjectStep searchVaneAgain; - steps.put(190, returnToArhein); + ObjectStep goDownFromRoof; + ObjectStep goDownLadderToSeers; + ObjectStep useVane123OnAnvil; + ObjectStep useVane12OnAnvil; + ObjectStep useVane13OnAnvil; + ObjectStep useVane23OnAnvil; + ObjectStep useVane1OnAnvil; + ObjectStep useVane2OnAnvil; + ObjectStep useVane3OnAnvil; - steps.put(195, returnToBleemadge); + ObjectStep goBackUpLadder; + ObjectStep goBackUpToRoof; + ObjectStep useVane1; + ObjectStep useVane2; + ObjectStep useVane3; - ConditionalStep goAndReturnToSanfew = new ConditionalStep(this, returnUpToSanfew); - goAndReturnToSanfew.addStep(inSanfewRoom, returnToSanfew); - steps.put(200, goAndReturnToSanfew); + ObjectStep goFromRoofToPhantuwti; + ObjectStep goDownLadderToPhantuwti; + NpcStep finishWithPhantuwti; - ConditionalStep dealWithHammerspike = new ConditionalStep(this, goDownToHammerspikeAgain); - dealWithHammerspike.addStep(inDwarvenMine, returnToHammerspike); + NpcStep returnToArhein; - steps.put(205, dealWithHammerspike); + NpcStep returnToBleemadge; - ConditionalStep sortOutGangMembers = new ConditionalStep(this, goDownToHammerspikeAgain); - sortOutGangMembers.addStep(inDwarvenMine, killGangMembers); + ObjectStep returnUpToSanfew; + NpcStep returnToSanfew; - steps.put(210, sortOutGangMembers); - steps.put(215, sortOutGangMembers); - steps.put(220, sortOutGangMembers); - steps.put(225, dealWithHammerspike); + ObjectStep goDownToHammerspikeAgain; + NpcStep returnToHammerspike; - steps.put(230, returnToTassie); + NpcStep killGangMembers; - ConditionalStep makePotAndReturnToApoth = new ConditionalStep(this, spinPotLid); - makePotAndReturnToApoth.addStep(potWithLid, returnToApothecary); - makePotAndReturnToApoth.addStep(new Conditions(potLid, pot), usePotLidOnPot); - makePotAndReturnToApoth.addStep(potLid, pickUpPot); - makePotAndReturnToApoth.addStep(unfiredPotLid, firePotLid); + NpcStep talkToHammerspikeFinal; - steps.put(235, makePotAndReturnToApoth); + NpcStep returnToTassie; - steps.put(240, returnToHorvik); + ObjectStep spinPotLid; + ItemStep pickUpPot; + ObjectStep firePotLid; + DetailedQuestStep usePotLidOnPot; + NpcStep returnToApothecary; - steps.put(245, talkToHorvikFinal); + NpcStep returnToHorvik; - steps.put(250, returnToSeth); + NpcStep talkToHorvikFinal; - ConditionalStep goFinishWithJohanhus = new ConditionalStep(this, returnDownToJohnahus); - goFinishWithJohanhus.addStep(inHamBase, returnToJohnahus); + NpcStep returnToSeth; - steps.put(255, goFinishWithJohanhus); + ObjectStep returnDownToJohnahus; + NpcStep returnToJohnahus; - steps.put(260, returnToAggie); + NpcStep returnToAggie; - steps.put(265, returnToBrian); + NpcStep returnToBrian; - steps.put(270, returnToForester); + NpcStep returnToForester; - steps.put(275, returnToYanni); + NpcStep returnToYanni; - return steps; + @Override + protected void setupZones() + { + sanfewRoom = new Zone(new WorldPoint(2893, 3423, 1), new WorldPoint(2903, 3433, 1)); + hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); + dwarvenMine = new Zone(new WorldPoint(2960, 9696, 0), new WorldPoint(3062, 9854, 0)); + goblinCave = new Zone(new WorldPoint(2560, 9792, 0), new WorldPoint(2623, 9855, 0)); + scrollSpot = new Zone(new WorldPoint(2616, 9835, 0), new WorldPoint(2619, 9835, 0)); + seersVillageUpstairs = new Zone(new WorldPoint(2698, 3468, 1), new WorldPoint(2717, 3476, 1)); + roof = new Zone(new WorldPoint(2695, 3469, 3), new WorldPoint(2716, 3476, 3)); } @Override @@ -353,6 +407,18 @@ protected void setupRequirements() pickaxe = new ItemRequirement("Any pickaxe to kill Slagilith", ItemCollections.PICKAXES).isNotConsumed(); + combatGear = new ItemRequirement("Combat gear to fight Slagilith and the dwarf gang members", -1, -1); + combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); + + opal2 = new ItemRequirement("Opal", ItemID.OPAL, 2); + opal2.setHighlightInInventory(true); + jade2 = new ItemRequirement("Jade", ItemID.JADE, 2); + jade2.setHighlightInInventory(true); + redTopaz2 = new ItemRequirement("Red topaz", ItemID.RED_TOPAZ, 2); + redTopaz2.setHighlightInInventory(true); + coins3000 = new ItemRequirement("Coins", ItemID.COINS, 3000); + coins3000.setTooltip("Alternatively for purchasing backup gems from Gnormadium Avlafrim"); + bluntAxe = new ItemRequirement("Blunt axe", ItemID.FAVOUR_JUNGLEFORESTERAXE_BLUNT); bluntAxe.setTooltip("You can get another from a Jungle Forester south of Shilo Village"); herbalTincture = new ItemRequirement("Herbal tincture", ItemID.FAVOUR_HERBAL_TINCTURE); @@ -360,9 +426,9 @@ protected void setupRequirements() harrTea = new ItemRequirement("Herb tea mix (harralander)", ItemID.FAVOUR_CUP_HARRALANDER); guamTea = new ItemRequirement("Herb tea mix (guam)", ItemID.FAVOUR_CUP_GUAM); - marrTea = new ItemRequirement("Herb tea mix (marrentill)", ItemID.FAVOUR_CUP_MARRENTILL); + marrTea = new ItemRequirement("Herb tea mix (marrentill)", ItemID.FAVOUR_CUP_MARRENTILL); harrMarrTea = new ItemRequirement("Herb tea mix (harr/marr)", ItemID.FAVOUR_CUP_HARRALANDER_MARRENTILL); - guamHarrTea = new ItemRequirement("Herb tea mix (harr/guam)", ItemID.FAVOUR_CUP_HARRALANDER_GUAM); + guamHarrTea = new ItemRequirement("Herb tea mix (harr/guam)", ItemID.FAVOUR_CUP_HARRALANDER_GUAM); guam2Tea = new ItemRequirement("Herb tea mix (2 guam)", ItemID.FAVOUR_CUP_GUAM_GUAM); guamMarrTea = new ItemRequirement("Herb tea mix (marr/guam)", ItemID.FAVOUR_CUP_GUAM_MARRENTILL); guamHarrMarrTea = new ItemRequirement("Herb tea mix (harr/marr/guam)", ItemID.FAVOUR_CUP_HARRALANDER_MARRENTILL_GUAM); @@ -377,12 +443,9 @@ protected void setupRequirements() sapphire = new ItemRequirement("Sapphire", ItemID.SAPPHIRE); sapphire.setHighlightInInventory(true); - opal = new ItemRequirement("Opal", ItemID.OPAL); - opal.setHighlightInInventory(true); - jade = new ItemRequirement("Jade", ItemID.JADE); - jade.setHighlightInInventory(true); - redTopaz = new ItemRequirement("Red topaz", ItemID.RED_TOPAZ); - redTopaz.setHighlightInInventory(true); + opal = opal2.quantity(1); + jade = jade2.quantity(1); + redTopaz = redTopaz2.quantity(1); uncutSapphire = new ItemRequirement("Uncut sapphire", ItemID.UNCUT_SAPPHIRE); uncutSapphire.setHighlightInInventory(true); @@ -440,29 +503,14 @@ protected void setupRequirements() breathingSalts.setTooltip("You can get more by bringing the Apothecary another airtight pot and 200 gp"); chickenCages5 = new ItemRequirement("Chicken cage", ItemID.FAVOUR_CHICKEN_CAGE, 5); - chickenCages5.setTooltip("You can get more chicken cages by bringing Horvik a pidgeon cage and 100 coins per cage"); + chickenCages5.setTooltip("You can get more chicken cages by bringing Horvik a pigeon cage and 100 coins per cage"); sharpenedAxe = new ItemRequirement("Sharpened axe", ItemID.FAVOUR_JUNGLEFORESTERAXE_SHARP); sharpenedAxe.setTooltip("You can get another from Brian in Port Sarim"); redMahog = new ItemRequirement("Red mahogany log", ItemID.FAVOUR_MAHOGANY_LOG); redMahog.setTooltip("You can get another from a jungle forester for 200 gp"); - } - - @Override - protected void setupZones() - { - sanfewRoom = new Zone(new WorldPoint(2893, 3423, 1), new WorldPoint(2903, 3433, 1)); - hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); - dwarvenMine = new Zone(new WorldPoint(2960, 9696, 0), new WorldPoint(3062, 9854, 0)); - goblinCave = new Zone(new WorldPoint(2560, 9792, 0), new WorldPoint(2623, 9855, 0)); - scrollSpot = new Zone(new WorldPoint(2616, 9835, 0), new WorldPoint(2619, 9835, 0)); - seersVillageUpstairs = new Zone(new WorldPoint(2698, 3468, 1), new WorldPoint(2717, 3476, 1)); - roof = new Zone(new WorldPoint(2695, 3469, 3), new WorldPoint(2716, 3476, 3)); - } - public void setupConditions() - { inSanfewRoom = new ZoneRequirement(sanfewRoom); inHamBase = new ZoneRequirement(hamBase); inDwarvenMine = new ZoneRequirement(dwarvenMine); @@ -477,8 +525,6 @@ public void setupConditions() lamp7Empty = new VarbitRequirement(VarbitID.OPALLIGHT2_TAKEN, 1); lamp8Empty = new VarbitRequirement(VarbitID.SAPPHIRELIGHT2_TAKEN, 1); - allEmpty = new VarbitRequirement(VarbitID.CHECKLANDINGLIGHTS, 255); - lamp1Full = new VarbitRequirement(VarbitID.JADELIGHT1_FIXED, 1); lamp2Full = new VarbitRequirement(VarbitID.TOPAZLIGHT1_FIXED, 1); lamp3Full = new VarbitRequirement(VarbitID.OPALLIGHT1_FIXED, 1); @@ -501,19 +547,23 @@ public void setupConditions() addedDirectionals = new VarbitRequirement(VarbitID.DIRECTIONALSFIXED, 1); addedWeathervanePillar = new VarbitRequirement(VarbitID.ROTATINGPILLARFIXED, 1); - hasOrUsedDirectionals = new Conditions(LogicType.OR, addedDirectionals, directionals.alsoCheckBank()); - hasOrUsedOrnament = new Conditions(LogicType.OR, addedOrnaments, ornament.alsoCheckBank()); - hasOrUsedWeathervanePillar = new Conditions(LogicType.OR, addedWeathervanePillar, weathervanePillar.alsoCheckBank()); + hasOrUsedDirectionals = or(addedDirectionals, directionals.alsoCheckBank()); + hasOrUsedOrnament = or(addedOrnaments, ornament.alsoCheckBank()); + hasOrUsedWeathervanePillar = or(addedWeathervanePillar, weathervanePillar.alsoCheckBank()); + + freeSlots3 = new FreeInventorySlotRequirement(3); } - public void setupSteps() + void setupSteps() { talkToYanni = new NpcStep(this, NpcID.SHILOANTIQUES, new WorldPoint(2836, 2983, 0), "Talk to Yanni Salika in Shilo Village. CKR fairy ring or take cart from Brimhaven."); + talkToYanni.addDialogStep("Is there anything else interesting to do around here?"); talkToYanni.addDialogStep("Yes."); - talkToYanni.addDialogSteps("Is there anything else interesting to do around here?", "Ok, see you in a tick!"); + talkToJungleForester = new NpcStep(this, new int[]{NpcID.JUNGLEFORESTER_F, NpcID.JUNGLEFORESTER_M}, new WorldPoint(2861, 2942, 0), "Talk to a Jungle Forester south of Shilo Village.", true); - talkToJungleForester.addDialogSteps("I'll get going then!", "I need to talk to you about red mahogany."); + talkToJungleForester.addDialogStep("I need to talk to you about red mahogany."); talkToJungleForester.addDialogStep("Okay, I'll take your axe to get it sharpened."); + talkToBrian = new NpcStep(this, NpcID.BRIAN, new WorldPoint(3027, 3249, 0), "Talk to Brian in the Port Sarim axe shop.", bluntAxe); talkToBrian.addDialogStep("Do you sharpen axes?"); talkToBrian.addDialogStepWithExclusion("Look, can you sharpen this cursed axe or what?", "Ok, ok, I'll do it! I'll go and see Aggie."); @@ -561,32 +611,24 @@ public void setupSteps() talkToSanfew.addDialogSteps("A dwarf I know wants to become an initiate.", "Yep, it's a deal."); talkToSanfew.addSubSteps(goUpToSanfew); - useBowlOnCup = new DetailedQuestStep(this, "Use a bowl of hot water on an empty cup.", - hotWaterBowl.highlighted(), emptyCup.highlighted()); - useHerbsOnCup = new DetailedQuestStep(this, - "Use 2 guams, a marrentill and a harralander on the cup.", - guam2.hideConditioned(new Conditions(LogicType.OR, guamTea, guam2Tea, guamMarrTea, guamHarrTea, - guamHarrMarrTea)).highlighted(), - guam.hideConditioned(new Conditions(LogicType.OR, cupOfWater, marrTea, harrTea, guam2Tea, guam2MarrTea, - guam2HarrTea)).highlighted(), - marrentill.hideConditioned(new Conditions(LogicType.OR, marrTea, harrMarrTea, guamMarrTea, guam2MarrTea, - guamHarrMarrTea)).highlighted(), - harralander.hideConditioned(new Conditions(LogicType.OR, harrTea, harrMarrTea, guamHarrTea, guam2HarrTea, - guamHarrMarrTea)).highlighted(), - cupOfWater.hideConditioned(new Conditions(LogicType.OR, guamTea, harrTea, marrTea, harrMarrTea, guamHarrTea, - guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted(), - herbTeaMix.hideConditioned(new Conditions(LogicType.NOR, guamTea, harrTea, marrTea, harrMarrTea, - guamHarrTea, guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted()); + useBowlOnCup = new DetailedQuestStep(this, "Use a bowl of hot water on an empty cup.", hotWaterBowl.highlighted(), emptyCup.highlighted()); + useHerbsOnCup = new DetailedQuestStep(this, "Use 2 guams, a marrentill and a harralander on the cup.", + guam2.hideConditioned(or(guamTea, guam2Tea, guamMarrTea, guamHarrTea, guamHarrMarrTea)).highlighted(), + guam.hideConditioned(or(cupOfWater, marrTea, harrTea, guam2Tea, guam2MarrTea, guam2HarrTea)).highlighted(), + marrentill.hideConditioned(or(marrTea, harrMarrTea, guamMarrTea, guam2MarrTea, guamHarrMarrTea)).highlighted(), + harralander.hideConditioned(or(harrTea, harrMarrTea, guamHarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted(), + cupOfWater.hideConditioned(or(guamTea, harrTea, marrTea, harrMarrTea, guamHarrTea, guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted(), + herbTeaMix.hideConditioned(nor(guamTea, harrTea, marrTea, harrMarrTea, guamHarrTea, guam2Tea, guam2MarrTea, guamMarrTea, guam2HarrTea, guamHarrMarrTea)).highlighted()); makeGuthixRest = new DetailedQuestStep(this, "Make Guthix Rest by using a bowl of hot water on an empty tea cup, then using 2 guams, a marrentill and a harralander on it.", emptyCup, hotWaterBowl, guam2, marrentill, harralander); makeGuthixRest.addSubSteps(useBowlOnCup, useHerbsOnCup); talkToBleemadge = new NpcStep(this, NpcID.PILOT_WHITE_WOLF_BASE, new WorldPoint(2847, 3498, 0), "Right-click talk to Captain Bleemadge on White Wolf Mountain.", guthixRest); - ((NpcStep) talkToBleemadge).addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, + talkToBleemadge.addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, NpcID.PILOT_WHITE_WOLF_AL_KHARID, NpcID.PILOT_WHITE_WOLF_VARROCK, NpcID.PILOT_WHITE_WOLF_OGRE, NpcID.PILOT_WHITE_WOLF_APE); talkToBleemadge.addDialogStep("I have a special tea here for you from Sanfew!"); talkToBleemadgeNoTea = new NpcStep(this, NpcID.PILOT_WHITE_WOLF_BASE, new WorldPoint(2847, 3498, 0), "Right-click talk to Captain Bleemadge on White Wolf Mountain."); - ((NpcStep) talkToBleemadgeNoTea).addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, + talkToBleemadgeNoTea.addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, NpcID.PILOT_WHITE_WOLF_AL_KHARID, NpcID.PILOT_WHITE_WOLF_VARROCK, NpcID.PILOT_WHITE_WOLF_OGRE, NpcID.PILOT_WHITE_WOLF_APE); talkToBleemadgeNoTea.addDialogStep("How was that tea?"); @@ -607,7 +649,7 @@ public void setupSteps() searchWall = new ObjectStep(this, ObjectID.FAVOUR_LADY_IN_WALL, new WorldPoint(2621, 9835, 0), "Right-click search the sculpture in the wall in the north east corner of the cave."); talkToCromperty = new NpcStep(this, NpcID.CROMPERTY_PRE_DIARY, new WorldPoint(2684, 3323, 0), "Talk to Wizard Cromperty in north east Ardougne."); - ((NpcStep) talkToCromperty).addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); + talkToCromperty.addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); talkToCromperty.addDialogStep("Chat."); talkToCromperty.addDialogStep("I need to talk to you about a girl stuck in some rock!"); talkToCromperty.addDialogStep("Oh! Ok, one more 'small favour' isn't going to kill me...I hope!"); @@ -668,7 +710,7 @@ public void setupSteps() returnToTindel.addDialogStep("I have the mattress."); returnToCromperty = new NpcStep(this, NpcID.CROMPERTY_PRE_DIARY, new WorldPoint(2684, 3323, 0), "Return to Wizard Cromperty in north east Ardougne.", ironOxide); - ((NpcStep) returnToCromperty).addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); + returnToCromperty.addAlternateNpcs(NpcID.CROMPERTY_PRE_DIARY, NpcID.CROMPERTY_POST_DIARY); returnToCromperty.addDialogStep("Chat."); returnToCromperty.addDialogStep("I have that iron oxide you asked for!"); @@ -676,14 +718,14 @@ public void setupSteps() enterGoblinCaveAgain = new ObjectStep(this, ObjectID.MCANNONCAVE, new WorldPoint(2624, 3393, 0), "Enter the cave south east of the Fishing Guild. " + "Be prepared to fight the Slagilith(level 92, takes reduced damage from anything other than pickaxes).", Arrays.asList(pigeonCages5, animateRockScroll), Collections.singletonList(pickaxe)); - standNextToSculpture = new DetailedQuestStep(this, new WorldPoint(2616, 9835, 0), "Use the animate rock scroll next to the sculpture in the north east cavern.", animateRockScroll); + standNextToSculpture = new TileStep(this, new WorldPoint(2616, 9835, 0), "Use the animate rock scroll next to the sculpture in the north east cavern.", animateRockScroll); readScroll = new DetailedQuestStep(this, "Read the animate rock scroll.", animateRockScrollHighlight); standNextToSculpture.addSubSteps(readScroll); killSlagilith = new NpcStep(this, NpcID.SLAGILITH, new WorldPoint(2617, 9837, 0), "Kill the Slagilith. They take reduced damage from anything other than a pickaxe."); killSlagilith.addRecommended(pickaxe); - readScrollAgain = new DetailedQuestStep(this, "Read the animate rock scroll.", animateRockScrollHighlight); + readScrollAgain = new DetailedQuestStep(this, "Read the animate rock scroll again.", animateRockScrollHighlight); talkToPetra = new NpcStep(this, NpcID.FAVOUR_PETRA, new WorldPoint(2617, 9837, 0), "Talk to Petra Fiyed."); returnToPhantuwti = new NpcStep(this, NpcID.FAVOUR_PHANTUWTI_FARSIGHT, new WorldPoint(2702, 3473, 0), "Return to Phantuwti in the south west house of Seers' Village."); @@ -705,9 +747,11 @@ public void setupSteps() searchVane.addSubSteps(goUpLadder, goUpToRoof); useHammerOnVane = new ObjectStep(this, ObjectID.OSF_WEATHERVANE, new WorldPoint(2702, 3476, 3), "Use a hammer on the weathervane.", hammerHighlight); useHammerOnVane.addIcon(ItemID.HAMMER); - searchVaneAgain = new ObjectStep(this, ObjectID.OSF_WEATHERVANE, new WorldPoint(2702, 3476, 3), "Right-click search the weathervane on top of the Seers' building again."); + + searchVaneAgain = new ObjectStep(this, ObjectID.OSF_WEATHERVANE, new WorldPoint(2702, 3476, 3), "Right-click search the weathervane on top of the Seers' building again.", freeSlots3); goDownFromRoof = new ObjectStep(this, ObjectID.FAVOUR_ROOF_TRAPDOOR, new WorldPoint(2715, 3472, 3), "Climb down from the roof."); + goDownFromRoof.addDialogStep("Yes."); goDownLadderToSeers = new ObjectStep(this, ObjectID.KR_LADDERTOP, new WorldPoint(2715, 3470, 1), "Repair the vane parts on the anvil in north Seers' Village."); useVane123OnAnvil = new ObjectStep(this, ObjectID.ANVIL, new WorldPoint(2712, 3495, 0), "Repair the vane parts on an anvil. You can find one in the north of Seers' Village.", brokenVane1, brokenVane2, brokenVane3, hammer, steelBar, ironBar, bronzeBar); useVane12OnAnvil = new ObjectStep(this, ObjectID.ANVIL, new WorldPoint(2712, 3495, 0), "Repair the vane parts on an anvil. You can find one in the north of Seers' Village.", brokenVane1, brokenVane2, hammer, steelBar, bronzeBar); @@ -726,6 +770,7 @@ public void setupSteps() goBackUpLadder.addSubSteps(goBackUpToRoof, useVane1, useVane2, useVane3); goFromRoofToPhantuwti = new ObjectStep(this, ObjectID.FAVOUR_ROOF_TRAPDOOR, new WorldPoint(2715, 3472, 3), "Return to Phantuwti."); + goFromRoofToPhantuwti.addDialogStep("Yes."); goDownLadderToPhantuwti = new ObjectStep(this, ObjectID.KR_LADDERTOP_DIRECTIONAL, new WorldPoint(2699, 3476, 1), "Return to Phantuwti."); finishWithPhantuwti = new NpcStep(this, NpcID.FAVOUR_PHANTUWTI_FARSIGHT, new WorldPoint(2702, 3473, 0), "Return to Phantuwti in the south west house of Seers' Village."); finishWithPhantuwti.addSubSteps(goFromRoofToPhantuwti, goDownLadderToPhantuwti); @@ -737,28 +782,29 @@ public void setupSteps() returnToBleemadge = new NpcStep(this, NpcID.PILOT_WHITE_WOLF_BASE, new WorldPoint(2847, 3498, 0), "Right-click talk to Captain Bleemadge on White Wolf Mountain."); returnToBleemadge.addDialogStep("Hey there, did you get your T.R.A.S.H?"); - ((NpcStep) returnToBleemadge).addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, + returnToBleemadge.addAlternateNpcs(NpcID.PILOT_WHITE_WOLF_GRANDTREE, NpcID.PILOT_WHITE_WOLF_KARAMJA, NpcID.PILOT_WHITE_WOLF_AL_KHARID, NpcID.PILOT_WHITE_WOLF_VARROCK, NpcID.PILOT_WHITE_WOLF_OGRE, NpcID.PILOT_WHITE_WOLF_APE); returnUpToSanfew = new ObjectStep(this, ObjectID.SPIRALSTAIRS, new WorldPoint(2899, 3429, 0), "Return to Sanfew upstairs in the Taverley herblore store."); returnToSanfew = new NpcStep(this, NpcID.SANFEW, new WorldPoint(2899, 3429, 1), "Return to Sanfew upstairs in the Taverley herblore store."); returnToSanfew.addDialogStep("Hi there, the Gnome Pilot has agreed to take you to see the ogres!"); + returnToSanfew.addSubSteps(returnUpToSanfew); goDownToHammerspikeAgain = new ObjectStep(this, ObjectID.FAI_DWARF_TRAPDOOR_DOWN, new WorldPoint(3019, 3450, 0), "Return to the Dwarven Mine and talk to Hammerspike Stoutbeard in the west side."); returnToHammerspike = new NpcStep(this, NpcID.FAVOUR_HAMMERSPIKE_STOUTBEARD, new WorldPoint(2968, 9811, 0), "Return to Hammerspike Stoutbeard in the west cavern of the Dwarven Mine."); returnToHammerspike.addSubSteps(goDownToHammerspikeAgain); killGangMembers = new NpcStep(this, NpcID.FAVOUR_GANGSTER_DWARF, new WorldPoint(2968, 9811, 0), - "Kill 3 dwarf gang members until Hammerspike gives in. One dwarf gang member should appear after each kill.", true); - ((NpcStep) killGangMembers).addAlternateNpcs(NpcID.FAVOUR_GANGSTER_DWARF_2, NpcID.FAVOUR_GANGSTER_DWARF_3); - talkToHammerspikeFinal = new NpcStep(this, NpcID.FAVOUR_HAMMERSPIKE_STOUTBEARD, new WorldPoint(2968, 9811, 0), "Return to Hammerspike Stoutbeard in the west cavern of the Dwarven Mine."); + "Kill 3 dwarf gang members until Hammerspike gives in. One dwarf gang member should appear after each kill.", true); + killGangMembers.addAlternateNpcs(NpcID.FAVOUR_GANGSTER_DWARF_2, NpcID.FAVOUR_GANGSTER_DWARF_3); + talkToHammerspikeFinal = new NpcStep(this, NpcID.FAVOUR_HAMMERSPIKE_STOUTBEARD, new WorldPoint(2968, 9811, 0), "Return to Hammerspike Stoutbeard in the west cavern of the Dwarven Mine after killing his dwarf gang members."); returnToTassie = new NpcStep(this, NpcID.FAVOUR_TASSIE_SLIPCAST, new WorldPoint(3085, 3409, 0), "Return to Tassie Slipcast in the Barbarian Village pottery building."); spinPotLid = new ObjectStep(this, ObjectID.POTTERYWHEEL, new WorldPoint(3087, 3409, 0), "Spin the clay into a pot lid.", softClay); - spinPotLid.addWidgetHighlightWithItemIdRequirement(270, 19, ItemID.POTLID_UNFIRED, true); + spinPotLid.addWidgetHighlight(WidgetHighlight.createMultiskillByItemId(ItemID.POTLID_UNFIRED)); pickUpPot = new ItemStep(this, "Get a pot to put your lid on. There's one in the Barbarian Village helmet shop.", pot); firePotLid = new ObjectStep(this, ObjectID.FAI_BARBARIAN_POTTERY_OVEN, new WorldPoint(3085, 3407, 0), "Fire the unfired pot lid.", unfiredPotLid); - firePotLid.addWidgetHighlightWithItemIdRequirement(270, 19, ItemID.POTLID, true); + firePotLid.addWidgetHighlight(WidgetHighlight.createMultiskillByItemId(ItemID.POTLID_UNFIRED)); usePotLidOnPot = new DetailedQuestStep(this, "Use the pot lid on a pot.", pot, potLid); returnToApothecary = new NpcStep(this, NpcID.APOTHECARY, new WorldPoint(3196, 3404, 0), "Return to the Apothecary in west Varrock.", potWithLid); returnToApothecary.addDialogStep("Talk about One Small Favour."); @@ -784,62 +830,293 @@ public void setupSteps() } @Override - public List getItemRequirements() + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + Map steps = new HashMap<>(); + + steps.put(0, talkToYanni); + steps.put(5, talkToJungleForester); + + steps.put(10, talkToBrian); + steps.put(15, talkToBrian); + + steps.put(20, talkToAggie); + + var goTalkToJohanhus = new ConditionalStep(this, goDownToJohanhus); + goTalkToJohanhus.addStep(inHamBase, talkToJohanhus); + + steps.put(25, goTalkToJohanhus); + steps.put(30, goTalkToJohanhus); + steps.put(35, goTalkToJohanhus); + steps.put(40, goTalkToJohanhus); + + steps.put(45, talkToFred); + steps.put(50, talkToSeth); + steps.put(55, talkToHorvik); + steps.put(60, talkToApoth); + steps.put(62, talkToApoth); + steps.put(63, talkToApoth); + + steps.put(65, talkToTassie); + + var goTalkToHammerspike = new ConditionalStep(this, goDownToHammerspike); + goTalkToHammerspike.addStep(inDwarvenMine, talkToHammerspike); + steps.put(70, goTalkToHammerspike); + + var goTalkToSanfew = new ConditionalStep(this, goUpToSanfew); + goTalkToSanfew.addStep(inSanfewRoom, talkToSanfew); + + steps.put(75, goTalkToSanfew); + + var makeGuthixRestForGnome = new ConditionalStep(this, useBowlOnCup); + makeGuthixRestForGnome.addStep(guthixRest, talkToBleemadge); + makeGuthixRestForGnome.addStep(or(herbTeaMix, cupOfWater), useHerbsOnCup); + + steps.put(80, makeGuthixRestForGnome); + steps.put(81, makeGuthixRestForGnome); + steps.put(82, makeGuthixRestForGnome); + steps.put(83, makeGuthixRestForGnome); + steps.put(84, makeGuthixRestForGnome); + + steps.put(86, talkToBleemadgeNoTea); + + steps.put(88, talkToArhein); + + steps.put(90, talkToPhantuwti); + + var investigateWall = new ConditionalStep(this, enterGoblinCave); + investigateWall.addStep(inGoblinCave, searchWall); + + steps.put(95, investigateWall); + + steps.put(100, talkToCromperty); + + steps.put(105, talkToTindel); + + steps.put(110, talkToRantz); + + steps.put(115, talkToGnormadium); + + var repairLights = new ConditionalStep(this, take1); + repairLights.addStep(allFull, talkToGnormadiumAgain); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty, sapphire), put8); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full, lamp8Empty), cutSaph); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Full), take8); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty, opal), put7); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full, lamp7Empty), cutOpal); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Full), take7); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty, redTopaz), put6); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full, lamp6Empty), cutTopaz); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Full), take6); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty, jade), put5); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full, lamp5Empty), cutJade); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Full), take5); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Empty, sapphire), put4); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full, lamp4Empty), cutSaph); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Full), take4); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Empty, opal), put3); + repairLights.addStep(and(lamp1Full, lamp2Full, lamp3Empty), cutOpal); + repairLights.addStep(and(lamp1Full, lamp2Full), take3); + repairLights.addStep(and(lamp1Full, lamp2Empty, redTopaz), put2); + repairLights.addStep(and(lamp1Full, lamp2Empty), cutTopaz); + repairLights.addStep(lamp1Full, take2); + repairLights.addStep(and(lamp1Empty, jade), put1); + repairLights.addStep(lamp1Empty, cutJade); + + steps.put(120, repairLights); + + steps.put(125, talkToGnormadiumAgain); + + steps.put(130, returnToRantz); + + steps.put(135, returnToTindel); + + steps.put(140, returnToCromperty); + + var fightSlagilith = new ConditionalStep(this, getPigeonCages); + fightSlagilith.addStep(slagilithNearby, killSlagilith); + fightSlagilith.addStep(inScrollSpot, readScroll); + fightSlagilith.addStep(inGoblinCave, standNextToSculpture); + fightSlagilith.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); + + steps.put(145, fightSlagilith); + steps.put(150, fightSlagilith); + + var freePetra = new ConditionalStep(this, getPigeonCages); + freePetra.addStep(petraNearby, talkToPetra); + freePetra.addStep(inScrollSpot, readScrollAgain); + freePetra.addStep(inGoblinCave, standNextToSculpture); + freePetra.addStep(pigeonCages5.alsoCheckBank(), enterGoblinCaveAgain); + + steps.put(152, freePetra); + steps.put(155, freePetra); + + steps.put(160, returnToPhantuwti); + steps.put(165, returnToPhantuwti2); + steps.put(170, returnToPhantuwti2); + + var repairVane = new ConditionalStep(this, goUpLadder); + repairVane.addStep(onRoof, searchVane); + repairVane.addStep(inSeersVillageUpstairs, goUpToRoof); + + steps.put(175, repairVane); + + var hitVane = new ConditionalStep(this, goUpLadder); + hitVane.addStep(onRoof, useHammerOnVane); + hitVane.addStep(inSeersVillageUpstairs, goUpToRoof); + + steps.put(176, hitVane); + + var getVaneBits = new ConditionalStep(this, goUpLadder); + getVaneBits.addStep(onRoof, searchVaneAgain); + getVaneBits.addStep(inSeersVillageUpstairs, goUpToRoof); + + steps.put(177, getVaneBits); + + var repairVaneParts = new ConditionalStep(this, useVane123OnAnvil); + + repairVaneParts.addStep(and(addedOrnaments, addedDirectionals, weathervanePillar, onRoof), useVane3); + repairVaneParts.addStep(and(addedOrnaments, directionals, onRoof), useVane2); + repairVaneParts.addStep(and(ornament, onRoof), useVane1); + repairVaneParts.addStep(onRoof, goDownFromRoof); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar, inSeersVillageUpstairs), goBackUpToRoof); + repairVaneParts.addStep(inSeersVillageUpstairs, goDownLadderToSeers); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedOrnament, hasOrUsedWeathervanePillar), goBackUpLadder); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedOrnament), useVane3OnAnvil); + repairVaneParts.addStep(and(hasOrUsedOrnament, hasOrUsedWeathervanePillar), useVane1OnAnvil); + repairVaneParts.addStep(and(hasOrUsedDirectionals, hasOrUsedWeathervanePillar), useVane2OnAnvil); + repairVaneParts.addStep(hasOrUsedOrnament, useVane13OnAnvil); + repairVaneParts.addStep(hasOrUsedWeathervanePillar, useVane12OnAnvil); + repairVaneParts.addStep(hasOrUsedDirectionals, useVane23OnAnvil); + + steps.put(180, repairVaneParts); + + var reportBackToPhantuwti = new ConditionalStep(this, finishWithPhantuwti); + reportBackToPhantuwti.addStep(inSeersVillageUpstairs, goDownLadderToPhantuwti); + reportBackToPhantuwti.addStep(onRoof, goFromRoofToPhantuwti); + + steps.put(185, reportBackToPhantuwti); + + steps.put(190, returnToArhein); + + steps.put(195, returnToBleemadge); + + var goAndReturnToSanfew = new ConditionalStep(this, returnUpToSanfew); + goAndReturnToSanfew.addStep(inSanfewRoom, returnToSanfew); + steps.put(200, goAndReturnToSanfew); + + var dealWithHammerspike = new ConditionalStep(this, goDownToHammerspikeAgain); + dealWithHammerspike.addStep(inDwarvenMine, returnToHammerspike); + + steps.put(205, dealWithHammerspike); + + var sortOutGangMembers = new ConditionalStep(this, goDownToHammerspikeAgain); + sortOutGangMembers.addStep(inDwarvenMine, killGangMembers); + + steps.put(210, sortOutGangMembers); + steps.put(215, sortOutGangMembers); + steps.put(220, sortOutGangMembers); + + var dealWithHammerspikeAfterKillingHisGang = new ConditionalStep(this, goDownToHammerspikeAgain); + dealWithHammerspikeAfterKillingHisGang.addStep(inDwarvenMine, talkToHammerspikeFinal); + steps.put(225, dealWithHammerspikeAfterKillingHisGang); + + steps.put(230, returnToTassie); + + var makePotAndReturnToApoth = new ConditionalStep(this, spinPotLid); + makePotAndReturnToApoth.addStep(potWithLid, returnToApothecary); + makePotAndReturnToApoth.addStep(and(potLid, pot), usePotLidOnPot); + makePotAndReturnToApoth.addStep(potLid, pickUpPot); + makePotAndReturnToApoth.addStep(unfiredPotLid, firePotLid); + + steps.put(235, makePotAndReturnToApoth); + + steps.put(240, returnToHorvik); + + steps.put(245, talkToHorvikFinal); + + steps.put(250, returnToSeth); + + var goFinishWithJohanhus = new ConditionalStep(this, returnDownToJohnahus); + goFinishWithJohanhus.addStep(inHamBase, returnToJohnahus); + + steps.put(255, goFinishWithJohanhus); + + steps.put(260, returnToAggie); + + steps.put(265, returnToBrian); + + steps.put(270, returnToForester); + + steps.put(275, returnToYanni); + + return steps; + } + + @Override + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(steelBars4); - reqs.add(bronzeBar); - reqs.add(ironBar); - reqs.add(chisel); - reqs.add(guam2); - reqs.add(marrentill); - reqs.add(harralander); - reqs.add(hammer); - reqs.add(emptyCup); - reqs.add(pot); - reqs.add(hotWaterBowl); - - return reqs; + return List.of( + new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.SHILO_VILLAGE, QuestState.FINISHED), + new SkillRequirement(Skill.AGILITY, 36, true), + new SkillRequirement(Skill.CRAFTING, 25, true), + new SkillRequirement(Skill.HERBLORE, 18, true), + new SkillRequirement(Skill.SMITHING, 30, true) + ); } + @Override - public List getItemRecommended() + public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(draynorVillageTeleports); - reqs.add(lumbridgeTeleports); - reqs.add(varrockTeleports); - reqs.add(taverleyOrFaladorTeleports); - reqs.add(camelotTeleports); - reqs.add(fishingGuildAndDwarvenMineTeleports); - reqs.add(ardougneTeleports); - reqs.add(khazardTeleports); - reqs.add(feldipHillsTeleports); - reqs.add(opal.quantity(2)); - reqs.add(jade.quantity(2)); - reqs.add(redTopaz.quantity(2)); - reqs.add(pickaxe); - return reqs; + return List.of( + steelBars4, + bronzeBar, + ironBar, + chisel, + guam2, + marrentill, + harralander, + hammer, + emptyCup, + pot, + hotWaterBowl + ); } @Override - public List getCombatRequirements() + public List getItemRecommended() { - return Arrays.asList("Slagilith (level 92)", "3x Dwarf gang members (level 44)"); + return List.of( + draynorVillageTeleports, + lumbridgeTeleports, + varrockTeleports, + taverleyOrFaladorTeleports, + camelotTeleports, + fishingGuildAndDwarvenMineTeleports, + ardougneTeleports, + khazardTeleports, + feldipHillsTeleports, + opal2, + jade2, + redTopaz2, + coins3000, + pickaxe + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.SHILO_VILLAGE, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.AGILITY, 36, true)); - req.add(new SkillRequirement(Skill.CRAFTING, 25, true)); - req.add(new SkillRequirement(Skill.HERBLORE, 18, true)); - req.add(new SkillRequirement(Skill.SMITHING, 30, true)); - return req; + return List.of( + "Slagilith (level 92)", + "3x Dwarf gang members (level 44)" + ); } @Override @@ -851,36 +1128,117 @@ public QuestPointReward getQuestPointReward() @Override public List getItemRewards() { - return Arrays.asList( - new ItemReward("10,000 Experience Lamps (Any skill over level 30)", ItemID.THOSF_REWARD_LAMP, 2), //4447 is placeholder for filter - new ItemReward("A Steel Keyring", ItemID.FAVOUR_KEY_RING, 1)); + return List.of( + new ItemReward("10,000 Experience Lamps (Any skill over level 30)", ItemID.THOSF_REWARD_LAMP, 2), + new ItemReward("A Steel Keyring", ItemID.FAVOUR_KEY_RING, 1) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("The ability to make Guthix Rest tea."), - new UnlockReward("Gnome Glider in Feldip Hills.")); + return List.of( + new UnlockReward("The ability to make Guthix Rest tea."), + new UnlockReward("Gnome Glider in Feldip Hills.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToYanni))); - allSteps.add(new PanelDetails("A few small favours", Arrays.asList(talkToJungleForester, talkToBrian, talkToAggie, talkToJohanhus, talkToFred, talkToSeth, - talkToHorvik, talkToApoth, talkToTassie, talkToHammerspike, talkToSanfew, makeGuthixRest, talkToBleemadge, talkToArhein, talkToPhantuwti, enterGoblinCave, - searchWall, talkToCromperty, talkToTindel, talkToRantz, talkToGnormadium, fixAllLamps), - chisel, steelBars3, emptyCup, hotWaterBowl, guam2, marrentill, harralander)); - allSteps.add(new PanelDetails("Completing the favours", Arrays.asList(talkToGnormadiumAgain, returnToRantz, - returnToTindel, returnToCromperty, getPigeonCages, enterGoblinCaveAgain, standNextToSculpture, killSlagilith, - readScrollAgain, talkToPetra, returnToPhantuwti, searchVane, useHammerOnVane, searchVaneAgain, - useVane123OnAnvil, goBackUpLadder, finishWithPhantuwti, returnToArhein, returnToBleemadge, returnToSanfew, - returnToHammerspike, killGangMembers, talkToHammerspikeFinal, returnToTassie, spinPotLid, firePotLid, pickUpPot, - usePotLidOnPot, returnToApothecary, returnToHorvik, talkToHorvikFinal, returnToSeth, returnToJohnahus, returnToAggie, - returnToBrian, returnToForester, returnToYanni), bronzeBar, ironBar, steelBar, hammer, pot)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToYanni + ))); + + sections.add(new PanelDetails("A few small favours", List.of( + talkToJungleForester, + talkToBrian, + talkToAggie, + talkToJohanhus, + talkToFred, + talkToSeth, + talkToHorvik, + talkToApoth, + talkToTassie, + talkToHammerspike, + talkToSanfew, + makeGuthixRest, + talkToBleemadge, + talkToArhein, + talkToPhantuwti, + enterGoblinCave, + searchWall, + talkToCromperty, + talkToTindel, + talkToRantz, + talkToGnormadium, + fixAllLamps + ), List.of( + chisel, + steelBars3, + emptyCup, + hotWaterBowl, + guam2, + marrentill, + harralander + ), List.of( + opal2, + jade2, + redTopaz2, + coins3000 + ))); + + sections.add(new PanelDetails("Completing the favours", List.of( + talkToGnormadiumAgain, + returnToRantz, + returnToTindel, + returnToCromperty, + getPigeonCages, + enterGoblinCaveAgain, + standNextToSculpture, + killSlagilith, + readScrollAgain, + talkToPetra, + returnToPhantuwti, + searchVane, + useHammerOnVane, + searchVaneAgain, + useVane123OnAnvil, + goBackUpLadder, + finishWithPhantuwti, + returnToArhein, + returnToBleemadge, + returnToSanfew, + returnToHammerspike, + killGangMembers, + talkToHammerspikeFinal, + returnToTassie, + spinPotLid, + firePotLid, + pickUpPot, + usePotLidOnPot, + returnToApothecary, + returnToHorvik, + talkToHorvikFinal, + returnToSeth, + returnToJohnahus, + returnToAggie, + returnToBrian, + returnToForester, + returnToYanni + ), List.of( + bronzeBar, + ironBar, + steelBar, + hammer, + pot + ), List.of( + combatGear, + pickaxe + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java index 1d1cfc0ac4..8360d6e890 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pandemonium/Pandemonium.java @@ -27,11 +27,14 @@ import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.NoItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.ShipInPortRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.ItemSlots; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Port; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; @@ -41,143 +44,106 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.BoardShipStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.SailStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - -import java.util.*; -import java.util.regex.Pattern; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; public class Pandemonium extends BasicQuestHelper { - NpcStep getToPandemonium, talkToWill, boardWAShip, explainJob, explainJob2, learnWhereYouAre, learnWhoWAare, talkToRibs, findLocationWA, enterShipyard, informAboutShip, showCup, getLogBook, getNewJob, talkToJim, meetGrog, finishQuest; - ObjectStep buildCargoHold, embarkShipSY, disembarkShipSY, leaveShipyard,dropCargoInCargoHold, disembarkShipPS, deliverCargo, disembarkShipP, getHammer, getSaw; - Zone pandemonium, portSarim, pandemoniumDockZone, portSarimDockZone, shipWreckZone; - DetailedQuestStep navigateShip, watchSalvageCutscene, takeHelm, takeHelm2, takeHelm3, raiseSails, raiseSails2, raiseSails3, salvageShipwreck, sailToPortSarim, pickupCargo, pickupCargoShip, sailToPandemonium, letGoOfHelm, letGoOfHelm2; - BoardShipStep boardShip, boardShip2, boardShip3; - Requirement onPandemonium, boatAtPortSarim, onboardShip, takenHelm, setSails, sailing, atShipwreck, notAtShipwreck, canSalvage, hammerAndSaw, atShipyard, atPortSarimDock, atPandemoniumDock, holdingCargo, cargoPickedUp, cargoNotPickedUp, cargoInCargoHold; - ItemRequirement hammer, saw, cup; + // Required items + ItemRequirement hammer; + ItemRequirement saw; + + // Mid-quest item requirements + ItemRequirement cup; + + // Zones + Zone pandemonium; + Zone portSarim; + Zone pandemoniumDockZone; + Zone portSarimDockZone; + Zone shipWreckZone; + + // Miscellaneous requirements + ZoneRequirement onPandemonium; + ShipInPortRequirement boatAtPortSarim; + VarbitRequirement onboardShip; + VarbitRequirement takenHelm; + VarbitRequirement setSails; + Conditions sailing; + VarbitRequirement atShipwreck; + Conditions canSalvage; + VarbitRequirement atShipyard; + VarbitRequirement holdingCargo; + VarbitRequirement cargoPickedUp; + Conditions cargoNotPickedUp; + ZoneRequirement atPortSarimDock; + ZoneRequirement atPandemoniumDock; + Conditions cargoInCargoHold; NoItemRequirement nothingInHands; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToWill); - steps.put(2, talkToWill); - - steps.put(4, boardWAShip); - - ConditionalStep goListenOnShip = new ConditionalStep(this, talkToWill); - goListenOnShip.addStep(onboardShip, explainJob); - steps.put(6, goListenOnShip); - - ConditionalStep cNavigateToShipwreckOnShip = new ConditionalStep(this, takeHelm); - cNavigateToShipwreckOnShip.addStep(canSalvage, salvageShipwreck); - cNavigateToShipwreckOnShip.addStep(atShipwreck, explainJob2); - cNavigateToShipwreckOnShip.addStep(sailing, navigateShip); - cNavigateToShipwreckOnShip.addStep(takenHelm, raiseSails); - cNavigateToShipwreckOnShip.addStep(notAtShipwreck, takeHelm); - - ConditionalStep cNavigateToShipwreck = new ConditionalStep(this, boardWAShip); - cNavigateToShipwreck.addStep(and(new VarbitRequirement(VarbitID.CUTSCENE_STATUS, 1), canSalvage), watchSalvageCutscene); - cNavigateToShipwreck.addStep(onboardShip, cNavigateToShipwreckOnShip); - steps.put(8, cNavigateToShipwreck); - steps.put(10, cNavigateToShipwreck); - steps.put(12, cNavigateToShipwreck); - steps.put(14, cNavigateToShipwreck); - - ConditionalStep cLearnWhereYouAre = new ConditionalStep(this, getToPandemonium); - cLearnWhereYouAre.addStep(onPandemonium, learnWhereYouAre); - steps.put(16, cLearnWhereYouAre); - ConditionalStep cLearnWhoWAare = new ConditionalStep(this, getToPandemonium); - cLearnWhoWAare.addStep(onPandemonium, learnWhoWAare); - steps.put(18, cLearnWhoWAare); - ConditionalStep cTalkToRibs = new ConditionalStep(this, getToPandemonium); - cTalkToRibs.addStep(onPandemonium, talkToRibs); - steps.put(20, cTalkToRibs); - ConditionalStep cFindLocationWA = new ConditionalStep(this, getToPandemonium); - cFindLocationWA.addStep(onPandemonium, findLocationWA); - steps.put(22, cFindLocationWA); - ConditionalStep cInformAboutShip = new ConditionalStep(this, getToPandemonium); - cInformAboutShip.addStep(onPandemonium, informAboutShip); - steps.put(24, cInformAboutShip); - ConditionalStep cShowCup = new ConditionalStep(this, getToPandemonium); - cShowCup.addStep(onPandemonium, showCup); - steps.put(26, cShowCup); - - ConditionalStep cBuildCargoHold = new ConditionalStep(this, getToPandemonium); - cBuildCargoHold.addStep(and(atShipyard, onboardShip), buildCargoHold); - cBuildCargoHold.addStep(and(atShipyard, hammerAndSaw), embarkShipSY); - cBuildCargoHold.addStep(and(atShipyard, saw), getHammer); - cBuildCargoHold.addStep(atShipyard, getSaw); - cBuildCargoHold.addStep(onPandemonium, enterShipyard); - steps.put(28, cBuildCargoHold); - - - ConditionalStep cGetLogBook = new ConditionalStep(this, getToPandemonium); - cGetLogBook.addStep(onPandemonium, getLogBook); - cGetLogBook.addStep(atShipyard, leaveShipyard); - steps.put(30, cGetLogBook); // Jim - - steps.put(32, getNewJob); // Jim - steps.put(34, boardShip); - ConditionalStep cSailToPortSarim = new ConditionalStep(this, boardShip); - cSailToPortSarim.addStep(and(not(atPortSarimDock), sailing), sailToPortSarim); - cSailToPortSarim.addStep(and(not(atPortSarimDock), takenHelm), raiseSails2); - cSailToPortSarim.addStep(and(not(atPortSarimDock), onboardShip), takeHelm2); - steps.put(36, cSailToPortSarim); - ConditionalStep cCheckPortMaster = new ConditionalStep(this, cSailToPortSarim); - cCheckPortMaster.addStep(and(boatAtPortSarim, holdingCargo, not(onboardShip)), boardShip2); - cCheckPortMaster.addStep(and(boatAtPortSarim, cargoNotPickedUp, not(onboardShip)), pickupCargo); - cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, takenHelm), letGoOfHelm); - cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, onboardShip), disembarkShipPS); - steps.put(38, cCheckPortMaster); - ConditionalStep cSailToPandemonium = new ConditionalStep(this, cCheckPortMaster); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm, sailing), sailToPandemonium); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm), raiseSails3); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip), takeHelm3); - cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoPickedUp, holdingCargo, onboardShip), dropCargoInCargoHold); - - ConditionalStep cDeliverCargo = new ConditionalStep(this, cSailToPandemonium); - cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), holdingCargo), deliverCargo); - cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, holdingCargo), disembarkShipP); - cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, nor(takenHelm, setSails), cargoInCargoHold), pickupCargoShip); - cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), cargoInCargoHold), boardShip3); - cDeliverCargo.addStep(and(atPandemoniumDock, cargoInCargoHold, takenHelm), letGoOfHelm2); - steps.put(40, cDeliverCargo); - steps.put(42, cDeliverCargo); - steps.put(44, talkToJim); - steps.put(46, meetGrog); - steps.put(48, finishQuest); - - return steps; - } - - public void setupConditions() - { - onboardShip = new VarbitRequirement(VarbitID.SAILING_BOARDED_BOAT, 1); - takenHelm = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_HELM_STATUS, 2); - setSails = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_BOAT_MOVE_MODE, 0, Operation.GREATER); - canSalvage = and(atShipwreck, new VarbitRequirement(VarbitID.SAILING_INTRO, 14, Operation.GREATER_EQUAL)); // At wreck, with explanation about salvaging - sailing = and(takenHelm, setSails, onboardShip); - - atShipyard = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_SHIPYARD_MODE, 1); - holdingCargo = new VarbitRequirement(VarbitID.SAILING_CARRYING_CARGO, 1); - - cargoPickedUp = new VarbitRequirement(VarbitID.PORT_TASK_SLOT_0_CARGO_TAKEN, 1); - cargoNotPickedUp = not(cargoPickedUp); - cargoInCargoHold = and(cargoPickedUp, not(holdingCargo)); - - nothingInHands = new NoItemRequirement("Nothing equipped in your hands.",ItemSlots.WEAPON, ItemSlots.SHIELD); - } + // Steps + NpcStep getToPandemonium; + NpcStep talkToWill; + NpcStep boardWAShip; + NpcStep explainJob; + NpcStep explainJob2; + NpcStep learnWhereYouAre; + NpcStep learnWhoWAare; + NpcStep talkToRibs; + NpcStep findLocationWA; + NpcStep enterShipyard; + NpcStep informAboutShip; + NpcStep showCup; + NpcStep getLogBook; + NpcStep getNewJob; + NpcStep talkToJim; + NpcStep meetGrog; + NpcStep finishQuest; + ObjectStep buildCargoHold; + ObjectStep embarkShipSY; + ObjectStep disembarkShipSY; + ObjectStep leaveShipyard; + ObjectStep dropCargoInCargoHold; + ObjectStep disembarkShipPS; + ObjectStep deliverCargo; + ObjectStep disembarkShipP; + ObjectStep getHammer; + ObjectStep getSaw; + DetailedQuestStep navigateShip; + DetailedQuestStep watchSalvageCutscene; + DetailedQuestStep takeHelm; + DetailedQuestStep takeHelm2; + DetailedQuestStep takeHelm3; + DetailedQuestStep raiseSails; + DetailedQuestStep raiseSails2; + DetailedQuestStep raiseSails3; + DetailedQuestStep salvageShipwreck; + DetailedQuestStep sailToPortSarim; + DetailedQuestStep pickupCargo; + DetailedQuestStep pickupCargoShip; + DetailedQuestStep sailToPandemonium; + DetailedQuestStep letGoOfHelm; + DetailedQuestStep letGoOfHelm2; + BoardShipStep boardShip; + BoardShipStep boardShip2; + BoardShipStep boardShip3; @Override protected void setupZones() @@ -187,12 +153,6 @@ protected void setupZones() portSarim = new Zone(new WorldPoint(3027, 3192, 0), new WorldPoint(3050, 3204, 0)); pandemoniumDockZone = new Zone(new WorldPoint(3065, 2974, 0), new WorldPoint(3084, 2998, 0)); portSarimDockZone = new Zone(new WorldPoint(3045, 3183, 0), new WorldPoint(3061, 3208, 0)); - atShipwreck = new VarbitRequirement(VarbitID.SAILING_INTRO_REACHED_WRECK, 1); - notAtShipwreck = not(atShipwreck); - onPandemonium = new ZoneRequirement(pandemonium); - boatAtPortSarim = new ShipInPortRequirement(Port.PORT_SARIM); - atPandemoniumDock = new ZoneRequirement(pandemoniumDockZone); - atPortSarimDock = new ZoneRequirement(portSarimDockZone); } @Override @@ -202,11 +162,32 @@ protected void setupRequirements() hammer.setTooltip("You can pick this up at the shipyard."); saw = new ItemRequirement("Saw", ItemCollections.SAW).isNotConsumed().canBeObtainedDuringQuest(); saw.setTooltip("You can pick this up at the shipyard."); - hammerAndSaw = and(hammer, saw); // Quest items cup = new ItemRequirement("Old cup", ItemID.SAILING_INTRO_CUP); cup.setTooltip("You can get another from Steve Beanie behind the bar on Pandemonium"); + + atShipwreck = new VarbitRequirement(VarbitID.SAILING_INTRO_REACHED_WRECK, 1); + onPandemonium = new ZoneRequirement(pandemonium); + boatAtPortSarim = new ShipInPortRequirement(Port.PORT_SARIM); + atPandemoniumDock = new ZoneRequirement(pandemoniumDockZone); + atPortSarimDock = new ZoneRequirement(portSarimDockZone); + + // Miscellaneous requirements + onboardShip = new VarbitRequirement(VarbitID.SAILING_BOARDED_BOAT, 1); + takenHelm = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_HELM_STATUS, 2); + setSails = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_BOAT_MOVE_MODE, 0, Operation.GREATER); + canSalvage = and(atShipwreck, new VarbitRequirement(VarbitID.SAILING_INTRO, 14, Operation.GREATER_EQUAL)); // At wreck, with explanation about salvaging + sailing = and(takenHelm, setSails, onboardShip); + + atShipyard = new VarbitRequirement(VarbitID.SAILING_SIDEPANEL_SHIPYARD_MODE, 1); + holdingCargo = new VarbitRequirement(VarbitID.SAILING_CARRYING_CARGO, 1); + + cargoPickedUp = new VarbitRequirement(VarbitID.PORT_TASK_SLOT_0_CARGO_TAKEN, 1); + cargoNotPickedUp = not(cargoPickedUp); + cargoInCargoHold = and(cargoPickedUp, not(holdingCargo)); + + nothingInHands = new NoItemRequirement("Nothing equipped in your hands.", ItemSlots.EMPTY_HANDS); } public void setupSteps() @@ -248,7 +229,7 @@ public void setupSteps() // Your mighty vessel enterShipyard = new NpcStep(this, NpcID.JUNIOR_JIM, new WorldPoint(3059, 2979, 0), "Talk to Junior Jim to enter the shipyard."); getHammer = new ObjectStep(this, ObjectID.CRATE_HAMMERS, "Pick up a hammer from the crate of hammers."); - getSaw = new ObjectStep(this, ObjectID.CRATE_SAWS, "Pick up a from the crate of saws."); + getSaw = new ObjectStep(this, ObjectID.CRATE_SAWS, "Pick up a saw from the crate of saws."); embarkShipSY = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_PROXY_WIDE, "Board your vessel."); buildCargoHold = new ObjectStep(this, ObjectID.SAILING_BOAT_FACILITY_PLACEHOLDER_RAFT_0, "Build the Cargo Hold."); disembarkShipSY = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_SHIPYARD_DISEMBARK, "Disembark your vessel."); @@ -264,7 +245,7 @@ public void setupSteps() sailToPortSarim = new SailStep(this, Port.PORT_SARIM); letGoOfHelm = new ObjectStep(this, ObjectID.SAILING_BOAT_STEERING_KANDARIN_1X3_WOOD_IN_USE, new WorldPoint(3843, 6460, 1), "Let go of the helm."); disembarkShipPS = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(3051, 3193, 0), "Leave your ship."); - + pickupCargo = new ObjectStep(this, ObjectID.DOCK_LOADING_BAY_LEDGER_TABLE_WITHDRAW, new WorldPoint(3028, 3194, 0), "Pick up the cargo from the ledger table on the docks.", nothingInHands); boardShip2 = new BoardShipStep(this); dropCargoInCargoHold = new ObjectStep(this, ObjectID.SAILING_BOAT_CARGO_HOLD_REGULAR_RAFT, "Deposit the crate into your cargo hold."); @@ -274,7 +255,11 @@ public void setupSteps() sailToPandemonium = new SailStep(this, Port.PANDEMONIUM); letGoOfHelm2 = new ObjectStep(this, ObjectID.SAILING_BOAT_STEERING_KANDARIN_1X3_WOOD_IN_USE, new WorldPoint(3843, 6460, 1), "Let go of the helm."); pickupCargoShip = new ObjectStep(this, ObjectID.SAILING_BOAT_CARGO_HOLD_REGULAR_RAFT, "Pick up the cargo from your ship's cargo hold.", nothingInHands); + + // In case the user boards the Pandemonium without picking up the cargo from their ship boardShip3 = new BoardShipStep(this); + pickupCargoShip.addSubSteps(boardShip3); + disembarkShipP = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(3070, 2987, 0), "Leave your ship."); deliverCargo = new ObjectStep(this, ObjectID.DOCK_LOADING_BAY_LEDGER_TABLE_DEPOSIT, new WorldPoint(3061, 2985, 0), "Deliver the cargo at the ledger table on the docks."); //Finish up @@ -284,15 +269,119 @@ public void setupSteps() } @Override - public QuestPointReward getQuestPointReward() + public Map loadSteps() { - return new QuestPointReward(1); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToWill); + steps.put(2, talkToWill); + + steps.put(4, boardWAShip); + + var goListenOnShip = new ConditionalStep(this, talkToWill); + goListenOnShip.addStep(onboardShip, explainJob); + steps.put(6, goListenOnShip); + + var cNavigateToShipwreckOnShip = new ConditionalStep(this, takeHelm); + cNavigateToShipwreckOnShip.addStep(canSalvage, salvageShipwreck); + cNavigateToShipwreckOnShip.addStep(atShipwreck, explainJob2); + cNavigateToShipwreckOnShip.addStep(sailing, navigateShip); + cNavigateToShipwreckOnShip.addStep(takenHelm, raiseSails); + cNavigateToShipwreckOnShip.addStep(not(atShipwreck), takeHelm); + + var cNavigateToShipwreck = new ConditionalStep(this, boardWAShip); + cNavigateToShipwreck.addStep(and(new VarbitRequirement(VarbitID.CUTSCENE_STATUS, 1), canSalvage), watchSalvageCutscene); + cNavigateToShipwreck.addStep(onboardShip, cNavigateToShipwreckOnShip); + steps.put(8, cNavigateToShipwreck); + steps.put(10, cNavigateToShipwreck); + steps.put(12, cNavigateToShipwreck); + steps.put(14, cNavigateToShipwreck); + + var cLearnWhereYouAre = new ConditionalStep(this, getToPandemonium); + cLearnWhereYouAre.addStep(onPandemonium, learnWhereYouAre); + steps.put(16, cLearnWhereYouAre); + var cLearnWhoWAare = new ConditionalStep(this, getToPandemonium); + cLearnWhoWAare.addStep(onPandemonium, learnWhoWAare); + steps.put(18, cLearnWhoWAare); + var cTalkToRibs = new ConditionalStep(this, getToPandemonium); + cTalkToRibs.addStep(onPandemonium, talkToRibs); + steps.put(20, cTalkToRibs); + var cFindLocationWA = new ConditionalStep(this, getToPandemonium); + cFindLocationWA.addStep(onPandemonium, findLocationWA); + steps.put(22, cFindLocationWA); + var cInformAboutShip = new ConditionalStep(this, getToPandemonium); + cInformAboutShip.addStep(onPandemonium, informAboutShip); + steps.put(24, cInformAboutShip); + var cShowCup = new ConditionalStep(this, getToPandemonium); + cShowCup.addStep(onPandemonium, showCup); + steps.put(26, cShowCup); + + var cBuildCargoHold = new ConditionalStep(this, getToPandemonium); + cBuildCargoHold.addStep(and(atShipyard, onboardShip), buildCargoHold); + cBuildCargoHold.addStep(and(atShipyard, hammer, saw), embarkShipSY); + cBuildCargoHold.addStep(and(atShipyard, saw), getHammer); + cBuildCargoHold.addStep(atShipyard, getSaw); + cBuildCargoHold.addStep(onPandemonium, enterShipyard); + steps.put(28, cBuildCargoHold); + + + var cGetLogBook = new ConditionalStep(this, getToPandemonium); + cGetLogBook.addStep(onPandemonium, getLogBook); + cGetLogBook.addStep(atShipyard, leaveShipyard); + steps.put(30, cGetLogBook); // Jim + + steps.put(32, getNewJob); // Jim + steps.put(34, boardShip); + var cSailToPortSarim = new ConditionalStep(this, boardShip); + cSailToPortSarim.addStep(and(atPortSarimDock, cargoNotPickedUp, takenHelm), letGoOfHelm); + cSailToPortSarim.addStep(and(atPortSarimDock, cargoNotPickedUp, onboardShip), disembarkShipPS); + cSailToPortSarim.addStep(and(not(atPortSarimDock), sailing), sailToPortSarim); + cSailToPortSarim.addStep(and(not(atPortSarimDock), takenHelm), raiseSails2); + cSailToPortSarim.addStep(and(not(atPortSarimDock), onboardShip), takeHelm2); + steps.put(36, cSailToPortSarim); + var cCheckPortMaster = new ConditionalStep(this, cSailToPortSarim); + cCheckPortMaster.addStep(and(boatAtPortSarim, holdingCargo, not(onboardShip)), boardShip2); + cCheckPortMaster.addStep(and(boatAtPortSarim, cargoNotPickedUp, not(onboardShip)), pickupCargo); + cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, takenHelm), letGoOfHelm); + cCheckPortMaster.addStep(and(atPortSarimDock, cargoNotPickedUp, onboardShip), disembarkShipPS); + steps.put(38, cCheckPortMaster); + var cSailToPandemonium = new ConditionalStep(this, cCheckPortMaster); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm, sailing), sailToPandemonium); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip, takenHelm), raiseSails3); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoInCargoHold, onboardShip), takeHelm3); + cSailToPandemonium.addStep(and(not(atPandemoniumDock), cargoPickedUp, holdingCargo, onboardShip), dropCargoInCargoHold); + + var cDeliverCargo = new ConditionalStep(this, cSailToPandemonium); + cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), holdingCargo), deliverCargo); + cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, holdingCargo), disembarkShipP); + cDeliverCargo.addStep(and(atPandemoniumDock, onboardShip, nor(takenHelm, setSails), cargoInCargoHold), pickupCargoShip); + cDeliverCargo.addStep(and(onPandemonium, not(onboardShip), cargoInCargoHold), boardShip3); + cDeliverCargo.addStep(and(atPandemoniumDock, cargoInCargoHold, takenHelm), letGoOfHelm2); + steps.put(40, cDeliverCargo); + steps.put(42, cDeliverCargo); + steps.put(44, talkToJim); + steps.put(46, meetGrog); + steps.put(48, finishQuest); + + return steps; } @Override public List getItemRequirements() { - return Arrays.asList(hammer, saw); + return List.of( + hammer, + saw + ); + } + + @Override + public QuestPointReward getQuestPointReward() + { + return new QuestPointReward(1); } @Override @@ -304,29 +393,93 @@ public List getExperienceRewards() @Override public List getItemRewards() { - return Arrays.asList( + return List.of( new ItemReward("Sawmill Coupon (wood plank)", ItemID.SAWMILL_COUPON, 25), new ItemReward("Repair kits", ItemID.BOAT_REPAIR_KIT, 2), - new ItemReward("Spyglass", ItemID.SAILING_CHARTING_SPYGLASS, 1)); + new ItemReward("Spyglass", ItemID.SAILING_CHARTING_SPYGLASS, 1) + ); } @Override public List getUnlockRewards() { - return Arrays.asList(new UnlockReward("Access to the Sailing Skill"), new UnlockReward("Access to Pandemonium"), new UnlockReward("Your very own mighty ship!")); + return List.of( + new UnlockReward("Access to the Sailing Skill"), + new UnlockReward("Access to Pandemonium"), + new UnlockReward("Your very own mighty ship!") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("You got the job!", Arrays.asList(talkToWill, boardWAShip))); - allSteps.add(new PanelDetails("What's the job?", Arrays.asList(explainJob, takeHelm, raiseSails, navigateShip, explainJob2, salvageShipwreck, watchSalvageCutscene))); - allSteps.add(new PanelDetails("You lost the job!", Arrays.asList(getToPandemonium, learnWhereYouAre, learnWhoWAare, talkToRibs, findLocationWA, informAboutShip, showCup))); - allSteps.add(new PanelDetails("Your mighty vessel", Arrays.asList(enterShipyard, getSaw, getHammer, embarkShipSY, buildCargoHold, disembarkShipSY, leaveShipyard, getLogBook))); - allSteps.add(new PanelDetails("You got the job... again!", Arrays.asList(getNewJob, boardShip, takeHelm2, raiseSails2, sailToPortSarim, letGoOfHelm, disembarkShipPS, pickupCargo, boardShip2))); - allSteps.add(new PanelDetails("Deliver the cargo.", Arrays.asList(dropCargoInCargoHold, takeHelm3, raiseSails3, sailToPandemonium, letGoOfHelm2, pickupCargoShip, disembarkShipP, deliverCargo))); - allSteps.add(new PanelDetails("Finishing up", Arrays.asList(talkToJim, meetGrog, finishQuest))); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("You got the job!", List.of( + talkToWill, + boardWAShip + ))); + + sections.add(new PanelDetails("What's the job?", List.of( + explainJob, + takeHelm, + raiseSails, + navigateShip, + explainJob2, + salvageShipwreck, + watchSalvageCutscene + ))); + + sections.add(new PanelDetails("You lost the job!", List.of( + getToPandemonium, + learnWhereYouAre, + learnWhoWAare, + talkToRibs, + findLocationWA, + informAboutShip, + showCup + ))); + + sections.add(new PanelDetails("Your mighty vessel", List.of( + enterShipyard, + getSaw, + getHammer, + embarkShipSY, + buildCargoHold, + disembarkShipSY, + leaveShipyard, + getLogBook + ))); + + sections.add(new PanelDetails("You got the job... again!", List.of( + getNewJob, + boardShip, + takeHelm2, + raiseSails2, + sailToPortSarim, + letGoOfHelm, + disembarkShipPS, + pickupCargo, + boardShip2 + ))); + + sections.add(new PanelDetails("Deliver the cargo.", List.of( + dropCargoInCargoHold, + takeHelm3, + raiseSails3, + sailToPandemonium, + letGoOfHelm2, + pickupCargoShip, + disembarkShipP, + deliverCargo + ))); + + sections.add(new PanelDetails("Finishing up", List.of( + talkToJim, + meetGrog, + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java index 0766746b7b..c3c4b80bb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/PiratesTreasure.java @@ -33,16 +33,20 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DigStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; public class PiratesTreasure extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java index 805f3e4c30..8075c234ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/piratestreasure/RumSmugglingStep.java @@ -32,22 +32,24 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.List; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.List; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class RumSmugglingStep extends ConditionalStep { private final PiratesTreasure pt; @@ -171,7 +173,7 @@ private void setupRequirements() private void setupSteps() { goToKaramja = new NpcStep(getQuestHelper(), NpcID.SEAMAN_LORRIS, new WorldPoint(3027, 3222, 0), - "Talk to one of the Seamen on the docks in Port Sarim to go to Karamja.", new ItemRequirement("Coins", ItemCollections.COINS, 60)); + "Talk to one of the Seamen on the docks in Port Sarim to go to Musa Point.", new ItemRequirement("Coins", ItemCollections.COINS, 60)); goToKaramja.addDialogStep("Yes please."); talkToZambo = new NpcStep(getQuestHelper(), NpcID.ZEMBO, new WorldPoint(2929, 3145, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java index f2e6906212..ea5c10ad94 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/plaguecity/PlagueCity.java @@ -28,13 +28,22 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -42,13 +51,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class PlagueCity extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java index 9bbc283069..c739999b53 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/priestinperil/PriestInPeril.java @@ -27,10 +27,11 @@ import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -38,150 +39,104 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class PriestInPeril extends BasicQuestHelper { - //Items Required - ItemRequirement runeEssence, lotsOfRuneEssence, bucket, weaponAndArmour, goldenKey, rangedMagedGear, - murkyWater, ironKey, blessedWaterHighlighted, bucketHighlighted, goldenKeyHighlighted; - - //Items Recommended - ItemRequirement runePouches, varrockTeleport; - - Requirement inUnderground, hasGoldenOrIronKey, inTempleGroundFloor, inTemple, inTempleFirstFloor, inTempleSecondFloor; - - QuestStep talkToRoald, goToTemple, goDownToDog, killTheDog, climbUpAfterKillingDog, returnToKingRoald, returnToTemple, killMonk, talkToDrezel, - goUpToFloorTwoTemple, goUpToFloorOneTemple, goDownToFloorOneTemple, goDownToGroundFloorTemple, enterUnderground, fillBucket, useKeyForKey, - openDoor, useBlessedWater, blessWater, goUpWithWaterToSurface, goUpWithWaterToFirstFloor, goUpWithWaterToSecondFloor, talkToDrezelAfterFreeing, - goDownToFloorOneAfterFreeing, goDownToGroundFloorAfterFreeing, enterUndergroundAfterFreeing, talkToDrezelUnderground, bringDrezelEssence; + // Required items + ItemRequirement runeEssence; + ItemRequirement bucket; + + // Recommended items + ItemRequirement varrockTeleport; + ItemRequirement runePouches; + + // Mid-quest requirements + ItemRequirement lotsOfRuneEssence; + ItemRequirement weaponAndArmour; + ItemRequirement goldenKey; + ItemRequirement rangedMagedGear; + ItemRequirement murkyWater; + ItemRequirement ironKey; + ItemRequirement blessedWaterHighlighted; + ItemRequirement bucketHighlighted; + ItemRequirement goldenKeyHighlighted; + + // Zones + Zone underground; + Zone temple1; + Zone temple2; + Zone temple3; + Zone temple4; + Zone temple5; + Zone temple6; + Zone templeFloorOne; + Zone templeFloorTwo; + + // Miscellaneous requirements + ZoneRequirement inUnderground; + ZoneRequirement inTempleGroundFloor; + ZoneRequirement inTemple; + ZoneRequirement inTempleFirstFloor; + ZoneRequirement inTempleSecondFloor; + Conditions hasGoldenOrIronKey; + + // Steps + NpcStep talkToRoald; + ObjectStep goToTemple; + ObjectStep goDownToDog; + NpcStep killTheDog; + ObjectStep climbUpAfterKillingDog; + NpcStep returnToKingRoald; + ObjectStep returnToTemple; + NpcStep killMonk; + NpcStep talkToDrezel; + ObjectStep goUpToFloorTwoTemple; + ObjectStep goUpToFloorOneTemple; + ObjectStep goDownToFloorOneTemple; + ObjectStep goDownToGroundFloorTemple; + ObjectStep enterUnderground; + ObjectStep fillBucket; + DetailedQuestStep useKeyForKey; + ObjectStep openDoor; + ObjectStep useBlessedWater; + NpcStep blessWater; + ObjectStep goUpWithWaterToSurface; + ObjectStep goUpWithWaterToFirstFloor; + ObjectStep goUpWithWaterToSecondFloor; + NpcStep talkToDrezelAfterFreeing; + ObjectStep goDownToFloorOneAfterFreeing; + ObjectStep goDownToGroundFloorAfterFreeing; + ObjectStep enterUndergroundAfterFreeing; + NpcStep talkToDrezelUnderground; + NpcStep bringDrezelEssence; - //Zones - Zone underground, temple1, temple2, temple3, temple4, temple5, temple6, templeFloorOne, templeFloorTwo; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToRoald); - steps.put(1, goToTemple); - - ConditionalStep goDownAndKillDog = new ConditionalStep(this, goDownToDog); - goDownAndKillDog.addStep(inUnderground, killTheDog); - - steps.put(2, goDownAndKillDog); - - ConditionalStep reportKillingDog = new ConditionalStep(this, returnToKingRoald); - reportKillingDog.addStep(inUnderground, climbUpAfterKillingDog); - steps.put(3, reportKillingDog); - - ConditionalStep goTalkToDrezel = new ConditionalStep(this, returnToTemple); - goTalkToDrezel.addStep(new Conditions(hasGoldenOrIronKey, inTempleSecondFloor), talkToDrezel); - goTalkToDrezel.addStep(new Conditions(hasGoldenOrIronKey, inTempleFirstFloor), goUpToFloorTwoTemple); - goTalkToDrezel.addStep(new Conditions(hasGoldenOrIronKey, inTempleGroundFloor), goUpToFloorOneTemple); - goTalkToDrezel.addStep(inTemple, killMonk); - steps.put(4, goTalkToDrezel); - - ConditionalStep goGetKey = new ConditionalStep(this, returnToTemple); - goGetKey.addStep(new Conditions(ironKey, murkyWater, inTempleSecondFloor), openDoor); - goGetKey.addStep(new Conditions(ironKey, murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); - goGetKey.addStep(new Conditions(ironKey, murkyWater, inUnderground), goUpWithWaterToSurface); - goGetKey.addStep(new Conditions(ironKey, murkyWater), goUpWithWaterToFirstFloor); - goGetKey.addStep(new Conditions(ironKey, inUnderground), fillBucket); - goGetKey.addStep(new Conditions(hasGoldenOrIronKey, inUnderground), useKeyForKey); - goGetKey.addStep(new Conditions(hasGoldenOrIronKey, inTempleSecondFloor), goDownToFloorOneTemple); - goGetKey.addStep(new Conditions(hasGoldenOrIronKey, inTempleFirstFloor), goDownToGroundFloorTemple); - goGetKey.addStep(hasGoldenOrIronKey, enterUnderground); - goGetKey.addStep(inTemple, killMonk); - steps.put(5, goGetKey); - - ConditionalStep goGetWater = new ConditionalStep(this, enterUnderground); - goGetWater.addStep(new Conditions(blessedWaterHighlighted, inTempleSecondFloor), useBlessedWater); - goGetWater.addStep(new Conditions(murkyWater, inTempleSecondFloor), blessWater); - goGetWater.addStep(new Conditions(murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); - goGetWater.addStep(new Conditions(murkyWater, inUnderground), goUpWithWaterToSurface); - goGetWater.addStep(murkyWater, goUpWithWaterToFirstFloor); - goGetWater.addStep(inUnderground, fillBucket); - goGetWater.addStep(inTempleSecondFloor, goDownToFloorOneTemple); - goGetWater.addStep(inTempleFirstFloor, goDownToGroundFloorTemple); - steps.put(6, goGetWater); - - ConditionalStep goTalkToDrezelAfterFreeing = new ConditionalStep(this, goUpWithWaterToFirstFloor); - goTalkToDrezelAfterFreeing.addStep(inTempleSecondFloor, talkToDrezelAfterFreeing); - goTalkToDrezelAfterFreeing.addStep(inTempleFirstFloor, goUpWithWaterToSecondFloor); - steps.put(7, goTalkToDrezelAfterFreeing); - - ConditionalStep goDownToDrezel = new ConditionalStep(this, enterUndergroundAfterFreeing); - goDownToDrezel.addStep(inUnderground, talkToDrezelUnderground); - goDownToDrezel.addStep(inTempleFirstFloor, goDownToGroundFloorAfterFreeing); - goDownToDrezel.addStep(inTempleSecondFloor, goDownToFloorOneAfterFreeing); - steps.put(8, goDownToDrezel); - steps.put(9, goDownToDrezel); - - steps.put(10, bringDrezelEssence); - steps.put(11, bringDrezelEssence); - steps.put(12, bringDrezelEssence); - steps.put(13, bringDrezelEssence); - steps.put(14, bringDrezelEssence); - steps.put(15, bringDrezelEssence); - steps.put(16, bringDrezelEssence); - steps.put(17, bringDrezelEssence); - steps.put(18, bringDrezelEssence); - steps.put(19, bringDrezelEssence); - steps.put(20, bringDrezelEssence); - steps.put(21, bringDrezelEssence); - steps.put(22, bringDrezelEssence); - steps.put(23, bringDrezelEssence); - steps.put(24, bringDrezelEssence); - steps.put(25, bringDrezelEssence); - steps.put(26, bringDrezelEssence); - steps.put(27, bringDrezelEssence); - steps.put(28, bringDrezelEssence); - steps.put(29, bringDrezelEssence); - steps.put(30, bringDrezelEssence); - steps.put(31, bringDrezelEssence); - steps.put(32, bringDrezelEssence); - steps.put(33, bringDrezelEssence); - steps.put(34, bringDrezelEssence); - steps.put(35, bringDrezelEssence); - steps.put(36, bringDrezelEssence); - steps.put(37, bringDrezelEssence); - steps.put(38, bringDrezelEssence); - steps.put(39, bringDrezelEssence); - steps.put(40, bringDrezelEssence); - steps.put(41, bringDrezelEssence); - steps.put(42, bringDrezelEssence); - steps.put(43, bringDrezelEssence); - steps.put(44, bringDrezelEssence); - steps.put(45, bringDrezelEssence); - steps.put(46, bringDrezelEssence); - steps.put(47, bringDrezelEssence); - steps.put(48, bringDrezelEssence); - steps.put(49, bringDrezelEssence); - steps.put(50, bringDrezelEssence); - steps.put(51, bringDrezelEssence); - steps.put(52, bringDrezelEssence); - steps.put(53, bringDrezelEssence); - steps.put(54, bringDrezelEssence); - steps.put(55, bringDrezelEssence); - steps.put(56, bringDrezelEssence); - steps.put(57, bringDrezelEssence); - steps.put(58, bringDrezelEssence); - steps.put(59, bringDrezelEssence); - // There is a 60th step before the final 61, but the 'Quest Completed!' message pops up prior to it - - return steps; + underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); + temple1 = new Zone(new WorldPoint(3409, 3483, 0), new WorldPoint(3411, 3494, 0)); + temple2 = new Zone(new WorldPoint(3408, 3485, 0), new WorldPoint(3408, 3486, 0)); + temple3 = new Zone(new WorldPoint(3408, 3491, 0), new WorldPoint(3408, 3492, 0)); + temple4 = new Zone(new WorldPoint(3412, 3484, 0), new WorldPoint(3415, 3493, 0)); + temple5 = new Zone(new WorldPoint(3416, 3483, 0), new WorldPoint(3417, 3494, 0)); + temple6 = new Zone(new WorldPoint(3418, 3484, 0), new WorldPoint(3418, 3493, 0)); + templeFloorOne = new Zone(new WorldPoint(3408, 3483, 1), new WorldPoint(3419, 3494, 1)); + templeFloorTwo = new Zone(new WorldPoint(3408, 3483, 2), new WorldPoint(3419, 3494, 2)); } @Override @@ -211,36 +166,20 @@ protected void setupRequirements() ironKey = new ItemRequirement("Iron key", ItemID.PIPKEY_IRON); blessedWaterHighlighted = new ItemRequirement("Blessed water", ItemID.BUCKET_BLESSEDWATER); blessedWaterHighlighted.setHighlightInInventory(true); - } - - @Override - protected void setupZones() - { - underground = new Zone(new WorldPoint(3402, 9880, 0), new WorldPoint(3443, 9907, 0)); - temple1 = new Zone(new WorldPoint(3409, 3483, 0), new WorldPoint(3411, 3494, 0)); - temple2 = new Zone(new WorldPoint(3408, 3485, 0), new WorldPoint(3408, 3486, 0)); - temple3 = new Zone(new WorldPoint(3408, 3491, 0), new WorldPoint(3408, 3492, 0)); - temple4 = new Zone(new WorldPoint(3412, 3484, 0), new WorldPoint(3415, 3493, 0)); - temple5 = new Zone(new WorldPoint(3416, 3483, 0), new WorldPoint(3417, 3494, 0)); - temple6 = new Zone(new WorldPoint(3418, 3484, 0), new WorldPoint(3418, 3493, 0)); - templeFloorOne = new Zone(new WorldPoint(3408, 3483, 1), new WorldPoint(3419, 3494, 1)); - templeFloorTwo = new Zone(new WorldPoint(3408, 3483, 2), new WorldPoint(3419, 3494, 2)); - } - public void setupConditions() - { inUnderground = new ZoneRequirement(underground); inTempleGroundFloor = new ZoneRequirement(temple1, temple2, temple3, temple4, temple5, temple6); inTempleFirstFloor = new ZoneRequirement(templeFloorOne); inTempleSecondFloor = new ZoneRequirement(templeFloorTwo); inTemple = new ZoneRequirement(temple1, temple2, temple3, temple4, temple5, temple6, templeFloorOne, templeFloorTwo); - hasGoldenOrIronKey = new Conditions(LogicType.OR, goldenKey, ironKey); + hasGoldenOrIronKey = or(goldenKey, ironKey); } + public void setupSteps() { - talkToRoald = new NpcStep(this, NpcID.KING_ROALD_CUTSCENE, new WorldPoint(3222, 3473, 0), "Speak to King Roald in Varrock Castle."); + talkToRoald = new NpcStep(this, NpcID.KING_ROALD, new WorldPoint(3222, 3473, 0), "Speak to King Roald in Varrock Castle."); talkToRoald.addDialogStep("I'm looking for a quest!"); talkToRoald.addDialogStep("Yes."); goToTemple = new ObjectStep(this, ObjectID.PRIESTPERILTEMPLEDOORR, new WorldPoint(3408, 3488, 0), @@ -248,13 +187,15 @@ public void setupSteps() goToTemple.addDialogSteps("I'll get going.", "Roald sent me to check on Drezel.", "Sure. I'm a helpful person!"); goDownToDog = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Go down the ladder north of the temple."); goDownToDog.addDialogStep("Yes."); - ((ObjectStep) (goDownToDog)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + goDownToDog.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); killTheDog = new NpcStep(this, NpcID.PRIESTPERIL_GUARDIAN_MODEL, new WorldPoint(3405, 9901, 0), "Kill the Temple Guardian (level 30). It is immune to magic so you will need to use either ranged or melee."); + killTheDog.addSubSteps(goDownToDog); climbUpAfterKillingDog = new ObjectStep(this, ObjectID.LADDER_FROM_CELLAR, new WorldPoint(3405, 9907, 0), "Climb back up the ladder and return to King Roald."); - returnToKingRoald = new NpcStep(this, NpcID.KING_ROALD_CUTSCENE, new WorldPoint(3222, 3473, 0), + returnToKingRoald = new NpcStep(this, NpcID.KING_ROALD, new WorldPoint(3222, 3473, 0), "Return to King Roald."); + returnToKingRoald.addDialogStep("About that job I'm doing..."); returnToKingRoald.addSubSteps(climbUpAfterKillingDog); returnToTemple = new ObjectStep(this, ObjectID.PRIESTPERILTEMPLEDOORR, new WorldPoint(3408, 3488, 0), @@ -270,13 +211,13 @@ public void setupSteps() fillBucket = new ObjectStep(this, ObjectID.PRIESTPERIL_WELL, new WorldPoint(3423, 9890, 0), "Use the bucket on the well in the central room.", bucketHighlighted); fillBucket.addIcon(ItemID.BUCKET_EMPTY); - useKeyForKey = new DetailedQuestStep(this, "Go to the central room, and study the monuments to find which has a key on it. Use the Golden Key on it.", goldenKeyHighlighted); + useKeyForKey = new DetailedQuestStep(this, new WorldPoint(3421, 9888, 0), "Go to the central room, and study the monuments to find which has a key on it. Use the Golden Key on it.", goldenKeyHighlighted); goDownToFloorOneTemple = new ObjectStep(this, ObjectID.LADDERTOP, new WorldPoint(3410, 3485, 2), "Go down to the underground of the temple.", bucket); - goDownToGroundFloorTemple = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 0), "Go down to the underground of the temple.", bucket); + goDownToGroundFloorTemple = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 1), "Go down to the underground of the temple.", bucket); enterUnderground = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Go down to the underground of the temple.", bucket); enterUnderground.addSubSteps(goDownToFloorOneTemple, goDownToGroundFloorTemple); - ((ObjectStep) (enterUnderground)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + enterUnderground.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); goUpWithWaterToSurface = new ObjectStep(this, ObjectID.LADDER_FROM_CELLAR, new WorldPoint(3405, 9907, 0), "Go back up to the top floor of the temple."); @@ -294,9 +235,9 @@ public void setupSteps() talkToDrezelAfterFreeing = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3418, 3489, 2), "Talk to Drezel again."); goDownToFloorOneAfterFreeing = new ObjectStep(this, ObjectID.LADDERTOP, new WorldPoint(3410, 3485, 2), "Go down to the underground of the temple.", lotsOfRuneEssence); - goDownToGroundFloorAfterFreeing = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 0), "Go down to the underground of the temple.", lotsOfRuneEssence); + goDownToGroundFloorAfterFreeing = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP, new WorldPoint(3417, 3485, 1), "Go down to the underground of the temple.", lotsOfRuneEssence); enterUndergroundAfterFreeing = new ObjectStep(this, ObjectID.TRAPDOOR, new WorldPoint(3405, 3507, 0), "Go down to the underground of the temple.", lotsOfRuneEssence); - ((ObjectStep) (enterUndergroundAfterFreeing)).addAlternateObjects(ObjectID.TRAPDOOR_OPEN); + enterUndergroundAfterFreeing.addAlternateObjects(ObjectID.TRAPDOOR_OPEN); talkToDrezelUnderground = new NpcStep(this, NpcID.PRIESTPERILTRAPPEDMONK_VIS, new WorldPoint(3439, 9896, 0), "Talk to Drezel in the east of the underground temple area.", lotsOfRuneEssence); talkToDrezelUnderground.addSubSteps(goDownToFloorOneAfterFreeing, goDownToGroundFloorAfterFreeing, enterUndergroundAfterFreeing); @@ -304,28 +245,150 @@ public void setupSteps() } @Override - public List getItemRecommended() + public Map loadSteps() { - ArrayList reqs = new ArrayList<>(); - reqs.add(varrockTeleport); - reqs.add(runePouches); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToRoald); + steps.put(1, goToTemple); + + var goDownAndKillDog = new ConditionalStep(this, goDownToDog); + goDownAndKillDog.addStep(inUnderground, killTheDog); + + steps.put(2, goDownAndKillDog); - return reqs; + var reportKillingDog = new ConditionalStep(this, returnToKingRoald); + reportKillingDog.addStep(inUnderground, climbUpAfterKillingDog); + steps.put(3, reportKillingDog); + + var goTalkToDrezel = new ConditionalStep(this, returnToTemple); + goTalkToDrezel.addStep(and(hasGoldenOrIronKey, inTempleSecondFloor), talkToDrezel); + goTalkToDrezel.addStep(and(hasGoldenOrIronKey, inTempleFirstFloor), goUpToFloorTwoTemple); + goTalkToDrezel.addStep(and(hasGoldenOrIronKey, inTempleGroundFloor), goUpToFloorOneTemple); + goTalkToDrezel.addStep(inTemple, killMonk); + steps.put(4, goTalkToDrezel); + + var goGetKey = new ConditionalStep(this, returnToTemple); + goGetKey.addStep(and(ironKey, murkyWater, inTempleSecondFloor), openDoor); + goGetKey.addStep(and(ironKey, murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); + goGetKey.addStep(and(ironKey, murkyWater, inUnderground), goUpWithWaterToSurface); + goGetKey.addStep(and(ironKey, murkyWater), goUpWithWaterToFirstFloor); + goGetKey.addStep(and(ironKey, inUnderground), fillBucket); + goGetKey.addStep(and(hasGoldenOrIronKey, inUnderground), useKeyForKey); + goGetKey.addStep(and(hasGoldenOrIronKey, inTempleSecondFloor), goDownToFloorOneTemple); + goGetKey.addStep(and(hasGoldenOrIronKey, inTempleFirstFloor), goDownToGroundFloorTemple); + goGetKey.addStep(hasGoldenOrIronKey, enterUnderground); + goGetKey.addStep(inTemple, killMonk); + steps.put(5, goGetKey); + + var goGetWater = new ConditionalStep(this, enterUnderground); + goGetWater.addStep(and(blessedWaterHighlighted, inTempleSecondFloor), useBlessedWater); + goGetWater.addStep(and(murkyWater, inTempleSecondFloor), blessWater); + goGetWater.addStep(and(murkyWater, inTempleFirstFloor), goUpWithWaterToSecondFloor); + goGetWater.addStep(and(murkyWater, inUnderground), goUpWithWaterToSurface); + goGetWater.addStep(murkyWater, goUpWithWaterToFirstFloor); + goGetWater.addStep(inUnderground, fillBucket); + goGetWater.addStep(inTempleSecondFloor, goDownToFloorOneTemple); + goGetWater.addStep(inTempleFirstFloor, goDownToGroundFloorTemple); + steps.put(6, goGetWater); + + var goTalkToDrezelAfterFreeing = new ConditionalStep(this, goUpWithWaterToFirstFloor); + goTalkToDrezelAfterFreeing.addStep(inTempleSecondFloor, talkToDrezelAfterFreeing); + goTalkToDrezelAfterFreeing.addStep(inTempleFirstFloor, goUpWithWaterToSecondFloor); + steps.put(7, goTalkToDrezelAfterFreeing); + + var goDownToDrezel = new ConditionalStep(this, enterUndergroundAfterFreeing); + goDownToDrezel.addStep(inUnderground, talkToDrezelUnderground); + goDownToDrezel.addStep(inTempleFirstFloor, goDownToGroundFloorAfterFreeing); + goDownToDrezel.addStep(inTempleSecondFloor, goDownToFloorOneAfterFreeing); + steps.put(8, goDownToDrezel); + steps.put(9, goDownToDrezel); + + steps.put(10, bringDrezelEssence); + steps.put(11, bringDrezelEssence); + steps.put(12, bringDrezelEssence); + steps.put(13, bringDrezelEssence); + steps.put(14, bringDrezelEssence); + steps.put(15, bringDrezelEssence); + steps.put(16, bringDrezelEssence); + steps.put(17, bringDrezelEssence); + steps.put(18, bringDrezelEssence); + steps.put(19, bringDrezelEssence); + steps.put(20, bringDrezelEssence); + steps.put(21, bringDrezelEssence); + steps.put(22, bringDrezelEssence); + steps.put(23, bringDrezelEssence); + steps.put(24, bringDrezelEssence); + steps.put(25, bringDrezelEssence); + steps.put(26, bringDrezelEssence); + steps.put(27, bringDrezelEssence); + steps.put(28, bringDrezelEssence); + steps.put(29, bringDrezelEssence); + steps.put(30, bringDrezelEssence); + steps.put(31, bringDrezelEssence); + steps.put(32, bringDrezelEssence); + steps.put(33, bringDrezelEssence); + steps.put(34, bringDrezelEssence); + steps.put(35, bringDrezelEssence); + steps.put(36, bringDrezelEssence); + steps.put(37, bringDrezelEssence); + steps.put(38, bringDrezelEssence); + steps.put(39, bringDrezelEssence); + steps.put(40, bringDrezelEssence); + steps.put(41, bringDrezelEssence); + steps.put(42, bringDrezelEssence); + steps.put(43, bringDrezelEssence); + steps.put(44, bringDrezelEssence); + steps.put(45, bringDrezelEssence); + steps.put(46, bringDrezelEssence); + steps.put(47, bringDrezelEssence); + steps.put(48, bringDrezelEssence); + steps.put(49, bringDrezelEssence); + steps.put(50, bringDrezelEssence); + steps.put(51, bringDrezelEssence); + steps.put(52, bringDrezelEssence); + steps.put(53, bringDrezelEssence); + steps.put(54, bringDrezelEssence); + steps.put(55, bringDrezelEssence); + steps.put(56, bringDrezelEssence); + steps.put(57, bringDrezelEssence); + steps.put(58, bringDrezelEssence); + steps.put(59, bringDrezelEssence); + // There is a 60th step before the final 61, but the 'Quest Completed!' message pops up prior to it + + return steps; } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(runeEssence); - reqs.add(bucket); - return reqs; + return List.of( + runeEssence, + bucket + ); } + @Override + public List getItemRecommended() + { + return List.of( + weaponAndArmour, + varrockTeleport, + runePouches + ); + } + + @Override public List getCombatRequirements() { - return Arrays.asList("Temple Guardian (level 30). You cannot use Magic. Rings of recoil will not award the kill.", "Monk of Zamorak (level 30)"); + return List.of( + "Temple Guardian (level 30). You cannot use Magic. Rings of recoil will not award the kill.", + "Monk of Zamorak (level 30)" + ); } @Override @@ -337,31 +400,75 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.PRAYER, 1406)); + return List.of( + new ExperienceReward(Skill.PRAYER, 1406) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Wolfbane Dagger", ItemID.DAGGER_WOLFBANE, 1)); + return List.of( + new ItemReward("Wolfbane Dagger", ItemID.DAGGER_WOLFBANE, 1) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Access to Canifis and Morytania")); + return List.of( + new UnlockReward("Access to Canifis and Morytania") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Start the quest", Collections.singletonList(talkToRoald))); - allSteps.add(new PanelDetails("Go to the temple", Arrays.asList(goToTemple, killTheDog, returnToKingRoald), weaponAndArmour)); - allSteps.add(new PanelDetails("Return to the temple", Arrays.asList(returnToTemple, killMonk, talkToDrezel), weaponAndArmour, bucket, lotsOfRuneEssence)); - allSteps.add(new PanelDetails("Freeing Drezel", Arrays.asList(enterUnderground, useKeyForKey, fillBucket, goUpWithWaterToSecondFloor, openDoor, blessWater, useBlessedWater, talkToDrezelAfterFreeing), weaponAndArmour, bucket, lotsOfRuneEssence)); - allSteps.add(new PanelDetails("Curing the Salve", Arrays.asList(talkToDrezelUnderground, bringDrezelEssence), runeEssence)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Start the quest", List.of( + talkToRoald + ))); + + sections.add(new PanelDetails("Go to the temple", List.of( + goToTemple, + killTheDog, + returnToKingRoald + ), List.of( + weaponAndArmour + ))); + + sections.add(new PanelDetails("Return to the temple", List.of( + returnToTemple, + killMonk, + talkToDrezel + ), List.of( + weaponAndArmour, + bucket, + lotsOfRuneEssence + ))); + + sections.add(new PanelDetails("Freeing Drezel", List.of( + enterUnderground, + useKeyForKey, + fillBucket, + goUpWithWaterToSecondFloor, + openDoor, + blessWater, + useBlessedWater, + talkToDrezelAfterFreeing + ), List.of( + weaponAndArmour, + bucket, + lotsOfRuneEssence + ))); + + sections.add(new PanelDetails("Curing the Salve", List.of( + talkToDrezelUnderground, bringDrezelEssence + ), List.of( + runeEssence + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java index df394cbc6c..3a8b00e831 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/princealirescue/PrinceAliRescue.java @@ -30,7 +30,6 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; @@ -51,19 +50,18 @@ public class PrinceAliRescue extends BasicQuestHelper { //Items Required - ItemRequirement softClay, ballsOfWool3, yellowDye, redberries, ashes, bucketOfWater, potOfFlour, bronzeBar, pinkSkirt, beers3, rope, coins100, wig, dyedWig, paste, keyMould, key, + ItemRequirement softClay, ballsOfWool3, yellowDye, redberries, ashes, bucketOfWater, potOfFlour, bronzeBar, pinkSkirt, beers3, rope, coins100, wig, dyedWig, paste, keyPrint, key, ropeReqs, yellowDyeReqs, ropeHighlighted, keyHighlighted; //Items Recommended ItemRequirement glory; - Requirement hasOrGivenKeyMould, inCell, givenKeyMould, hasWigPasteAndKey; + Requirement hasOrUsedKeyPrint, inCell, hasWigPasteAndKey; + RuneliteRequirement madeKey; - RuneliteRequirement madeMould; + QuestStep talkToHassan, talkToOsman, talkToNed, talkToAggie, dyeWig, talkToKeli, makeKey, talkToLeela, reobtainKey, talkToJoe, useRopeOnKeli, useKeyOnDoor, talkToAli, returnToHassan; - QuestStep talkToHassan, talkToOsman, talkToNed, talkToAggie, dyeWig, talkToKeli, bringImprintToOsman, talkToLeela, talkToJoe, useRopeOnKeli, useKeyOnDoor, talkToAli, returnToHassan; - - ConditionalStep makeDyedWig, makePaste, makeKeyMould, getKey; + ConditionalStep makeDyedWig, makePaste, makeKeyPrint, getKey; //Zones Zone cell; @@ -86,39 +84,38 @@ public Map loadSteps() makePaste = new ConditionalStep(this, talkToAggie); makePaste.setLockingCondition(paste.alsoCheckBank()); - makeKeyMould = new ConditionalStep(this, talkToKeli); - makeKeyMould.setLockingCondition(hasOrGivenKeyMould); + makeKeyPrint = new ConditionalStep(this, talkToKeli); + makeKeyPrint.setLockingCondition(hasOrUsedKeyPrint); - getKey = new ConditionalStep(this, bringImprintToOsman); - getKey.setLockingCondition(givenKeyMould); + getKey = new ConditionalStep(this, makeKey); ConditionalStep prepareToSaveAli = new ConditionalStep(this, makeDyedWig); - prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), - new Conditions(LogicType.OR, madeMould, givenKeyMould)), talkToLeela); - prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), hasOrGivenKeyMould), getKey); - prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank()), makeKeyMould); + prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), madeKey), talkToLeela); + prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), hasOrUsedKeyPrint), getKey); + prepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank()), makeKeyPrint); prepareToSaveAli.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(20, prepareToSaveAli); - ConditionalStep getJoeDrunk = new ConditionalStep(this, makeDyedWig); + ConditionalStep reprepareToSaveAli = new ConditionalStep(this, makeDyedWig); + reprepareToSaveAli.addStep(new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank()), reobtainKey); + reprepareToSaveAli.addStep(dyedWig.alsoCheckBank(), makePaste); + + ConditionalStep getJoeDrunk = new ConditionalStep(this, reprepareToSaveAli); getJoeDrunk.addStep(hasWigPasteAndKey, talkToJoe); - getJoeDrunk.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(30, getJoeDrunk); steps.put(31, getJoeDrunk); steps.put(32, getJoeDrunk); steps.put(33, getJoeDrunk); - ConditionalStep tieUpKeli = new ConditionalStep(this, makeDyedWig); + ConditionalStep tieUpKeli = new ConditionalStep(this, reprepareToSaveAli); tieUpKeli.addStep(hasWigPasteAndKey, useRopeOnKeli); - tieUpKeli.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(40, tieUpKeli); - ConditionalStep freeAli = new ConditionalStep(this, makeDyedWig); + ConditionalStep freeAli = new ConditionalStep(this, reprepareToSaveAli); freeAli.addStep(new Conditions(hasWigPasteAndKey, inCell), talkToAli); freeAli.addStep(hasWigPasteAndKey, useKeyOnDoor); - freeAli.addStep(dyedWig.alsoCheckBank(), makePaste); steps.put(50, freeAli); steps.put(100, returnToHassan); @@ -150,7 +147,7 @@ protected void setupRequirements() wig.setHighlightInInventory(true); dyedWig = new ItemRequirement("Wig (dyed)", ItemID.BLONDWIG); paste = new ItemRequirement("Paste", ItemID.SKINPASTE); - keyMould = new ItemRequirement("Key print", ItemID.KEYPRINT); + keyPrint = new ItemRequirement("Key print", ItemID.KEYPRINT); key = new ItemRequirement("Bronze key", ItemID.PRINCESKEY); key.setTooltip("You can get another from Leela for 15 coins"); @@ -164,17 +161,15 @@ public void setupConditions() { inCell = new ZoneRequirement(cell); hasWigPasteAndKey = new Conditions(dyedWig.alsoCheckBank(), paste.alsoCheckBank(), key.alsoCheckBank()); - givenKeyMould = new Conditions(true, LogicType.OR, // TODO quest journal widget text outdated - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I have duplicated a key, I need to get it from"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I got a duplicated cell door key"), - new WidgetTextRequirement(11, 2, true, "You give Osman the imprint along with a bronze bar."), - new DialogRequirement("I'll use this to have a copy of the key made. I'll send it to Leela once it's ready."), - new DialogRequirement("I think I have everything needed."), + + var usedKeyPrint = new Conditions(true, LogicType.OR, + new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "made a copy of the key to his cell"), key.alsoCheckBank()); - madeMould = new RuneliteRequirement(getConfigManager(), "princealikeymouldhandedin", "true", givenKeyMould); - madeMould.initWithValue("false"); - hasOrGivenKeyMould = new Conditions(LogicType.OR, keyMould, givenKeyMould, key.alsoCheckBank()); + madeKey = new RuneliteRequirement(getConfigManager(), "princealikeymouldhandedin", "true", usedKeyPrint); + madeKey.initWithValue("false"); + + hasOrUsedKeyPrint = new Conditions(LogicType.OR, keyPrint, madeKey); } @Override @@ -197,15 +192,17 @@ public void setupSteps() talkToAggie = new NpcStep(this, NpcID.AGGIE_1OP, new WorldPoint(3086, 3257, 0), "Talk to Aggie in Draynor Village to get some paste.", redberries, ashes, potOfFlour, bucketOfWater); talkToAggie.addDialogStep("Can you make skin paste?"); talkToAggie.addDialogStep("Yes please. Mix me some skin paste."); - talkToKeli = new NpcStep(this, NpcID.LADY_KELI_VIS, new WorldPoint(3127, 3244, 0), "Talk to Keli in the jail east of Draynor Village. If you've already made the key mould, open the quest journal to re-sync.", softClay); + talkToKeli = new NpcStep(this, NpcID.LADY_KELI_VIS, new WorldPoint(3127, 3244, 0), "Talk to Keli in the jail east of Draynor Village. If you've already made the key print, open the quest journal to re-sync.", softClay); talkToKeli.addDialogStep("Heard of you? You're famous in Gielinor!"); talkToKeli.addDialogStep("What's your latest plan then?"); talkToKeli.addDialogStep("How do you know someone won't try to free him?"); talkToKeli.addDialogStep("Could I see the key please?"); talkToKeli.addDialogStep("Could I touch the key for a moment please?"); - bringImprintToOsman = new NpcStep(this, NpcID.OSMAN, new WorldPoint(3285, 3179, 0), "Bring the key print to Osman north of the Al Kharid Palace. If " + - "you already have, open the quest journal to re-sync.", keyMould, bronzeBar); + makeKey = new ObjectStep(this, ObjectID.FAI_FALADOR_FURNACE, new WorldPoint(3227, 3256, 0), "Use the key print on any furnace with a bronze bar in your inventory to make a key.", keyPrint.highlighted(), bronzeBar); talkToLeela = new NpcStep(this, NpcID.LEELA, new WorldPoint(3113, 3262, 0), "Talk to Leela east of Draynor Village.", beers3, dyedWig, paste, rope, pinkSkirt); + reobtainKey = new NpcStep(this, NpcID.LEELA, new WorldPoint(3113, 3262, 0), "Talk to Leela east of Draynor Village for another key. It'll cost 15gp.", coins100.quantity(15)); + talkToLeela.addSubSteps(reobtainKey); + talkToJoe = new NpcStep(this, NpcID.JOE_VIS, new WorldPoint(3124, 3245, 0), "Bring everything to the jail and give Joe there three beers.", beers3, key, dyedWig, paste, rope, pinkSkirt); talkToJoe.addDialogStep("I have some beer here. Fancy one?"); useRopeOnKeli = new NpcStep(this, NpcID.LADY_KELI_VIS, new WorldPoint(3127, 3244, 0), "Use rope on Keli.", ropeHighlighted); @@ -287,11 +284,11 @@ public List getPanels() makePastePanel.setLockingStep(makePaste); allSteps.add(makePastePanel); - PanelDetails makeKeyMouldPanel = new PanelDetails("Make a key mould", Collections.singletonList(talkToKeli), softClay); - makeKeyMouldPanel.setLockingStep(makeKeyMould); - allSteps.add(makeKeyMouldPanel); + PanelDetails makeKeyPrintPanel = new PanelDetails("Make a key print", Collections.singletonList(talkToKeli), softClay); + makeKeyPrintPanel.setLockingStep(makeKeyPrint); + allSteps.add(makeKeyPrintPanel); - PanelDetails getKeyPanel = new PanelDetails("Make the key", Collections.singletonList(bringImprintToOsman), bronzeBar, keyMould); + PanelDetails getKeyPanel = new PanelDetails("Make the key", Collections.singletonList(makeKey), bronzeBar, keyPrint); getKeyPanel.setLockingStep(getKey); allSteps.add(getKeyPanel); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java index c625f54b27..6e21173da6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/pryingtimes/PryingTimes.java @@ -43,7 +43,18 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PortTaskStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.client.plugins.microbot.questhelper.steps.SailStep; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -51,10 +62,9 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; public class PryingTimes extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java index 544bf9cd52..ab58653f45 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ragandboneman/RagAndBoneManII.java @@ -55,7 +55,11 @@ import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; import java.util.*; @@ -211,7 +215,7 @@ protected void setupRequirements() logs = new ItemRequirement("Logs", ItemID.LOGS); tinderbox = new ItemRequirement("Tinderbox", ItemID.TINDERBOX).isNotConsumed(); lightSource = new ItemRequirement("Light source", ItemCollections.LIGHT_SOURCES).isNotConsumed(); - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).isNotConsumed(); dustyKey.canBeObtainedDuringQuest(); mirrorShield = new ItemRequirement("Mirror shield", ItemID.SLAYER_MIRROR_SHIELD).isNotConsumed(); mirrorShield.addAlternates(ItemID.VIKINGEXILE_V_SHIELD, ItemID.V_SHIELD); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java index 40a971a3ed..72e8d43bac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/ratcatchers/RatCatchers.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java index 6200b6aba1..9592e7bf52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDDwarf.java @@ -144,7 +144,7 @@ protected void setupRequirements() asgoldianAle4 = new ItemRequirement("Asgoldian ale", ItemID.HUNDRED_DWARF_ASGARNIAN_ALE, 4); // Recommended - taverleyTeleport = new ItemRequirement("Teleport to taverley", ItemID.NZONE_TELETAB_TAVERLEY); + taverleyTeleport = new ItemRequirement("Teleport to Taverley", ItemID.NZONE_TELETAB_TAVERLEY); taverleyTeleport.addAlternates(ItemCollections.COMBAT_BRACELETS); teleportFalador = new ItemRequirement("Teleport to Falador", ItemID.POH_TABLET_FALADORTELEPORT); teleportLumbridge = new ItemRequirement("Teleport to Lumbridge", ItemID.POH_TABLET_LUMBRIDGETELEPORT); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java index af346440f1..eb088118a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDPiratePete.java @@ -61,7 +61,7 @@ public class RFDPiratePete extends BasicQuestHelper { ItemRequirement combatGear, pestleHighlighted, rawCodHighlighted, knifeHighlighted, breadHighlighted, divingAparatus, divingHelmet, fishBowl, bronzeWire3, needle, fishCake, fishCakeHighlighted, rocks5, mudskipperHide5, crabMeat, kelp, groundKelpHighlighted, groundCrabMeatHighlighted, kelpHighlighted, crabMeatHighlighted, - rawFishCake, groundCod, breadcrumbs; + rawFishCake, groundCod, breadcrumbs, emptySlotsX6; WeightRequirement canSwim; @@ -162,6 +162,7 @@ protected void setupRequirements() fishBowl = new ItemRequirement("Empty fishbowl", ItemID.FISHBOWL_EMPTY); bronzeWire3 = new ItemRequirement("Bronze wire", ItemID.BRONZECRAFTWIRE, 3); needle = new ItemRequirement("Needle", ItemID.NEEDLE).isNotConsumed(); + needle.setTooltip("Costume needle cannot be used as a substitute"); fishCake = new ItemRequirement("Cooked fishcake", ItemID.HUNDRED_PIRATE_FISHCAKE); fishCakeHighlighted = new ItemRequirement("Cooked fishcake", ItemID.HUNDRED_PIRATE_FISHCAKE); fishCakeHighlighted.setHighlightInInventory(true); @@ -185,6 +186,8 @@ protected void setupRequirements() groundCod = new ItemRequirement("Ground cod", ItemID.HUNDRED_PIRATE_GROUND_COD); groundCod.setTooltip("You can make this by use a pestle and mortar on a raw cod"); breadcrumbs = new ItemRequirement("Breadcrumbs", ItemID.HUNDRED_PIRATE_BREADCRUMBS); + emptySlotsX6 = new ItemRequirement("Empty inventory slots at minimum", -1, 6); + emptySlotsX6.setTooltip("Have an additional empty slot for each additional kelp beyond the minimum of 1"); combatGear = new ItemRequirement("Combat gear", -1, -1); combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); @@ -341,7 +344,7 @@ public List getPanels() { List allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Starting off", Arrays.asList(inspectPete, talkToCook, talkToMurphy, talkToMurphyAgain), fishBowl)); - allSteps.add(new PanelDetails("Get Crab and Kelp", Arrays.asList(goDiving, pickKelp, talkToNung, pickUpRocks, enterCave, killMudksippers5, returnToNung, giveNungWire, killCrab, climbAnchor), divingHelmet, divingAparatus, bronzeWire3, needle)); + allSteps.add(new PanelDetails("Get Crab and Kelp", Arrays.asList(goDiving, pickKelp, talkToNung, pickUpRocks, enterCave, killMudksippers5, returnToNung, giveNungWire, killCrab, climbAnchor), Arrays.asList(divingHelmet, divingAparatus, bronzeWire3, needle, emptySlotsX6, canSwim), Collections.singletonList(combatGear))); allSteps.add(new PanelDetails("Saving Pete", Arrays.asList(grindCrab, grindKelp, usePestleOnCod, useKnifeOnBread, talkToCookAgain, useCrabOnKelp, cookCake, useCakeOnPete), pestleHighlighted, knifeHighlighted, rawCodHighlighted, breadHighlighted, crabMeat, kelp)); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java index edfcb62abc..74ec05479d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recipefordisaster/RFDSkrachUglogwee.java @@ -220,7 +220,7 @@ public void setupSteps() getToad.addSubSteps(fillUpBellows); getRock = new ObjectStep(this, ObjectID.SWAMP_ROCK1, new WorldPoint(2567, 2960, 0), "Mine a pile of rocks near the Feldip Hills Fairy Ring for a rock.", pickaxe); useBellowOnToadInInv = new DetailedQuestStep(this, "Use the bellows on your toad with a ball of wool in your inventory.", ogreBellowsFilled, toad, ballOfWool); - dropBalloonToad = new DetailedQuestStep(this, new WorldPoint(2593, 2964, 0), "Drop the balloon toad near a swamp and wait for a Jubbly to arrive.", toadReady, ogreBowAndArrows); + dropBalloonToad = new DetailedQuestStep(this, new WorldPoint(2635, 2965, 0), "Drop the balloon toad in the dark area south of Rantz's cave and wait for a Jubbly to arrive.", toadReady, ogreBowAndArrows); killJubbly = new NpcStep(this, NpcID._100_JUBBLY_BIRD, "Kill then pluck jubbly.", ogreBowAndArrows); pickUpRawJubbly = new ItemStep(this, "Pick up the raw jubbly.", rawJubbly); lootJubbly = new NpcStep(this, NpcID._100_JUBBLY_BIRD_DEAD, "Pluck the jubbly's carcass."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java index 5a8f81a6bf..292f8e9a95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/DoorPuzzle.java @@ -28,43 +28,25 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; import net.runelite.api.events.GameTick; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; -import java.awt.*; -import java.util.HashMap; -import java.util.Map; - public class DoorPuzzle extends QuestStep { + private final HashMap highlightButtons = new HashMap<>(); + private final HashMap distance = new HashMap<>(); private Character ENTRY_ONE; private Character ENTRY_TWO; private Character ENTRY_THREE; private Character ENTRY_FOUR; - private final int SLOT_ONE = 43; - private final int SLOT_TWO = 44; - private final int SLOT_THREE = 45; - private final int SLOT_FOUR = 46; - - private final int ARROW_ONE_LEFT = 47; - private final int ARROW_ONE_RIGHT = 48; - private final int ARROW_TWO_LEFT = 49; - private final int ARROW_TWO_RIGHT = 50; - private final int ARROW_THREE_LEFT = 51; - private final int ARROW_THREE_RIGHT = 52; - private final int ARROW_FOUR_LEFT = 53; - private final int ARROW_FOUR_RIGHT = 54; - - private final int COMPLETE = 56; - - private final HashMap highlightButtons = new HashMap<>(); - private final HashMap distance = new HashMap<>(); - public DoorPuzzle(QuestHelper questHelper, String word) { super(questHelper, "Click the highlighted arrows to move the slots to the solution."); @@ -73,10 +55,10 @@ public DoorPuzzle(QuestHelper questHelper, String word) ENTRY_THREE = word.charAt(2); ENTRY_FOUR = word.charAt(3); - highlightButtons.put(1, ARROW_ONE_RIGHT); - highlightButtons.put(2, ARROW_TWO_RIGHT); - highlightButtons.put(3, ARROW_THREE_RIGHT); - highlightButtons.put(4, ARROW_FOUR_RIGHT); + highlightButtons.put(1, InterfaceID.RdCombolock.RDA_RIGHT); + highlightButtons.put(2, InterfaceID.RdCombolock.RDB_RIGHT); + highlightButtons.put(3, InterfaceID.RdCombolock.RDC_RIGHT); + highlightButtons.put(4, InterfaceID.RdCombolock.RDD_RIGHT); distance.put(1, 0); distance.put(2, 0); @@ -84,13 +66,23 @@ public DoorPuzzle(QuestHelper questHelper, String word) distance.put(4, 0); } + @Override + public void startUp() + { + super.startUp(); + + // Recalculate once when the step starts up to ensure highlights aren't wrong for a tick + updateSolvedPositionState(); + } + public void updateWord(String word) { ENTRY_ONE = word.charAt(0); ENTRY_TWO = word.charAt(1); - ENTRY_THREE = word.charAt(2); - ENTRY_FOUR = word.charAt(3); + ENTRY_THREE = word.charAt(2); + ENTRY_FOUR = word.charAt(3); setText("Click the highlighted arrows to move the slots to the solution. The answer is " + word + "."); + updateSolvedPositionState(); } @Subscribe @@ -101,19 +93,20 @@ public void onGameTick(GameTick gameTick) private void updateSolvedPositionState() { - highlightButtons.replace(1, matchStateToSolution(SLOT_ONE, ENTRY_ONE, ARROW_ONE_RIGHT, ARROW_ONE_LEFT)); - highlightButtons.replace(2, matchStateToSolution(SLOT_TWO, ENTRY_TWO, ARROW_TWO_RIGHT, ARROW_TWO_LEFT)); - highlightButtons.replace(3, matchStateToSolution(SLOT_THREE, ENTRY_THREE, ARROW_THREE_RIGHT, ARROW_THREE_LEFT)); - highlightButtons.replace(4, matchStateToSolution(SLOT_FOUR, ENTRY_FOUR, ARROW_FOUR_RIGHT, ARROW_FOUR_LEFT)); - distance.replace(1, matchStateToDistance(SLOT_ONE, ENTRY_ONE)); - distance.replace(2, matchStateToDistance(SLOT_TWO, ENTRY_TWO)); - distance.replace(3, matchStateToDistance(SLOT_THREE, ENTRY_THREE)); - distance.replace(4, matchStateToDistance(SLOT_FOUR, ENTRY_FOUR)); + highlightButtons.replace(1, matchStateToSolution(InterfaceID.RdCombolock.RDA, ENTRY_ONE, InterfaceID.RdCombolock.RDA_RIGHT, InterfaceID.RdCombolock.RDA_LEFT)); + highlightButtons.replace(2, matchStateToSolution(InterfaceID.RdCombolock.RDB, ENTRY_TWO, InterfaceID.RdCombolock.RDB_RIGHT, InterfaceID.RdCombolock.RDB_LEFT)); + highlightButtons.replace(3, matchStateToSolution(InterfaceID.RdCombolock.RDC, ENTRY_THREE, InterfaceID.RdCombolock.RDC_RIGHT, InterfaceID.RdCombolock.RDC_LEFT)); + highlightButtons.replace(4, matchStateToSolution(InterfaceID.RdCombolock.RDD, ENTRY_FOUR, InterfaceID.RdCombolock.RDD_RIGHT, InterfaceID.RdCombolock.RDD_LEFT)); + + distance.replace(1, matchStateToDistance(InterfaceID.RdCombolock.RDA, ENTRY_ONE)); + distance.replace(2, matchStateToDistance(InterfaceID.RdCombolock.RDB, ENTRY_TWO)); + distance.replace(3, matchStateToDistance(InterfaceID.RdCombolock.RDC, ENTRY_THREE)); + distance.replace(4, matchStateToDistance(InterfaceID.RdCombolock.RDD, ENTRY_FOUR)); if (highlightButtons.get(1) + highlightButtons.get(2) + highlightButtons.get(3) + highlightButtons.get(4) == 0) { - highlightButtons.put(5, COMPLETE); + highlightButtons.put(5, InterfaceID.RdCombolock.RDENTER); } else { @@ -123,19 +116,28 @@ private void updateSolvedPositionState() private int matchStateToSolution(int slot, Character target, int arrowRightId, int arrowLeftId) { - Widget widget = client.getWidget(InterfaceID.RD_COMBOLOCK, slot); - if (widget == null) return 0; + Widget widget = client.getWidget(slot); + if (widget == null) + { + return 0; + } char current = widget.getText().charAt(0); int currentPos = (int) current - (int) 'A'; int id = Math.floorMod(currentPos - target, 26) < Math.floorMod(target - currentPos, 26) ? arrowRightId : arrowLeftId; - if (current != target) return id; + if (current != target) + { + return id; + } return 0; } private int matchStateToDistance(int slot, Character target) { - Widget widget = client.getWidget(InterfaceID.RD_COMBOLOCK, slot); - if (widget == null) return 0; + Widget widget = client.getWidget(slot); + if (widget == null) + { + return 0; + } char current = widget.getText().charAt(0); return Math.min(Math.floorMod(current - target, 26), Math.floorMod(target - current, 26)); } @@ -151,7 +153,7 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) continue; } - Widget widget = client.getWidget(InterfaceID.RD_COMBOLOCK, entry.getValue()); + Widget widget = client.getWidget(entry.getValue()); if (widget != null) { graphics.setColor(new Color(questHelper.getConfig().targetOverlayColor().getRed(), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java index 8f3713f1f6..522c6f0fa3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/LadyTableStep.java @@ -25,113 +25,70 @@ */ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; -import com.google.inject.Inject; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.DetailedOwnerStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.Client; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.VarbitChanged; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class LadyTableStep extends DetailedOwnerStep +public class LadyTableStep extends ObjectStep { - @Inject - protected Client client; + private final Statue[] statues = new Statue[]{ + new Statue("Unknown", new WorldPoint(0, 0, 0)), + new Statue("Bronze Halberd", new WorldPoint(2452, 4976, 0)), + new Statue("Silver Halberd", new WorldPoint(2452, 4979, 0)), + new Statue("Gold Halberd", new WorldPoint(2452, 4982, 0)), - private Statue[] statues; + new Statue("Bronze 2H", new WorldPoint(2450, 4976, 0)), + new Statue("Silver 2H", new WorldPoint(2450, 4979, 0)), + new Statue("Gold 2H", new WorldPoint(2450, 4982, 0)), - private ObjectStep clickMissingStatue, leaveRoom; + new Statue("Gold Mace", new WorldPoint(2456, 4982, 0)), + new Statue("Silver Mace", new WorldPoint(2456, 4979, 0)), + new Statue("Bronze mace", new WorldPoint(2456, 4976, 0)), - VarbitRequirement finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM2_COMPLETE, 1); + new Statue("Bronze axe", new WorldPoint(2454, 4976, 0)), + new Statue("Silver axe", new WorldPoint(2454, 4979, 0)), + new Statue("Gold axe", new WorldPoint(2454, 4972, 0)) + }; public LadyTableStep(QuestHelper questHelper, Requirement... requirements) { - super(questHelper, requirements); + super(questHelper, ObjectID.RD_1G, new WorldPoint(0, 0, 0), "Click the missing statue.", requirements); + + addAlternateObjects(ObjectID.RD_1S, ObjectID.RD_1B, + ObjectID.RD_2G, ObjectID.RD_2S, ObjectID.RD_2B, ObjectID.RD_3G, + ObjectID.RD_3S, ObjectID.RD_3B, ObjectID.RD_4G, ObjectID.RD_4B); } @Override public void startUp() { super.startUp(); - Statue answerStatue = statues[client.getVarbitValue(VarbitID.RD_TEMPLOCK_2)]; - clickMissingStatue.setText("Click the " + answerStatue.text + " once it appears."); - clickMissingStatue.setWorldPoint(answerStatue.point); + + var answerIndex = client.getVarbitValue(VarbitID.RD_TEMPLOCK_2); + if (answerIndex < statues.length) + { + var answerStatue = statues[answerIndex]; + setText("Click the " + answerStatue.text + " once it appears."); + setWorldPoint(answerStatue.point); + } } @Override public void onVarbitChanged(VarbitChanged varbitChanged) { super.onVarbitChanged(varbitChanged); - Statue answerStatue = statues[client.getVarbitValue(VarbitID.RD_TEMPLOCK_2)]; - clickMissingStatue.setText("Click the " + answerStatue.text + " once it appears."); - clickMissingStatue.setWorldPoint(answerStatue.point); - } - @Override - public void setupSteps() - { - statues = new Statue[]{ - new Statue("Unknown", new WorldPoint(0, 0, 0)), - new Statue("Bronze Halberd", new WorldPoint(2452, 4976, 0)), - new Statue("Silver Halberd", new WorldPoint(2452, 4979, 0)), - new Statue("Gold Halberd", new WorldPoint(2452, 4982, 0)), - - new Statue("Bronze 2H", new WorldPoint(2450, 4976, 0)), - new Statue("Silver 2H", new WorldPoint(2450, 4979, 0)), - new Statue("Gold 2H", new WorldPoint(2450, 4982, 0)), - - new Statue("Gold Mace", new WorldPoint(2456, 4982, 0)), - new Statue("Silver Mace", new WorldPoint(2456, 4979, 0)), - new Statue("Bronze mace", new WorldPoint(2456, 4976, 0)), - - new Statue("Bronze axe", new WorldPoint(2454, 4976, 0)), - new Statue("Silver axe", new WorldPoint(2454, 4979, 0)), - new Statue("Gold axe", new WorldPoint(2454, 4972, 0)) - }; - - leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM2_EXITDOOR, "Leave through the door to enter the portal and continue."); - clickMissingStatue = new ObjectStep(questHelper, 0, statues[0].point, "CLick the missing statue."); - clickMissingStatue.addAlternateObjects(ObjectID.RD_1G, ObjectID.RD_1S, ObjectID.RD_1B, - ObjectID.RD_2G, ObjectID.RD_2S, ObjectID.RD_2B, ObjectID.RD_3G, - ObjectID.RD_3S, ObjectID.RD_3B, ObjectID.RD_4G, ObjectID.RD_4B); - } - - @Override - public Collection getSteps() - { - List step = new ArrayList<>(); - - step.add(clickMissingStatue); - step.add(leaveRoom); - return step; - } - - @Override - protected void updateSteps() - { - if (finishedRoom.check(client)) + if (varbitChanged.getVarbitId() == VarbitID.RD_TEMPLOCK_2) { - startUpStep(leaveRoom); + var answerIndex = varbitChanged.getValue(); + var answerStatue = statues[answerIndex]; + setText("Click the " + answerStatue.text + " once it appears."); + setWorldPoint(answerStatue.point); } - startUpStep(clickMissingStatue); - } - - public List getPanelSteps() - { - List steps = new ArrayList<>(); - steps.add(clickMissingStatue); - steps.add(leaveRoom); - - return steps; } static class Statue diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MissCheeversStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MissCheeversStep.java new file mode 100644 index 0000000000..1b76dbd736 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MissCheeversStep.java @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2020, Patyfatycake + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABI`LITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; + +import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.List; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; + +@SuppressWarnings("FieldCanBeLocal") +public class MissCheeversStep extends ConditionalStep +{ + // Requirements + ItemRequirement magnet; + ItemRequirement aceticAcid; + ItemRequirement vialOfLiquid; + ItemRequirement cupricSulfate; + ItemRequirement gypsum; + ItemRequirement sodiumChloride; + ItemRequirement bronzeWire; + ItemRequirement tin; + ItemRequirement shears; + ItemRequirement chisel; + ItemRequirement nitrousOxide; + ItemRequirement tinOrePowder; + ItemRequirement cupricOrePowder; + ItemRequirement knife; + ItemRequirement metalSpade; + ItemRequirement metalSpadeHead; + ItemRequirement ashes; + ItemRequirement gypsumTin; + ItemRequirement tinKeyPrint; + ItemRequirement tinWithCupricOre; + ItemRequirement tinWithTinOre; + ItemRequirement tinWithAllOre; + ItemRequirement bronzeKey; + + VarbitRequirement hasRetrievedThreeVials; + VarbitRequirement hasSpadeHeadOnDoor; + VarbitRequirement hasCupricSulfateOnDoor; + VarbitRequirement hasVialOfLiquidOnDoor; + VarbitRequirement hasFirstDoorOpen; + VarbitRequirement hasLiquidInTin; + + // Steps + ObjectStep getMagnet; + ObjectStep getTwoVials; + ObjectStep getCupricSulfate; + ObjectStep getGypsum; + ObjectStep getSodiumChloride; + ObjectStep getWire; + ObjectStep getTin; + ObjectStep getShears; + ObjectStep getChisel; + ObjectStep getNitrousOxide; + ObjectStep getTinOrePowder; + ObjectStep getCupricOrePowder; + ObjectStep getThreeVials; + ObjectStep getKnife; + ItemStep getMetalSpade; + + // Destroying first door steps + QuestStep useSpadeOnBunsenBurner; + QuestStep useSpadeHeadOnDoor; + QuestStep useCupricSulfateOnDoor; + QuestStep useVialOfLiquidOnDoor; + QuestStep openDoor; + // Creating second door key steps + QuestStep useVialOfLiquidOnCakeTin; + QuestStep useGypsumOnTin; + QuestStep useTinOnKey; + QuestStep useCupricOrePowderOnTin; + QuestStep useTinOrePowderOnTin; + QuestStep useTinOnBunsenBurner; + QuestStep useEquipmentOnTin; + + PuzzleWrapperStep pwGetMagnet; + PuzzleWrapperStep pwGetTwoVials; + PuzzleWrapperStep pwGetCupricSulfate; + PuzzleWrapperStep pwGetGypsum; + PuzzleWrapperStep pwGetSodiumChloride; + PuzzleWrapperStep pwGetWire; + PuzzleWrapperStep pwGetTin; + PuzzleWrapperStep pwGetShears; + PuzzleWrapperStep pwGetChisel; + PuzzleWrapperStep pwGetNitrousOxide; + PuzzleWrapperStep pwGetTinOrePowder; + PuzzleWrapperStep pwGetCupricOrePowder; + PuzzleWrapperStep pwGetThreeVials; + PuzzleWrapperStep pwGetKnife; + PuzzleWrapperStep pwGetMetalSpade; + PuzzleWrapperStep pwUseSpadeOnBunsenBurner; + PuzzleWrapperStep pwUseSpadeHeadOnDoor; + PuzzleWrapperStep pwUseCupricSulfateOnDoor; + PuzzleWrapperStep pwUseVialOfLiquidOnDoor; + PuzzleWrapperStep pwOpenDoor; + PuzzleWrapperStep pwUseVialOfLiquidOnCakeTin; + PuzzleWrapperStep pwUseGypsumOnTin; + PuzzleWrapperStep pwUseTinOnKey; + PuzzleWrapperStep pwUseCupricOrePowderOnTin; + PuzzleWrapperStep pwUseTinOrePowderOnTin; + PuzzleWrapperStep pwUseTinOnBunsenBurner; + PuzzleWrapperStep pwUseEquipmentOnTin; + + public MissCheeversStep(QuestHelper questHelper, Requirement... requirements) + { + // null safety - addSteps sets the null conditional step + super(questHelper, null, requirements); + + setupRequirements(); + setupSteps(); + addSteps(); + } + + public void setupRequirements() + { + magnet = new ItemRequirement("Magnet", ItemID.RD_MAGNET); + + aceticAcid = new ItemRequirement("Acetic Acid", ItemID.RD_ACETIC_ACID); + + vialOfLiquid = new ItemRequirement(true, "Vial of Liquid", ItemID.RD_DIHYDROGEN_MONOXIDE); + vialOfLiquid.setTooltip("Take from the shelf on the north side or the south side."); + + cupricSulfate = new ItemRequirement(true, "Cupric Sulfate", ItemID.RD_CUPRIC_SULPHATE); + cupricSulfate.setTooltip("Take from the shelves on the north side"); + + gypsum = new ItemRequirement(true, "Gypsum", ItemID.RD_GYPSUM); + + sodiumChloride = new ItemRequirement("Sodium Chloride", ItemID.RD_SODIUM_CHLORIDE); + + bronzeWire = new ItemRequirement(true, "Bronze Wire", ItemID.RD_WIRE); + + tin = new ItemRequirement(true, "Tin", ItemID.RD_TIN); + // TODO set tip + + shears = new ItemRequirement("Shears", ItemID.RD_SHEARS); + + chisel = new ItemRequirement(true, "Chisel", ItemID.RD_CHISEL); + + nitrousOxide = new ItemRequirement("Nitrous Oxide", ItemID.RD_NITORUS_OXIDE); + + tinOrePowder = new ItemRequirement(true, "Tin Ore Powder", ItemID.RD_TIN_ORE_POWDER); + + cupricOrePowder = new ItemRequirement(true, "Cupric Ore Powder", ItemID.RD_COPPER_ORE_POWDER); + + knife = new ItemRequirement(true, "Knife", ItemID.RD_KNIFE); + + metalSpade = new ItemRequirement(true, "Metal Spade", ItemID.RD_METAL_SPADE); + metalSpade.setTooltip("If you are missing this item pick another up off the table."); + + metalSpadeHead = new ItemRequirement(true, "Metal Spade", ItemID.RD_METAL_SPADE_NO_HANDLE); + metalSpadeHead.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); + ashes = new ItemRequirement(true, "Ashes", ItemID.ASHES); + ashes.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); + + gypsumTin = new ItemRequirement(true, "Tin", ItemID.RD_TINFULL); + + tinKeyPrint = new ItemRequirement(true, "Tin", ItemID.RD_KEYMOULD); + + tinWithCupricOre = new ItemRequirement(true, "Tin", ItemID.RD_FULL_KEYMOULD_COPPER); + + tinWithTinOre = new ItemRequirement(true, "Tin", ItemID.RD_FULL_KEYMOULD_UNHEATED); + + tinWithAllOre = new ItemRequirement(true, "Tin", ItemID.RD_FULL_KEYMOULD_COMPLETE); + + bronzeKey = new ItemRequirement("Bronze Key", ItemID.RD_PUZZLEROOM_KEY); + + hasRetrievedThreeVials = new VarbitRequirement(VarbitID.RD_SPARE_WATER, 3); + hasSpadeHeadOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 1); + hasCupricSulfateOnDoor = new VarbitRequirement(VarbitID.RD_REACT_ON_SPADE, 1); + hasVialOfLiquidOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 2); + hasFirstDoorOpen = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 3); + + hasLiquidInTin = new VarbitRequirement(VarbitID.RD_WATER_IN_TIN, 1); + } + + private void setupSteps() + { + getMagnet = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL, "Get the magnet from the old bookshelf."); + getTwoVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_1, "Get two vials from the shelves"); + getTwoVials.addDialogStep("Take both vials."); + getCupricSulfate = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_2, "Get Cupric Sulfate from the shelves."); + getCupricSulfate.addDialogStep("YES"); + getGypsum = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_3, "Get Gypsum from the shelves."); + getGypsum.addDialogStep("YES"); + getSodiumChloride = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_4, "Get Sodium Chloride from the shelves."); + getSodiumChloride.addDialogStep("YES"); + getWire = new ObjectStep(questHelper, ObjectID.RD_SMALL_CRATES, new WorldPoint(2475, 4943, 0), "Get Wire from the crate."); + getTin = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATE, new WorldPoint(2476, 4943, 0), "Get Tin from the crate."); + getShears = new ObjectStep(questHelper, ObjectID.RD_CHEST_CLOSED, "Get Shears from the chest."); + getShears.addAlternateObjects(ObjectID.RD_CHEST_OPEN); + getChisel = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATES, new WorldPoint(2476, 4937, 0), "Get a Chisel from the crate."); + getNitrousOxide = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_5, "Get Nitrous Oxide from the Shelves."); + getNitrousOxide.addDialogStep("YES"); + getTinOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_6, "Get Tin Ore Powder from the Shelves."); + getTinOrePowder.addDialogStep("YES"); + getCupricOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_7, "Get Cupric Ore Powder from the Shelves."); + getCupricOrePowder.addDialogStep("YES"); + getThreeVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_8, "Get Three Vials Of Liquid from the Shelves."); + getThreeVials.addDialogStep("Take all three vials"); + getKnife = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL3, "Get a Knife from the old bookshelf."); + getMetalSpade = new ItemStep(questHelper, "Get the metal spade off the table", metalSpade); + + useSpadeOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, "Use the spade in your inventory on the bunsen burner", metalSpade); + useSpadeOnBunsenBurner.addIcon(ItemID.RD_METAL_SPADE); + + useSpadeHeadOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use the spade in your inventory on the door.", metalSpadeHead); + useSpadeHeadOnDoor.addIcon(ItemID.RD_METAL_SPADE_NO_HANDLE); + + useCupricSulfateOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use Cupric Sulfate in your inventory on the door.", cupricSulfate); + useCupricSulfateOnDoor.addIcon(ItemID.RD_CUPRIC_SULPHATE); + + useVialOfLiquidOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use vial of liquid in your inventory on the door.", vialOfLiquid); + useVialOfLiquidOnDoor.addIcon(ItemID.RD_DIHYDROGEN_MONOXIDE); + + openDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Open the door."); + + useVialOfLiquidOnCakeTin = new DetailedQuestStep(questHelper, "Use a vial of liquid on the tin in your inventory.", tin, vialOfLiquid); + + useGypsumOnTin = new DetailedQuestStep(questHelper, "Use a vial of Gypsum on the tin in your inventory.", gypsum, tin); + + useTinOnKey = new ObjectStep(questHelper, ObjectID.RD_KEY_CHAINED, "Use tin full with Gypsum on the key on the ground.", gypsumTin); + useTinOnKey.addIcon(ItemID.RD_TINFULL); + + useCupricOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the cupric ore powder in your inventory.", tinKeyPrint, cupricOrePowder); + + useTinOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the tin ore powder in your inventory.", tinWithCupricOre, tinOrePowder); + + useTinOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, "Use your tin with the bunsen burner to create a bronze key.", tinWithTinOre); + useTinOnBunsenBurner.addIcon(ItemID.RD_FULL_KEYMOULD_UNHEATED); + + useEquipmentOnTin = new DetailedQuestStep(questHelper, "Use your chisel, knife or bronze wires on your tin in your inventory.", tinWithAllOre, chisel, knife, bronzeWire); + + pwGetMagnet = getMagnet.puzzleWrapStep(true); + pwGetTwoVials = getTwoVials.puzzleWrapStep(true); + pwGetCupricSulfate = getCupricSulfate.puzzleWrapStep(true); + pwGetGypsum = getGypsum.puzzleWrapStep(true); + pwGetSodiumChloride = getSodiumChloride.puzzleWrapStep(true); + pwGetWire = getWire.puzzleWrapStep(true); + pwGetTin = getTin.puzzleWrapStep(true); + pwGetShears = getShears.puzzleWrapStep(true); + pwGetChisel = getChisel.puzzleWrapStep(true); + pwGetNitrousOxide = getNitrousOxide.puzzleWrapStep(true); + pwGetTinOrePowder = getTinOrePowder.puzzleWrapStep(true); + pwGetCupricOrePowder = getCupricOrePowder.puzzleWrapStep(true); + pwGetThreeVials = getThreeVials.puzzleWrapStep(true); + pwGetKnife = getKnife.puzzleWrapStep(true); + pwGetMetalSpade = getMetalSpade.puzzleWrapStep(true); + pwUseSpadeOnBunsenBurner = useSpadeOnBunsenBurner.puzzleWrapStep(true); + pwUseSpadeHeadOnDoor = useSpadeHeadOnDoor.puzzleWrapStep(true); + pwUseCupricSulfateOnDoor = useCupricSulfateOnDoor.puzzleWrapStep(true); + pwUseVialOfLiquidOnDoor = useVialOfLiquidOnDoor.puzzleWrapStep(true); + pwOpenDoor = openDoor.puzzleWrapStep(true); + pwUseVialOfLiquidOnCakeTin = useVialOfLiquidOnCakeTin.puzzleWrapStep(true); + pwUseGypsumOnTin = useGypsumOnTin.puzzleWrapStep(true); + pwUseTinOnKey = useTinOnKey.puzzleWrapStep(true); + pwUseCupricOrePowderOnTin = useCupricOrePowderOnTin.puzzleWrapStep(true); + pwUseTinOrePowderOnTin = useTinOrePowderOnTin.puzzleWrapStep(true); + pwUseTinOnBunsenBurner = useTinOnBunsenBurner.puzzleWrapStep(true); + pwUseEquipmentOnTin = useEquipmentOnTin.puzzleWrapStep(true); + } + + private void addSteps() + { + this.addStep(null, pwGetMagnet); + setupSecondDoorKeyStep(); + destroyFirstDoorSteps(); + retrieveItemSteps(); + } + + /*** + * Steps and conditions required to create the key for the second door. + */ + private void setupSecondDoorKeyStep() + { + this.addStep(and(hasFirstDoorOpen, tinWithAllOre), pwUseEquipmentOnTin); + this.addStep(and(hasFirstDoorOpen, tinWithTinOre), pwUseTinOnBunsenBurner); + this.addStep(and(hasFirstDoorOpen, tinWithCupricOre), pwUseTinOrePowderOnTin); + this.addStep(and(hasFirstDoorOpen, tinKeyPrint), pwUseCupricOrePowderOnTin); + this.addStep(and(hasFirstDoorOpen, gypsumTin), pwUseTinOnKey); + this.addStep(and(hasFirstDoorOpen, hasLiquidInTin), pwUseGypsumOnTin); + this.addStep(hasFirstDoorOpen, pwUseVialOfLiquidOnCakeTin); + } + + /*** + * Steps and conditions required to destroy the first door. + */ + private void destroyFirstDoorSteps() + { + this.addStep(and(magnet, aceticAcid, vialOfLiquid, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, ashes, hasVialOfLiquidOnDoor), pwOpenDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, ashes, hasCupricSulfateOnDoor), pwUseVialOfLiquidOnDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, ashes, hasSpadeHeadOnDoor), pwUseCupricSulfateOnDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, metalSpadeHead, ashes), pwUseSpadeHeadOnDoor); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife, metalSpade), pwUseSpadeOnBunsenBurner); + } + + /** + * First stage to retrieve all required items to pass the room. + */ + private void retrieveItemSteps() + { + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials, knife), pwGetMetalSpade); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder, hasRetrievedThreeVials), pwGetKnife); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder, cupricOrePowder), pwGetThreeVials); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide, tinOrePowder), pwGetCupricOrePowder); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, nitrousOxide, nitrousOxide), pwGetTinOrePowder); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears, chisel), pwGetNitrousOxide); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin, shears), pwGetChisel); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire, tin), pwGetShears); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride, bronzeWire), pwGetTin); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum, sodiumChloride), pwGetWire); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate, gypsum), pwGetSodiumChloride); + this.addStep(and(magnet, aceticAcid, vialOfLiquid, cupricSulfate), pwGetGypsum); + this.addStep(and(magnet, aceticAcid, vialOfLiquid), pwGetCupricSulfate); + this.addStep(magnet, pwGetTwoVials); + } + + public List getPanelSteps() + { + return List.of( + pwGetMagnet, + pwGetTwoVials, + pwGetCupricSulfate, + pwGetGypsum, + pwGetSodiumChloride, + pwGetWire, + pwGetTin, + pwGetShears, + pwGetChisel, + pwGetNitrousOxide, + pwGetTinOrePowder, + pwGetCupricOrePowder, + pwGetThreeVials, + pwGetKnife, + pwGetMetalSpade, + pwUseSpadeOnBunsenBurner, + pwUseSpadeHeadOnDoor, + pwUseCupricSulfateOnDoor, + pwUseVialOfLiquidOnDoor, + pwOpenDoor, + pwUseVialOfLiquidOnCakeTin, + pwUseGypsumOnTin, + pwUseTinOnKey, + pwUseCupricOrePowderOnTin, + pwUseTinOrePowderOnTin, + pwUseTinOnBunsenBurner, + pwUseEquipmentOnTin + ); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsCheevesSetup.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsCheevesSetup.java deleted file mode 100644 index b80ed3d212..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsCheevesSetup.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2020, Patyfatycake - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABI`LITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; - -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; -import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.*; -import lombok.Getter; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.ObjectID; -import net.runelite.api.gameval.VarbitID; - -import java.util.ArrayList; -import java.util.List; - -public class MsCheevesSetup -{ - private QuestHelper questHelper; - - @Getter - private ZoneRequirement isInMsCheeversRoom; - - @Getter - private ConditionalStep conditionalStep; - - private ObjectStep getMagnetStep, getTwoVials, getCupricSulfate, - getGypsum, getSodiumChloride, getWire, getTin, getShears, - getChisel, getNitrousOxide, getTinOrePowder, getCupricOrePowder, getThreeVials, - getKnife, leaveRoom; - private ItemStep getMetalSpade; - - // TODO: Clean up to just use ItemRequirement - private Requirement hasMagnet, hasAceticAcid, hasOneVialOfLiquid, - hasCupricSulfate, hasGypsum, hasSodiumChloride, hasWire, hasTin, - hasShears, hasChisel, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasKnife, hasMetalSpade, hasMetalSpadeHead, hasAshes, hasBronzeKey; - - private VarbitRequirement finishedRoom; - - // Destroying first door steps - private QuestStep useSpadeOnBunsenBurner, useSpadeHeadOnDoor, useCupricSulfateOnDoor, useVialOfLiquidOnDoor, openDoor; - private VarbitRequirement hasRetrievedThreeVials, hasSpadeHeadOnDoor, hasCupricSulfateOnDoor, hasVialOfLiquidOnDoor, hasFirstDoorOpen; - private ItemRequirement metalSpade, metalSpadeHead, ashes, cupricSulfate, vialOfLiquid; - - // Creating second door key steps - private QuestStep useVialOfLiquidOnCakeTin, useGypsumOnTin, useTinOnKey, useCupricOrePowderOnTin, useTinOrePowderOnTin, useTinOnBunsenBurner, useEquipmentOnTin; - private ItemRequirement tin, gypsumTin, gypsum, tinKeyPrint, cupricOrePowder, tinOrePowder, tinWithCupricOre, - tinWithTinOre, tinWithAllOre, bronzeKey, knife, chisel, bronzeWire; - private VarbitRequirement hasLiquidInTin; - ItemRequirement hasGypsumTin, hasTinKeyPrint, hasTinCupricOre, hasTinWithTinOre, hasTinWithAllOre; - - public MsCheevesSetup(QuestHelper questHelper) - { - this.questHelper = questHelper; - setupRequirements(); - setupZoneCondition(); - setupConditions(); - setupSteps(); - addSteps(); - } - - private void setupSteps() - { - getMagnetStep = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL, "Get the magnet from the old bookshelf."); - getTwoVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_1, "Get two vials from the shelves"); - getTwoVials.addDialogStep("Take both vials."); - getCupricSulfate = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_2, "Get Cupric Sulfate from the shelves."); - getCupricSulfate.addDialogStep("YES"); - getGypsum = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_3, "Get Gypsum from the shelves."); - getGypsum.addDialogStep("YES"); - getSodiumChloride = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_4, "Get Sodium Chloride from the shelves."); - getSodiumChloride.addDialogStep("YES"); - getWire = new ObjectStep(questHelper, ObjectID.RD_SMALL_CRATES, new WorldPoint(2475, 4943, 0), "Get Wire from the crate."); - getTin = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATE, new WorldPoint(2476, 4943, 0), "Get Tin from the crate."); - getShears = new ObjectStep(questHelper, ObjectID.RD_CHEST_CLOSED, "Get Shears from the chest."); - getShears.addAlternateObjects(ObjectID.RD_CHEST_OPEN); - getChisel = new ObjectStep(questHelper, ObjectID.RD_LARGE_CRATES, new WorldPoint(2476, 4937, 0), "Get a Chisel from the crate."); - getNitrousOxide = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_5, "Get Nitrous Oxide from the Shelves."); - getNitrousOxide.addDialogStep("YES"); - getTinOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_6, "Get Tin Ore Powder from the Shelves."); - getTinOrePowder.addDialogStep("YES"); - getCupricOrePowder = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_7, "Get Curpic Ore Powder from the Shelves."); - getCupricOrePowder.addDialogStep("YES"); - getThreeVials = new ObjectStep(questHelper, ObjectID.RD_SHELVES_CHEMICALS_8, "Get Three Vials Of Liquid from the Shelves."); - getThreeVials.addDialogStep("Take all three vials"); - getKnife = new ObjectStep(questHelper, ObjectID.RD_BOOKSHELF_OLD_TALL3, "Get a Knife from the old bookshelf."); - getMetalSpade = new ItemStep(questHelper, "Get the metal spade off the table", metalSpade); - - useSpadeOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, "Use the spade in your inventory on the bunsen burner" - , metalSpade); - useSpadeOnBunsenBurner.addIcon(ItemID.RD_METAL_SPADE); - - useSpadeHeadOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use the spade in your inventory on the door.", - metalSpadeHead); - useSpadeHeadOnDoor.addIcon(ItemID.RD_METAL_SPADE_NO_HANDLE); - - useCupricSulfateOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use Cupric Sulfate in your inventory on the door.", - cupricSulfate); - useCupricSulfateOnDoor.addIcon(ItemID.RD_CUPRIC_SULPHATE); - - useVialOfLiquidOnDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Use vial of liquid in your inventory on the door.", - vialOfLiquid); - useVialOfLiquidOnDoor.addIcon(ItemID.RD_DIHYDROGEN_MONOXIDE); - - openDoor = new ObjectStep(questHelper, ObjectID.RD_STONE_DOOR, "Open the door."); - - useVialOfLiquidOnCakeTin = new DetailedQuestStep(questHelper, "Use a vial of liquid on the tin in your inventory.", - tin, vialOfLiquid); - - useGypsumOnTin = new DetailedQuestStep(questHelper, "Use a vial of Gypsum on the tin in your inventory.", - gypsum, tin); - - useTinOnKey = new ObjectStep(questHelper, ObjectID.RD_KEY_CHAINED, "Use tin full with Gypsum on the key on the ground.", - gypsumTin); - useTinOnKey.addIcon(ItemID.RD_TINFULL); - - useCupricOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the cupric ore powder in your inventory.", - tinKeyPrint, cupricOrePowder); - - useTinOrePowderOnTin = new DetailedQuestStep(questHelper, "Use Tin on the tin ore powder in your inventory.", - tinWithCupricOre, tinOrePowder); - - useTinOnBunsenBurner = new ObjectStep(questHelper, ObjectID.RD_WOODEN_TABLE_BUNSEN_BURNER, - "Use your tin with the bunsen burner to create a bronze key.", tinWithTinOre); - useTinOnBunsenBurner.addIcon(ItemID.RD_FULL_KEYMOULD_UNHEATED); - - useEquipmentOnTin = new DetailedQuestStep(questHelper, "Use your chisel, knife or bronze wires on your tin in your inventory.", - tinWithAllOre, chisel, knife, bronzeWire); - - leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM6_EXITDOOR, new WorldPoint(2478, 4940, 0), "Leave the room by the second door to enter the portal"); - } - - private void addSteps() - { - conditionalStep = new ConditionalStep(questHelper, getMagnetStep); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasBronzeKey, finishedRoom), leaveRoom); - setupSecondDoorKeyStep(); - destroyFirstDoorSteps(); - retrieveItemSteps(); - } - - public List GetPanelSteps() - { - List steps = new ArrayList<>(); - steps.add(getMagnetStep); - steps.add(getTwoVials); - steps.add(getCupricSulfate); - steps.add(getGypsum); - steps.add(getSodiumChloride); - steps.add(getWire); - steps.add(getTin); - steps.add(getShears); - steps.add(getChisel); - steps.add(getNitrousOxide); - steps.add(getTinOrePowder); - steps.add(getCupricOrePowder); - steps.add(getThreeVials); - steps.add(getKnife); - steps.add(getMetalSpade); - steps.add(useSpadeOnBunsenBurner); - steps.add(useSpadeHeadOnDoor); - steps.add(useCupricSulfateOnDoor); - steps.add(useVialOfLiquidOnDoor); - steps.add(openDoor); - steps.add(useVialOfLiquidOnCakeTin); - steps.add(useGypsumOnTin); - steps.add(useTinOnKey); - steps.add(useCupricOrePowderOnTin); - steps.add(useTinOrePowderOnTin); - steps.add(useTinOnBunsenBurner); - steps.add(useEquipmentOnTin); - steps.add(leaveRoom); - return steps; - } - - /*** - * Steps and conditions required to create the key for the second door. - */ - private void setupSecondDoorKeyStep() - { - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinWithAllOre), useEquipmentOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinWithTinOre), useTinOnBunsenBurner); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinCupricOre), useTinOrePowderOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasTinKeyPrint), useCupricOrePowderOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasGypsumTin), useTinOnKey); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen, hasLiquidInTin), useGypsumOnTin); - conditionalStep.addStep(new Conditions(hasFirstDoorOpen), useVialOfLiquidOnCakeTin); - } - - /*** - * Steps and conditions required to destroy the first door. - */ - private void destroyFirstDoorSteps() - { - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasAshes, hasVialOfLiquidOnDoor), openDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasAshes, hasCupricSulfateOnDoor), useVialOfLiquidOnDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasAshes, hasSpadeHeadOnDoor), useCupricSulfateOnDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasMetalSpadeHead, hasAshes), useSpadeHeadOnDoor); - - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife, hasMetalSpade), useSpadeOnBunsenBurner); - } - - /** - * First stage to retrieve all required items to pass the room. - */ - private void retrieveItemSteps() - { - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials, hasKnife), getMetalSpade); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder, - hasRetrievedThreeVials), getKnife); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder, hasCupricOrePowder) - , getThreeVials); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide, hasTinOrePowder), getCupricOrePowder); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasNitrousOxide, hasNitrousOxide), getTinOrePowder); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears, hasChisel), getNitrousOxide); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin, hasShears), getChisel); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire, hasTin), getShears); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride, hasWire), getTin); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum, - hasSodiumChloride), getWire); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate, hasGypsum), - getSodiumChloride); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid, hasCupricSulfate), getGypsum); - conditionalStep.addStep(new Conditions(hasMagnet, hasAceticAcid, hasOneVialOfLiquid), getCupricSulfate); - conditionalStep.addStep(hasMagnet, getTwoVials); - } - - private void setupZoneCondition() - { - Zone missCheevesZone = new Zone(new WorldPoint(2466, 4936, 0), - new WorldPoint(2480, 4947, 0)); - isInMsCheeversRoom = new ZoneRequirement(missCheevesZone); - } - - public void setupRequirements() - { - metalSpade = new ItemRequirement("Metal Spade", ItemID.RD_METAL_SPADE); - metalSpade.setTooltip("If you are missing this item pick another up off the table."); - metalSpade.setHighlightInInventory(true); - metalSpadeHead = new ItemRequirement("Metal Spade", ItemID.RD_METAL_SPADE_NO_HANDLE); - metalSpadeHead.setHighlightInInventory(true); - metalSpadeHead.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); - ashes = new ItemRequirement("Ashes", ItemID.ASHES); - ashes.setHighlightInInventory(true); - ashes.setTooltip("If you are missing this item pick up a metal spade off the table and use it on the bunsen burner."); - cupricSulfate = new ItemRequirement("Cupric Sulfate", ItemID.RD_CUPRIC_SULPHATE); - cupricSulfate.setHighlightInInventory(true); - cupricSulfate.setTooltip("Take from the shelves on the north side"); - - vialOfLiquid = new ItemRequirement("Vial of Liquid", ItemID.RD_DIHYDROGEN_MONOXIDE); - vialOfLiquid.setHighlightInInventory(true); - vialOfLiquid.setTooltip("Take from the shelf on the north side or the south side."); - - tin = new ItemRequirement("Tin", ItemID.RD_TIN); - tin.setHighlightInInventory(true); - //TODO set tip - - gypsumTin = new ItemRequirement("Tin", ItemID.RD_TINFULL); - gypsumTin.setHighlightInInventory(true); - - gypsum = new ItemRequirement("Gypsum", ItemID.RD_GYPSUM); - gypsum.setHighlightInInventory(true); - - tinKeyPrint = new ItemRequirement("Tin", ItemID.RD_KEYMOULD); - tinKeyPrint.setHighlightInInventory(true); - - tinWithCupricOre = new ItemRequirement("Tin", ItemID.RD_FULL_KEYMOULD_COPPER); - tinWithCupricOre.setHighlightInInventory(true); - - cupricOrePowder = new ItemRequirement("Cupric Ore Powder", ItemID.RD_COPPER_ORE_POWDER); - cupricOrePowder.setHighlightInInventory(true); - - tinOrePowder = new ItemRequirement("Tin Ore Powder", ItemID.RD_TIN_ORE_POWDER); - tinOrePowder.setHighlightInInventory(true); - - tinWithTinOre = new ItemRequirement("Tin", ItemID.RD_FULL_KEYMOULD_UNHEATED); - tinWithTinOre.setHighlightInInventory(true); - // duplicateBronzeKey = new ItemRequirement("Duplicate bronze key", ItemID.PRINCESKEY); - - tinWithAllOre = new ItemRequirement("Tin", ItemID.RD_FULL_KEYMOULD_COMPLETE); - tinWithAllOre.setHighlightInInventory(true); - - chisel = new ItemRequirement("Chisel", ItemID.RD_CHISEL); - chisel.setHighlightInInventory(true); - - bronzeWire = new ItemRequirement("Bronze Wire", ItemID.RD_WIRE); - bronzeWire.setHighlightInInventory(true); - - knife = new ItemRequirement("Knife", ItemID.RD_KNIFE); - knife.setHighlightInInventory(true); - - bronzeKey = new ItemRequirement("Bronze Key", ItemID.RD_PUZZLEROOM_KEY); - } - - private void setupConditions() - { - hasMagnet = new ItemRequirements(new ItemRequirement("Magnet", ItemID.RD_MAGNET)); - hasAceticAcid = new ItemRequirements(new ItemRequirement("Acetic Acid", ItemID.RD_ACETIC_ACID)); - hasOneVialOfLiquid = vialOfLiquid; - hasCupricSulfate = cupricSulfate; - hasGypsum = gypsum; - hasSodiumChloride = new ItemRequirements(new ItemRequirement("Sodium Chloride", ItemID.RD_SODIUM_CHLORIDE)); - hasTin = tin; - hasWire = bronzeWire; - hasShears = new ItemRequirements(new ItemRequirement("Shears", ItemID.RD_SHEARS)); - hasChisel = chisel; - hasNitrousOxide = new ItemRequirements(new ItemRequirement("Nitrous Oxide", ItemID.RD_NITORUS_OXIDE)); - hasTinOrePowder = tinOrePowder; - hasCupricOrePowder = cupricOrePowder; - hasKnife = knife; - hasMetalSpade = metalSpade; - hasMetalSpadeHead = metalSpadeHead; - hasAshes = ashes; - - hasGypsumTin = gypsumTin; - hasTinKeyPrint = tinKeyPrint; - hasTinCupricOre = tinWithCupricOre; - hasTinWithTinOre = tinWithTinOre; - hasTinWithAllOre = tinWithAllOre; - - hasBronzeKey = bronzeKey; - - hasRetrievedThreeVials = new VarbitRequirement(VarbitID.RD_SPARE_WATER, 3); - hasSpadeHeadOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 1); - hasCupricSulfateOnDoor = new VarbitRequirement(VarbitID.RD_REACT_ON_SPADE, 1); - hasVialOfLiquidOnDoor = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 2); - hasFirstDoorOpen = new VarbitRequirement(VarbitID.RD_ROOM6_STONE_DOOR, 3); - finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM6_COMPLETE, 1); - - hasLiquidInTin = new VarbitRequirement(VarbitID.RD_WATER_IN_TIN, 1); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java index e9caf82dd3..55e406002d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/MsHynnAnswerDialogQuizStep.java @@ -26,22 +26,13 @@ package net.runelite.client.plugins.microbot.questhelper.helpers.quests.recruitmentdrive; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; -import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; -import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.api.events.VarbitChanged; -import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.List; - -public class MsHynnAnswerDialogQuizStep extends ConditionalStep +public class MsHynnAnswerDialogQuizStep extends NpcStep { - private QuestStep leaveRoom, talkToMsHynnTerprett; - String[] answers = { "unknown", "10", @@ -51,56 +42,46 @@ public class MsHynnAnswerDialogQuizStep extends ConditionalStep "zero" }; - public MsHynnAnswerDialogQuizStep(QuestHelper questHelper, QuestStep step, Requirement... requirements) + public MsHynnAnswerDialogQuizStep(QuestHelper questHelper) { - super(questHelper, step, requirements); + super(questHelper, NpcID.RD_OBSERVER_ROOM_7, "Talk to Ms Hynn Terprett and answer the riddle."); - talkToMsHynnTerprett = step; - talkToMsHynnTerprett.addDialogSteps( + this.addDialogSteps( "The wolves.", "Bucket A (32 degrees)", "The number of false statements here is three.", - "Zero."); - addSteps(); + "Zero." + ); } - @Override - public void startUp() + private void updateAnswer(int answerID) { - super.startUp(); - int answerID = client.getVarbitValue(VarbitID.RD_TEMPLOCK_2); - if (answerID == 0) + if (answerID == 0 || answerID > answers.length) { + this.setText("Talk to Ms Hynn Terprett and answer the riddle."); return; } - String answer = "The answer is " + answers[answerID] + "."; - talkToMsHynnTerprett.setText("Talk to Ms Hynn Terprett and answer the riddle. " + answer); + var answer = "The answer is " + answers[answerID] + "."; + this.setText("Talk to Ms Hynn Terprett and answer the riddle. " + answer); } @Override - public void onVarbitChanged(VarbitChanged varbitChanged) + public void startUp() { - int answerID = client.getVarbitValue(VarbitID.RD_TEMPLOCK_2); - if (answerID == 0) - { - return; - } - String answer = "The answer is " + answers[answerID] + "."; - talkToMsHynnTerprett.setText("Talk to Ms Hynn Terprett and answer the riddle. " + answer); + super.startUp(); + this.updateAnswer(client.getVarbitValue(VarbitID.RD_TEMPLOCK_2)); } - private void addSteps() + @Override + public void onVarbitChanged(VarbitChanged event) { - VarbitRequirement finishedRoomCondition = new VarbitRequirement(VarbitID.RD_ROOM7_COMPLETE, 1); - leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM7_EXITDOOR, "Leave through the door to enter the portal and continue."); + super.onVarbitChanged(event); - addStep(finishedRoomCondition, leaveRoom); - } + if (event.getVarbitId() != VarbitID.RD_TEMPLOCK_2) + { + return; + } - public List getPanelSteps() - { - List steps = new ArrayList<>(); - steps.add(leaveRoom); - return steps; + this.updateAnswer(event.getValue()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java index 55e2025ffc..d57589e75c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/RecruitmentDrive.java @@ -27,13 +27,14 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.ConfigRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.NoItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.ItemSlots; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -42,7 +43,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -51,89 +61,120 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class RecruitmentDrive extends BasicQuestHelper { - private NoItemRequirement noItemRequirement; - private ZoneRequirement isFirstFloorCastle, isSecondFloorCastle, - isInSirTinleysRoom, isInMsHynnRoom, isInSirKuamsRoom, - isInSirSpishyusRoom, isInSirRenItchood, isInladyTableRoom; - - private ConditionalStep conditionalTalkToSirAmikVarze; - - private QuestStep talkToSirTiffy; - - //Sir Tinsley steps - QuestStep doNothingStep, talkToSirTinley, leaveSirTinleyRoom; + // Mid-quest requirements + NoItemRequirement noItemRequirement; + + // Zones + Zone firstFloorZone; + Zone secondFloorZone; + Zone missCheeversZone; + Zone sirTinleyRoomZone; + Zone msHynnRoomZone; + Zone sirKuamRoomZone; + Zone sirSphishyusZone; + Zone sirRenItchoodZone; + Zone ladyTableZone; + + // Miscellaneous requirements + ZoneRequirement isFirstFloorCastle; + ZoneRequirement isSecondFloorCastle; + ZoneRequirement isInMissCheeversRoom; + ZoneRequirement isInSirTinleysRoom; + ZoneRequirement isInMsHynnRoom; + ZoneRequirement isInSirKuamsRoom; + ZoneRequirement isInSirSpishyusRoom; + ZoneRequirement isInSirRenItchood; + ZoneRequirement isInladyTableRoom; + + // Steps + ConditionalStep cTalkToSirAmikVarze; + ObjectStep climbBottomSteps; + ObjectStep climbSecondSteps; + NpcStep talkToSirAmikVarze; + + ObjectStep climbDownSecondFloorStaircase; + ObjectStep climbDownfirstFloorStaircase; + QuestStep talkToSirTiffy; + + // Sir Tinley steps + PuzzleWrapperStep talkToSirTinley; + PuzzleWrapperStep doNothingStep; + ObjectStep leaveSirTinleyRoom; + ConditionalStep sirTinleyStep; // Sir Kuam Ferentse steps - QuestStep talkToSirKuam, killSirLeye, leaveSirKuamRoom; + NpcStep talkToSirKuam; + NpcStep killSirLeye; + PuzzleWrapperStep pwKillSirLeye; + ObjectStep leaveSirKuamRoom; + ConditionalStep sirKuamStep; // Sir Spishyus - QuestStep moveChickenOnRightToLeft, moveFoxOnRightToLeft, moveChickenOnLeftToRight, - moveGrainOnRightToLeft, moveChickenOnRightToLeftAgain, finishedSpishyusRoom; + QuestStep moveChickenOnRightToLeft; + QuestStep moveFoxOnRightToLeft; + QuestStep moveChickenOnLeftToRight; + QuestStep moveGrainOnRightToLeft; + QuestStep moveChickenOnRightToLeftAgain; + QuestStep leaveSirSpishyusRoom; + ConditionalStep sirSpishyusPuzzle; + ConditionalStep cSirSpishyus; + PuzzleWrapperStep pwSirSpishyusStep; // Sir Ren SirRenItchoodStep sirRenStep; // Lady Table LadyTableStep ladyTableStep; + PuzzleWrapperStep pwLadyTableStep; + ObjectStep leaveLadyTableRoom; + ConditionalStep cLadyTableStep; // Ms Hynn - private QuestStep talkToMsHynnTerprett; - private MsHynnAnswerDialogQuizStep msHynnDialogQuiz; - - // Ms Cheeves - private MsCheevesSetup msCheevesSetup; - - @Override - public Map loadSteps() - { - initializeRequirements(); - - return getSteps(); - } - - private Map getSteps() - { - Map steps = new HashMap<>(); - - steps.put(0, TalkToSirAmikVarze()); - steps.put(1, TalkToSirTiffyInFaladorPark()); + MsHynnAnswerDialogQuizStep msHynnDialogQuiz; + PuzzleWrapperStep pwMsHynnTerprett; + ObjectStep leaveMsHynnTerprettRoom; + ConditionalStep msHynnTerprettStep; - return steps; - } - - @Override - protected void setupRequirements() - { - noItemRequirement = new NoItemRequirement("No items or equipment carried", ItemSlots.ANY_EQUIPPED_AND_INVENTORY); - } + // Miss Cheevers + MissCheeversStep missCheeversStep; + PuzzleWrapperStep pwMissCheeversStep; + ObjectStep leaveMissCheeversRoom; + ConditionalStep cMissCheevers; @Override protected void setupZones() { - Zone firstFloorZone = new Zone(new WorldPoint(2954, 3335, 1), + firstFloorZone = new Zone(new WorldPoint(2954, 3335, 1), new WorldPoint(2966, 3343, 1)); - Zone secondFloorZone = new Zone(new WorldPoint(2955, 3334, 2), + secondFloorZone = new Zone(new WorldPoint(2955, 3334, 2), new WorldPoint(2964, 3342, 2)); - Zone sirTinleyRoomZone = new Zone(new WorldPoint(2471, 4954, 0), + missCheeversZone = new Zone(new WorldPoint(2466, 4936, 0), + new WorldPoint(2480, 4947, 0)); + sirTinleyRoomZone = new Zone(new WorldPoint(2471, 4954, 0), new WorldPoint(2481, 4960, 0)); - Zone msHynnRoomZone = new Zone(new WorldPoint(2446, 4934, 0), + msHynnRoomZone = new Zone(new WorldPoint(2446, 4934, 0), new WorldPoint(2457, 4946, 0)); - Zone sirKuamRoomZone = new Zone(new WorldPoint(2453, 4958, 0), + sirKuamRoomZone = new Zone(new WorldPoint(2453, 4958, 0), new WorldPoint(2466, 4970, 0)); - Zone sirSphishyusZone = new Zone(new WorldPoint(2469, 4968, 0), + sirSphishyusZone = new Zone(new WorldPoint(2469, 4968, 0), new WorldPoint(2492, 4980, 0)); - Zone sirRenItchoodZone = new Zone(new WorldPoint(2438, 4952, 0), + sirRenItchoodZone = new Zone(new WorldPoint(2438, 4952, 0), new WorldPoint(2448, 4962, 0)); - Zone ladyTableZone = new Zone(new WorldPoint(2445, 4974, 0), + ladyTableZone = new Zone(new WorldPoint(2445, 4974, 0), new WorldPoint(2461, 4987, 0)); + } + + @Override + protected void setupRequirements() + { + noItemRequirement = new NoItemRequirement("No items or equipment carried", ItemSlots.ANY_EQUIPPED_AND_INVENTORY); isFirstFloorCastle = new ZoneRequirement(firstFloorZone); isSecondFloorCastle = new ZoneRequirement(secondFloorZone); + isInMissCheeversRoom = new ZoneRequirement(missCheeversZone); isInSirTinleysRoom = new ZoneRequirement(sirTinleyRoomZone); isInMsHynnRoom = new ZoneRequirement(msHynnRoomZone); isInSirKuamsRoom = new ZoneRequirement(sirKuamRoomZone); @@ -142,222 +183,282 @@ protected void setupZones() isInladyTableRoom = new ZoneRequirement(ladyTableZone); } - private QuestStep TalkToSirTiffyInFaladorPark() + public void setupSteps() { - WorldPoint firstFloorStairsPosition = new WorldPoint(2955, 3338, 1); - WorldPoint secondFloorStairsPosition = new WorldPoint(2960, 3339, 2); + climbBottomSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, new WorldPoint(2955, 3339, 0), + "Climb up the stairs to the first floor on the Falador Castle."); - ObjectStep climbDownSecondFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, - secondFloorStairsPosition, "Climb down the stairs from the second floor."); - ObjectStep climbDownfirstFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, - firstFloorStairsPosition, "Climb down the stairs from the first floor."); + climbSecondSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, new WorldPoint(2961, 3339, 1), + "Climb up the stairs to talk to Sir Amik Varze."); + talkToSirAmikVarze = new NpcStep(this, NpcID.SIR_AMIK_VARZE, ""); + talkToSirAmikVarze.addDialogStep("Yes."); - talkToSirTiffy = new NpcStep(this, NpcID.RD_TELEPORTER_GUY, - "Talk to Sir Tiffy Cashien in Falador Park.", noItemRequirement); + climbDownSecondFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, new WorldPoint(2960, 3339, 2), "Climb down the stairs from the second floor."); + climbDownfirstFloorStaircase = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRSTOP, new WorldPoint(2955, 3338, 1), "Climb down the stairs from the first floor."); - ConditionalStep conditionalTalkToSirTiffy = new ConditionalStep(this, talkToSirTiffy); - conditionalTalkToSirTiffy.addStep(isSecondFloorCastle, climbDownSecondFloorStaircase); - conditionalTalkToSirTiffy.addStep(isFirstFloorCastle, climbDownfirstFloorStaircase); + talkToSirTiffy = new NpcStep(this, NpcID.RD_TELEPORTER_GUY, new WorldPoint(2997, 3373, 0), "Talk to Sir Tiffy Cashien in Falador Park.", noItemRequirement); talkToSirTiffy.addDialogStep("Yes, let's go!"); - talkToSirTiffy.addSubSteps(climbDownfirstFloorStaircase, - climbDownSecondFloorStaircase); - getMsCheeves(); + talkToSirTiffy.addSubSteps(climbDownfirstFloorStaircase, climbDownSecondFloorStaircase); - // Testing steps below - conditionalTalkToSirTiffy.addStep(isInSirTinleysRoom, getSirTinley()); - conditionalTalkToSirTiffy.addStep(isInMsHynnRoom, getMsHynnTerprett()); - conditionalTalkToSirTiffy.addStep(isInSirRenItchood, getSirRenItchood()); - conditionalTalkToSirTiffy.addStep(isInladyTableRoom, getLadyTableStep()); - conditionalTalkToSirTiffy.addStep(isInSirSpishyusRoom, getSirSpishyus()); - conditionalTalkToSirTiffy.addStep(isInSirKuamsRoom, getSirKuam()); - - conditionalTalkToSirTiffy.addStep(msCheevesSetup.getIsInMsCheeversRoom(), msCheevesSetup.getConditionalStep()); - return conditionalTalkToSirTiffy; - } + // Testing grounds + // Miss Cheevers + { + missCheeversStep = new MissCheeversStep(this); + pwMissCheeversStep = missCheeversStep.puzzleWrapStepWithDefaultText("Solve Miss Cheevers' puzzle."); + pwMissCheeversStep.conditionToHideInSidebar(new ConfigRequirement(this.getConfig()::solvePuzzles)); - private LadyTableStep getLadyTableStep() - { - this.ladyTableStep = new LadyTableStep(this); - return this.ladyTableStep; - } + leaveMissCheeversRoom = new ObjectStep(this, ObjectID.RD_ROOM6_EXITDOOR, new WorldPoint(2478, 4940, 0), "Leave the room by the second door to enter the portal."); - private QuestStep getSirKuam() - { - VarbitRequirement finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM3_COMPLETE, 1); + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM6_COMPLETE, 1); - talkToSirKuam = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_3, "Talk to Sir Kuam Ferentse to have him spawn Sir Leye."); - killSirLeye = new NpcStep(this, NpcID.RD_COMBAT_NPC_ROOM_3, - "Defeat Sir Leye to win this challenge. You must use the steel warhammer or your barehands to deal the final hit on him.", true); + cMissCheevers = new ConditionalStep(this, pwMissCheeversStep); + cMissCheevers.addStep(and(missCheeversStep.hasFirstDoorOpen, missCheeversStep.bronzeKey, finishedRoom), leaveMissCheeversRoom); + } + + // Sir Tinley + { + talkToSirTinley = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_4, "Talk to Sir Tinley. Once you have pressed continue do not do anything or you will fail.").puzzleWrapStepWithDefaultText("Talk to Sir Tinley and solve his puzzle."); + doNothingStep = new DetailedQuestStep(this, "Press Continue and do nothing. Sir Tinley will eventually talk to you and let you pass.").puzzleWrapStepWithDefaultText("Talk to Sir Tinley and solve his puzzle.").withNoHelpHiddenInSidebar(true); + leaveSirTinleyRoom = new ObjectStep(this, ObjectID.RD_ROOM4_EXITDOOR, "Leave through the portal to continue."); - leaveSirKuamRoom = new ObjectStep(this, ObjectID.RD_ROOM3_EXITDOOR, "Leave through the portal to continue."); - NpcCondition npcCondition = new NpcCondition(NpcID.RD_COMBAT_NPC_ROOM_3); + var waitForCondition = new VarbitRequirement(VarbitID.RD_TEMPLOCK_2, 1, Operation.GREATER_EQUAL); + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM4_COMPLETE, 1); - ConditionalStep sirKuamConditional = new ConditionalStep(this, talkToSirKuam); + talkToSirTinley.addSubSteps(doNothingStep); - sirKuamConditional.addStep(finishedRoom, leaveSirKuamRoom); - sirKuamConditional.addStep(npcCondition, killSirLeye); - return sirKuamConditional; - } + sirTinleyStep = new ConditionalStep(this, talkToSirTinley); + sirTinleyStep.addStep(finishedRoom, leaveSirTinleyRoom); + sirTinleyStep.addStep(waitForCondition, doNothingStep); + } - private void getMsCheeves() - { - msCheevesSetup = new MsCheevesSetup(this); - } + // Ms Hynn Terprett + { + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM7_COMPLETE, 1); - private QuestStep getSirSpishyus() - { - WorldPoint chickenOnLeftPoint = new WorldPoint(2473, 4970, 0); - WorldPoint chickenOnRightPoint = new WorldPoint(2487, 4974, 0); - WorldPoint foxOnRightPoint = new WorldPoint(2485, 4974, 0); - WorldPoint grainOnRightPoint = new WorldPoint(2486, 4974, 0); - - VarbitRequirement foxOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 0); - VarbitRequirement foxOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 1); - VarbitRequirement foxNotOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 1); - VarbitRequirement foxNotOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 0); - VarbitRequirement chickenOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 0); - VarbitRequirement chickenOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 1); - VarbitRequirement chickenNotOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 1); - VarbitRequirement chickenNotOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 0); - VarbitRequirement grainOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 0); - VarbitRequirement grainOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 1); - VarbitRequirement grainNotOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 1); - VarbitRequirement grainNotOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 0); - VarbitRequirement finishedSpishyus = new VarbitRequirement(VarbitID.RD_ROOM1_COMPLETE, 1); - - Conditions foxPickedUp = new Conditions(LogicType.AND, foxNotOnLeftSide, foxNotOnRightSide); - Conditions chickenPickedUp = new Conditions(LogicType.AND, chickenNotOnRightSide, chickenNotOnLeftSide); - Conditions grainPickedUp = new Conditions(LogicType.AND, grainNotOnLeftSide, grainNotOnRightSide); - - moveChickenOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, - getSpishyusPickupText("Chicken", true)); - finishedSpishyusRoom = new ObjectStep(this, ObjectID.RD_ROOM1_EXITDOOR, "Leave through the portal to continue."); - - moveFoxOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_FOX_MULTI, foxOnRightPoint, - getSpishyusPickupText("Fox", true)); - - DetailedQuestStep moveChickenToLeft = new DetailedQuestStep(this, getSpishyusMoveText("Chicken", false)); - moveChickenOnRightToLeft.addSubSteps(moveChickenToLeft); - - DetailedQuestStep moveFoxToLeft = new DetailedQuestStep(this, getSpishyusMoveText("Fox", false)); - moveFoxOnRightToLeft.addSubSteps(moveFoxToLeft); - - moveChickenOnLeftToRight = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI_RIGHT, chickenOnLeftPoint, - getSpishyusPickupText("Chicken", false)); - DetailedQuestStep moveChickenToRight = new DetailedQuestStep(this, getSpishyusMoveText("Chicken", true)); - moveChickenOnLeftToRight.addSubSteps(moveChickenToRight); - - moveGrainOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_GRAIN_MULTI, grainOnRightPoint, - getSpishyusPickupText("Grain", true)); - DetailedQuestStep moveGrainToLeft = new DetailedQuestStep(this, getSpishyusMoveText("Grain", false)); - moveGrainOnRightToLeft.addSubSteps(moveGrainToLeft); - - moveChickenOnRightToLeftAgain = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, - getSpishyusPickupText("Chicken", true)); - DetailedQuestStep moveChickenToLeftAgain = new DetailedQuestStep(this, getSpishyusMoveText("Chicken", false)); - moveChickenOnRightToLeftAgain.addSubSteps(moveChickenToLeftAgain); - - ConditionalStep sirSpishyus = new ConditionalStep(this, moveChickenOnRightToLeft); - sirSpishyus.addStep(finishedSpishyus, finishedSpishyusRoom); - - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnRightSide, grainOnRightSide), moveChickenOnRightToLeft); - sirSpishyus.addStep(new Conditions(chickenPickedUp, foxOnRightSide, grainOnRightSide), moveChickenToLeft); - sirSpishyus.addStep(new Conditions(chickenOnLeftSide, foxOnRightSide, grainOnRightSide), moveFoxOnRightToLeft); - sirSpishyus.addStep(new Conditions(chickenOnLeftSide, foxPickedUp, grainOnRightSide), moveFoxToLeft); - sirSpishyus.addStep(new Conditions(chickenOnLeftSide, foxOnLeftSide, grainOnRightSide), moveChickenOnLeftToRight); - sirSpishyus.addStep(new Conditions(chickenPickedUp, foxOnLeftSide, grainOnRightSide), moveChickenToRight); - - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnLeftSide, grainOnRightSide), moveGrainOnRightToLeft); - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnLeftSide, grainPickedUp), moveGrainToLeft); - sirSpishyus.addStep(new Conditions(chickenOnRightSide, foxOnLeftSide, grainOnLeftSide), moveChickenOnRightToLeftAgain); - sirSpishyus.addStep(new Conditions(chickenPickedUp, foxOnLeftSide, grainOnLeftSide), moveChickenToLeftAgain); - - return sirSpishyus; - } + msHynnDialogQuiz = new MsHynnAnswerDialogQuizStep(this); + pwMsHynnTerprett = msHynnDialogQuiz.puzzleWrapStepWithDefaultText("Talk to Ms Hynn Terprett and answer the riddle."); - private String getSpishyusPickupText(String itemName, boolean moveRightToLeft) - { - String firstSide = moveRightToLeft ? "east" : "west"; - String secondSide = moveRightToLeft ? "west" : "east"; - return "Pickup the " + itemName + " on the " + firstSide + " and move it to the " - + secondSide + " side by crossing the bridge"; - } + leaveMsHynnTerprettRoom = new ObjectStep(this, ObjectID.RD_ROOM7_EXITDOOR, "Leave through the door to enter the portal and continue."); - private String getSpishyusMoveText(String itemName, boolean rightSide) - { - String dropSide = rightSide ? "east" : "west"; - return "Cross the bridge to the " + dropSide + " and drop the " + itemName + " from your equipped items."; - } + msHynnTerprettStep = new ConditionalStep(this, pwMsHynnTerprett); + msHynnTerprettStep.addStep(finishedRoom, leaveMsHynnTerprettRoom); + } - private QuestStep getSirRenItchood() - { - NpcStep talkToSirRenItchood = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_5, "Talk to Sir Ren Itchood to receive the clue."); - talkToSirRenItchood.addDialogSteps("Can I have the clue for the door?"); + // Sir Ren Itchood + { + var talkToSirRenItchood = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_5, "Talk to Sir Ren Itchood to receive the clue."); + talkToSirRenItchood.addDialogSteps("Can I have the clue for the door?"); - sirRenStep = new SirRenItchoodStep(this, talkToSirRenItchood); - return sirRenStep; - } + sirRenStep = new SirRenItchoodStep(this, talkToSirRenItchood); + } - private QuestStep getSirTinley() - { - talkToSirTinley = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_4, - "Talk to Sir Tinley. \n Once you have pressed continue do not do anything or you will fail."); - doNothingStep = new DetailedQuestStep(this, - "Press Continue and do nothing. Sir Tinley will eventually talk to you and let you pass."); - leaveSirTinleyRoom = new ObjectStep(this, ObjectID.RD_ROOM4_EXITDOOR, "Leave through the portal to continue."); + // Lady Table + { + ladyTableStep = new LadyTableStep(this); + pwLadyTableStep = ladyTableStep.puzzleWrapStepWithDefaultText("Solve Lady Table's puzzle."); + + leaveLadyTableRoom = new ObjectStep(this, ObjectID.RD_ROOM2_EXITDOOR, "Leave through the door to enter the portal and continue."); + + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM2_COMPLETE, 1); + + cLadyTableStep = new ConditionalStep(this, pwLadyTableStep); + cLadyTableStep.addStep(finishedRoom, leaveLadyTableRoom); + } + + // Sir Spishyus + { + var chickenOnLeftPoint = new WorldPoint(2473, 4970, 0); + var chickenOnRightPoint = new WorldPoint(2487, 4974, 0); + var foxOnRightPoint = new WorldPoint(2485, 4974, 0); + var grainOnRightPoint = new WorldPoint(2486, 4974, 0); + + var foxOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 0); + var foxOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 1); + var foxNotOnRightSide = new VarbitRequirement(VarbitID.RD_FOXLEFT, 1); + var foxNotOnLeftSide = new VarbitRequirement(VarbitID.RD_FOXRIGHT, 0); + var chickenOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 0); + var chickenOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 1); + var chickenNotOnRightSide = new VarbitRequirement(VarbitID.RD_CHICKLEFT, 1); + var chickenNotOnLeftSide = new VarbitRequirement(VarbitID.RD_CHICKRIGHT, 0); + var grainOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 0); + var grainOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 1); + var grainNotOnRightSide = new VarbitRequirement(VarbitID.RD_GRAINLEFT, 1); + var grainNotOnLeftSide = new VarbitRequirement(VarbitID.RD_GRAINRIGHT, 0); + var finishedSpishyus = new VarbitRequirement(VarbitID.RD_ROOM1_COMPLETE, 1); + + var westSide = new Zone(new WorldPoint(2472, 4976, 0), new WorldPoint(2479, 4968, 0)); + var playerOnWestSide = new ZoneRequirement(westSide); + var playerOnEastSide = not(playerOnWestSide); + + var foxPickedUp = and(foxNotOnLeftSide, foxNotOnRightSide); + var chickenPickedUp = and(chickenNotOnRightSide, chickenNotOnLeftSide); + var grainPickedUp = and(grainNotOnLeftSide, grainNotOnRightSide); + + moveChickenOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, getSpishyusPickupText("Chicken", true)).puzzleWrapStep(true); + + moveFoxOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_FOX_MULTI, foxOnRightPoint, getSpishyusPickupText("Fox", true)).puzzleWrapStep(true); + + var moveChickenToLeft = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Chicken", false)); + moveChickenToLeft.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnRightToLeft).getSolvingStep().addSubSteps(moveChickenToLeft); + + var moveFoxToWest = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Fox", false)); + moveFoxToWest.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveFoxOnRightToLeft).getSolvingStep().addSubSteps(moveFoxToWest); + + moveChickenOnLeftToRight = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI_RIGHT, chickenOnLeftPoint, getSpishyusPickupText("Chicken", false)).puzzleWrapStep(true); + var moveChickenToRight = new ObjectStep(this, ObjectID.RD_BRIDGE_RIGHT, new WorldPoint(2477, 4972, 0), getSpishyusMoveText("Chicken", true)); + moveChickenToRight.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnLeftToRight).getSolvingStep().addSubSteps(moveChickenToRight); + + moveGrainOnRightToLeft = new ObjectStep(this, ObjectID.RD_ROOM2_GRAIN_MULTI, grainOnRightPoint, getSpishyusPickupText("Grain", true)).puzzleWrapStep(true); + var moveGrainToLeft = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Grain", false)); + moveGrainToLeft.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveGrainOnRightToLeft).getSolvingStep().addSubSteps(moveGrainToLeft); + + moveChickenOnRightToLeftAgain = new ObjectStep(this, ObjectID.RD_ROOM2_CHICKEN_MULTI, chickenOnRightPoint, getSpishyusPickupText("Chicken", true)).puzzleWrapStep(true); + var moveChickenToLeftAgain = new ObjectStep(this, ObjectID.RD_BRIDGE_LEFT, new WorldPoint(2483, 4972, 0), getSpishyusMoveText("Chicken", false)); + moveChickenToLeftAgain.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnRightToLeftAgain).getSolvingStep().addSubSteps(moveChickenToLeftAgain); + + sirSpishyusPuzzle = new ConditionalStep(this, moveChickenOnRightToLeft, "Solve Sir Spishyus' riddle."); - VarbitRequirement waitForCondition = new VarbitRequirement(VarbitID.RD_TEMPLOCK_2, 1, Operation.GREATER_EQUAL); - VarbitRequirement finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM4_COMPLETE, 1); + var dropChickenWest = new DetailedQuestStep(this, "Drop the Chicken on the west side from your equipped items."); + ((PuzzleWrapperStep) moveChickenOnRightToLeft).getSolvingStep().addSubSteps(dropChickenWest); + + // 1. Move Chicken from east to west + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnRightSide, grainOnRightSide), moveChickenOnRightToLeft); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnRightSide, grainOnRightSide, playerOnEastSide), moveChickenToLeft); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnRightSide, grainOnRightSide), dropChickenWest); - ConditionalStep sirTinleyStep = new ConditionalStep(this, talkToSirTinley); - sirTinleyStep.addStep(finishedRoom, leaveSirTinleyRoom); - sirTinleyStep.addStep(waitForCondition, doNothingStep); + var moveToEastSide1 = new ObjectStep(this, ObjectID.RD_BRIDGE_RIGHT, new WorldPoint(2477, 4972, 0), "Cross the bridge to the east side."); + moveToEastSide1.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveFoxOnRightToLeft).getSolvingStep().addSubSteps(moveToEastSide1); - return sirTinleyStep; + var dropFoxWest = new DetailedQuestStep(this, "Drop the Fox on the west side from your equipped items."); + ((PuzzleWrapperStep) moveFoxOnRightToLeft).getSolvingStep().addSubSteps(dropFoxWest); + + // 2. Return to east side, then move Fox from east to west + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxOnRightSide, grainOnRightSide, playerOnWestSide), moveToEastSide1); + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxOnRightSide, grainOnRightSide), moveFoxOnRightToLeft); + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxPickedUp, grainOnRightSide, playerOnEastSide), moveFoxToWest); + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxPickedUp, grainOnRightSide), dropFoxWest); + + var dropChickenEast = new DetailedQuestStep(this, "Drop the Chicken on the east side from your equipped items."); + ((PuzzleWrapperStep) moveChickenOnLeftToRight).getSolvingStep().addSubSteps(dropChickenEast); + + // 3. Move chicken from west to east + sirSpishyusPuzzle.addStep(and(chickenOnLeftSide, foxOnLeftSide, grainOnRightSide), moveChickenOnLeftToRight); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnRightSide, playerOnWestSide), moveChickenToRight); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnRightSide), dropChickenEast); + + var dropGrainWest = new DetailedQuestStep(this, "Drop the Grain on the west side from your equipped items."); + ((PuzzleWrapperStep) moveGrainOnRightToLeft).getSolvingStep().addSubSteps(dropGrainWest); + + // 4. Move grain from east to west + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainOnRightSide), moveGrainOnRightToLeft); + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainPickedUp, playerOnEastSide), moveGrainToLeft); + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainPickedUp), dropGrainWest); + + var moveToEastSide2 = new ObjectStep(this, ObjectID.RD_BRIDGE_RIGHT, new WorldPoint(2477, 4972, 0), "Cross the bridge to the east side."); + moveToEastSide2.setForceClickboxHighlight(true); + ((PuzzleWrapperStep) moveChickenOnRightToLeftAgain).getSolvingStep().addSubSteps(moveToEastSide2); + + var dropChickenWest2 = new DetailedQuestStep(this, "Drop the Chicken on the west side from your equipped items."); + ((PuzzleWrapperStep) moveChickenOnRightToLeftAgain).getSolvingStep().addSubSteps(dropChickenWest2); + + // 5. Cross the bridge to the east, then move the chicken from east to west + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainOnLeftSide, playerOnWestSide), moveToEastSide2); + sirSpishyusPuzzle.addStep(and(chickenOnRightSide, foxOnLeftSide, grainOnLeftSide), moveChickenOnRightToLeftAgain); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnLeftSide, playerOnEastSide), moveChickenToLeftAgain); + sirSpishyusPuzzle.addStep(and(chickenPickedUp, foxOnLeftSide, grainOnLeftSide), dropChickenWest2); + + pwSirSpishyusStep = sirSpishyusPuzzle.puzzleWrapStepWithDefaultText("Solve Sir Spishyus' riddle."); + pwSirSpishyusStep.conditionToHideInSidebar(new ConfigRequirement(this.getConfig()::solvePuzzles)); + + leaveSirSpishyusRoom = new ObjectStep(this, ObjectID.RD_ROOM1_EXITDOOR, "Leave through the portal to continue."); + + cSirSpishyus = new ConditionalStep(this, pwSirSpishyusStep); + cSirSpishyus.addStep(finishedSpishyus, leaveSirSpishyusRoom); + } + + // Sir Kuam + { + var finishedRoom = new VarbitRequirement(VarbitID.RD_ROOM3_COMPLETE, 1); + + talkToSirKuam = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_3, "Talk to Sir Kuam Ferentse to have him spawn Sir Leye."); + killSirLeye = new NpcStep(this, NpcID.RD_COMBAT_NPC_ROOM_3, "Defeat Sir Leye to win this challenge. You must use the steel warhammer or your bare hands to deal the final hit on him.", true); + pwKillSirLeye = killSirLeye.puzzleWrapStepWithDefaultText("Defeat Sir Leye to win this challenge."); + + leaveSirKuamRoom = new ObjectStep(this, ObjectID.RD_ROOM3_EXITDOOR, "Leave through the portal to continue."); + var npcCondition = new NpcCondition(NpcID.RD_COMBAT_NPC_ROOM_3); + + sirKuamStep = new ConditionalStep(this, talkToSirKuam); + sirKuamStep.addStep(finishedRoom, leaveSirKuamRoom); + sirKuamStep.addStep(npcCondition, pwKillSirLeye); + } } - private QuestStep getMsHynnTerprett() + @Override + public Map loadSteps() { - talkToMsHynnTerprett = new NpcStep(this, NpcID.RD_OBSERVER_ROOM_7, - "Talk to Ms Hynn Terprett and answer the riddle."); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + cTalkToSirAmikVarze = new ConditionalStep(this, climbBottomSteps, "Talk to Sir Amik Varze."); + cTalkToSirAmikVarze.addStep(isFirstFloorCastle, climbSecondSteps); + cTalkToSirAmikVarze.addStep(isSecondFloorCastle, talkToSirAmikVarze); + steps.put(0, cTalkToSirAmikVarze); + + var cTestingGrounds = new ConditionalStep(this, talkToSirTiffy); + cTestingGrounds.addStep(isSecondFloorCastle, climbDownSecondFloorStaircase); + cTestingGrounds.addStep(isFirstFloorCastle, climbDownfirstFloorStaircase); + + // Testing steps below + cTestingGrounds.addStep(isInMissCheeversRoom, cMissCheevers); + cTestingGrounds.addStep(isInSirTinleysRoom, sirTinleyStep); + cTestingGrounds.addStep(isInMsHynnRoom, msHynnTerprettStep); + cTestingGrounds.addStep(isInSirRenItchood, sirRenStep); + cTestingGrounds.addStep(isInladyTableRoom, cLadyTableStep); + cTestingGrounds.addStep(isInSirSpishyusRoom, cSirSpishyus); + cTestingGrounds.addStep(isInSirKuamsRoom, sirKuamStep); + + steps.put(1, cTestingGrounds); - msHynnDialogQuiz = new MsHynnAnswerDialogQuizStep(this, talkToMsHynnTerprett); - return msHynnDialogQuiz; + return steps; } - private QuestStep TalkToSirAmikVarze() + private String getSpishyusPickupText(String itemName, boolean moveRightToLeft) { - WorldPoint bottomStairsPosition = new WorldPoint(2955, 3339, 0); - WorldPoint secondStairsPosition = new WorldPoint(2961, 3339, 1); - ObjectStep climbBottomSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, bottomStairsPosition, - "Climb up the stairs to the first floor on the Falador Castle."); + String firstSide = moveRightToLeft ? "east" : "west"; + String secondSide = moveRightToLeft ? "west" : "east"; + return "Pick up the " + itemName + " on the " + firstSide + " and move it to the " + + secondSide + " side by crossing the bridge"; + } - ObjectStep climbSecondSteps = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_SPIRALSTAIRS, secondStairsPosition, - "Climb up the stairs to talk to Sir Amik Vaze."); - NpcStep talkToSirAmikVarze = new NpcStep(this, NpcID.SIR_AMIK_VARZE, ""); - talkToSirAmikVarze.addDialogStep("Yes please"); - - conditionalTalkToSirAmikVarze = new ConditionalStep(this, climbBottomSteps, - "Talk to Sir Amik Varze."); - conditionalTalkToSirAmikVarze.addStep(isFirstFloorCastle, climbSecondSteps); - conditionalTalkToSirAmikVarze.addStep(isSecondFloorCastle, talkToSirAmikVarze); - conditionalTalkToSirAmikVarze.addSubSteps(climbSecondSteps, climbBottomSteps, talkToSirAmikVarze); - return conditionalTalkToSirAmikVarze; + private String getSpishyusMoveText(String itemName, boolean rightSide) + { + String dropSide = rightSide ? "east" : "west"; + return "Cross the bridge to the " + dropSide + " and drop the " + itemName + " from your equipped items."; } @Override - public List getCombatRequirements() + public List getGeneralRequirements() { - return Collections.singletonList("Sir Leye (level 20) with no items"); + return List.of( + new QuestRequirement(QuestHelperQuest.BLACK_KNIGHTS_FORTRESS, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED) + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(new QuestRequirement(QuestHelperQuest.BLACK_KNIGHTS_FORTRESS, QuestState.FINISHED)); - reqs.add(new QuestRequirement(QuestHelperQuest.DRUIDIC_RITUAL, QuestState.FINISHED)); - return reqs; + return List.of( + "Sir Leye (level 20) with no items" + ); } @Override @@ -369,69 +470,87 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Arrays.asList( - new ExperienceReward(Skill.PRAYER, 1000), - new ExperienceReward(Skill.AGILITY, 1000), - new ExperienceReward(Skill.HERBLORE, 1000)); + return List.of( + new ExperienceReward(Skill.PRAYER, 1000), + new ExperienceReward(Skill.AGILITY, 1000), + new ExperienceReward(Skill.HERBLORE, 1000) + ); } @Override public List getItemRewards() { - return Arrays.asList( - new ItemReward("Initiate Helm", ItemID.BASIC_TK_HELM, 1), - new ItemReward("Coins", ItemID.COINS, 3000)); + return List.of( + new ItemReward("Initiate Helm", ItemID.BASIC_TK_HELM, 1), + new ItemReward("Coins", ItemID.COINS, 3000) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Ability to respawn in Falador"), - new UnlockReward("Access to Initiate Armor")); + return List.of( + new UnlockReward("Ability to respawn in Falador"), + new UnlockReward("Access to Initiate Armor") + ); } @Override public List getPanels() { - List steps = new ArrayList<>(); - - PanelDetails startingPanel = new PanelDetails("Starting out", - new ArrayList<>(Collections.singletonList(conditionalTalkToSirAmikVarze))); - - PanelDetails testing = new PanelDetails("Start the testing", - Collections.singletonList(talkToSirTiffy), noItemRequirement); - - PanelDetails sirTinleysRoom = new PanelDetails("Sir Tinley", - Arrays.asList(talkToSirTinley, doNothingStep, leaveSirTinleyRoom)); - - List hynnSteps = new ArrayList<>(); - hynnSteps.add(talkToMsHynnTerprett); - hynnSteps.addAll(msHynnDialogQuiz.getPanelSteps()); - PanelDetails msHynnsRoom = new PanelDetails("Ms Hynn Terprett", hynnSteps); - - PanelDetails sirKuamRoom = new PanelDetails("Sir Kuam", - Arrays.asList(talkToSirKuam, killSirLeye, leaveSirKuamRoom)); - - PanelDetails sirSpishyusRoom = new PanelDetails("Sir Spishyus", - Arrays.asList(moveChickenOnRightToLeft, moveFoxOnRightToLeft, - moveChickenOnLeftToRight, moveGrainOnRightToLeft, moveChickenOnRightToLeftAgain)); - - PanelDetails sirRensRoom = new PanelDetails("Sir Ren Itchood", sirRenStep.getPanelSteps()); - - PanelDetails missCheeversRoom = new PanelDetails("Mis Cheevers", msCheevesSetup.GetPanelSteps()); - - PanelDetails ladyTable = new PanelDetails("Lady Table", ladyTableStep.getPanelSteps()); - - steps.add(startingPanel); - steps.add(testing); - steps.add(sirKuamRoom); - steps.add(sirSpishyusRoom); - steps.add(msHynnsRoom); - steps.add(sirTinleysRoom); - steps.add(sirRensRoom); - steps.add(missCheeversRoom); - steps.add(ladyTable); - return steps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting out", List.of( + cTalkToSirAmikVarze + ))); + + sections.add(new PanelDetails("Start the testing", List.of( + talkToSirTiffy + ), List.of( + noItemRequirement + ))); + + sections.add(new PanelDetails("Sir Tinley", List.of( + talkToSirTinley, + doNothingStep, + leaveSirTinleyRoom + ))); + + sections.add(new PanelDetails("Ms. Hynn Terprett", List.of( + pwMsHynnTerprett, + leaveMsHynnTerprettRoom + ))); + + sections.add(new PanelDetails("Sir Kuam Ferentse", List.of( + talkToSirKuam, + pwKillSirLeye, + leaveSirKuamRoom + ))); + + sections.add(new PanelDetails("Sir Spishyus", List.of( + pwSirSpishyusStep, + moveChickenOnRightToLeft, + moveFoxOnRightToLeft, + moveChickenOnLeftToRight, + moveGrainOnRightToLeft, + moveChickenOnRightToLeftAgain, + leaveSirSpishyusRoom + ))); + + sections.add(new PanelDetails("Sir Ren Itchood", + sirRenStep.getPanelSteps() + )); + + var missCheeversSection = new PanelDetails("Miss Cheevers", pwMissCheeversStep); + missCheeversSection.addSteps(missCheeversStep.getPanelSteps()); + missCheeversSection.addSteps(leaveMissCheeversRoom); + sections.add(missCheeversSection); + + sections.add(new PanelDetails("Lady Table", List.of( + pwLadyTableStep, + leaveLadyTableRoom + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java index b7c1e17cf3..1ef8b3219f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/recruitmentdrive/SirRenItchoodStep.java @@ -27,31 +27,29 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.List; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.List; - public class SirRenItchoodStep extends ConditionalStep { - private String answer = null; - - private String[] answers = { + private final String[] answers = { "NULL", "TIME", "FISH", "RAIN", "BITE", "MEAT", "LAST" }; + private final QuestStep talkToRen; - private Requirement answerWidgetOpen; - private DoorPuzzle enterDoorcode; - private QuestStep talkToRen, openAnswerWidget, leaveRoom; - private VarbitRequirement finishedRoomCondition; + private DoorPuzzle enterDoorCode; + private PuzzleWrapperStep pwEnterDoorCode; + private QuestStep tryOpenDoor; + private QuestStep leaveRoom; public SirRenItchoodStep(QuestHelper questHelper, QuestStep step, Requirement... requirements) { @@ -71,42 +69,48 @@ public void startUp() return; } String answer = answers[answerID]; - enterDoorcode.updateWord(answer); + enterDoorCode.updateWord(answer); } @Override public void onVarbitChanged(VarbitChanged varbitChanged) { super.onVarbitChanged(varbitChanged); - int answerID = client.getVarbitValue(VarbitID.RD_TEMPLOCK_1); + + if (varbitChanged.getVarbitId() != VarbitID.RD_TEMPLOCK_1) + { + return; + } + var answerID = varbitChanged.getValue(); if (answerID == 0) { return; } - String answer = answers[answerID]; - enterDoorcode.updateWord(answer); + var answer = answers[answerID]; + enterDoorCode.updateWord(answer); } private void addRenSteps() { - finishedRoomCondition = new VarbitRequirement(VarbitID.RD_ROOM5_COMPLETE, 1); - openAnswerWidget = new ObjectStep(questHelper, ObjectID.RD_ROOM5_EXITDOOR, "Open the door to be prompted to enter a code."); - answerWidgetOpen = new WidgetTextRequirement(285, 55, "Combination Lock Door"); - enterDoorcode = new DoorPuzzle(questHelper, "NONE"); + var finishedRoomCondition = new VarbitRequirement(VarbitID.RD_ROOM5_COMPLETE, 1); + var answerWidgetOpen = new WidgetTextRequirement(InterfaceID.RdCombolock.RDCOMBOLOCK, "Combination Lock Door"); + tryOpenDoor = new ObjectStep(questHelper, ObjectID.RD_ROOM5_EXITDOOR, "Open the door to be prompted to enter a code."); + enterDoorCode = new DoorPuzzle(questHelper, "NONE"); + pwEnterDoorCode = enterDoorCode.puzzleWrapStepWithDefaultText("Solve the door combination lock using the hints from Sir Ren Itchood."); leaveRoom = new ObjectStep(questHelper, ObjectID.RD_ROOM5_EXITDOOR, "Leave through the door to enter the portal and continue."); addStep(finishedRoomCondition, leaveRoom); - addStep(new Conditions(answerWidgetOpen), enterDoorcode); - addStep(null, openAnswerWidget); + addStep(answerWidgetOpen, pwEnterDoorCode); + addStep(null, tryOpenDoor); } public List getPanelSteps() { - List steps = new ArrayList<>(); - steps.add(talkToRen); - steps.add(openAnswerWidget); - steps.add(enterDoorcode); - steps.add(leaveRoom); - return steps; + return List.of( + talkToRen, + tryOpenDoor, + pwEnterDoorCode, + leaveRoom + ); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java index 8ef44238f4..a3429528a9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/romeoandjuliet/RomeoAndJuliet.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; @@ -34,17 +35,14 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; public class RomeoAndJuliet extends BasicQuestHelper { @@ -151,7 +149,7 @@ public Map loadSteps() steps.put(50, bringPotionToJuliet); var cFinishQuest = new ConditionalStep(this, finishQuest); - cFinishQuest.addStep(inJulietRoom, goDownstairsToFinishQuest); + giveLetterToRomeo.addStep(inJulietRoom, goDownstairsToFinishQuest); steps.put(60, cFinishQuest); return steps; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java index c09884adb5..ec48d061e4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/runemysteries/RuneMysteries.java @@ -29,6 +29,7 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,19 +41,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class RuneMysteries extends BasicQuestHelper { // Recommended items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java index c9f9666182..a72acc34f3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scorpioncatcher/ScorpionCatcher.java @@ -6,19 +6,27 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -26,71 +34,82 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class ScorpionCatcher extends BasicQuestHelper { - ItemRequirement dustyKey, jailKey, scorpionCageMissingTaverley, scorpionCageMissingMonastery, scorpionCageEmptyOrTaverley, scorpionCageTaverleyAndMonastery, scorpionCageFull, food, - antiDragonShield, antiPoison, teleRunesFalador, gamesNecklace, gloryOrCombatBracelet, camelotTeleport; - QuestRequirement fairyRingAccess; - Zone sorcerersTower3, sorcerersTower2, sorcerersTower1, taverleyDungeon, deepTaverleyDungeon1, deepTaverleyDungeon2, deepTaverleyDungeon3, deepTaverleyDungeon4, - jailCell, taverleyScorpionRoom, upstairsMonastery, barbarianOutpost; - Requirement has70Agility, has80Agility, inTaverleyDungeon, inDeepTaverleyDungeon, inJailCell, inSorcerersTower1, inSorcerersTower2, - inSorcerersTower3, inTaverleyScorpionRoom, inUpstairsMonastery, inBarbarianOutpost, jailKeyNearby; - QuestStep speakToThormac, speakToSeer1, enterTaverleyDungeon, goThroughPipe, goOverStrangeFloor, killJailerForKey, - getDustyFromAdventurer, enterDeeperTaverley, pickUpJailKey, - searchOldWall, catchTaverleyScorpion, sorcerersTowerLadder0, sorcerersTowerLadder1, sorcerersTowerLadder2, enterMonastery, catchMonasteryScorpion, - catchOutpostScorpion, enterOutpost, returnToThormac; - + // Required items + ItemRequirement dustyKey; + + // Recommended items + ItemRequirement antiDragonShield; + ItemRequirement antiPoison; + ItemRequirement food; + ItemRequirement teleRunesFalador; + ItemRequirement camelotTeleport; + ItemRequirement gamesNecklace; + ItemRequirement gloryOrCombatBracelet; + + // Mid-quest item requirements + ItemRequirement jailKey; + ItemRequirement scorpionCageMissingTaverley; + ItemRequirement scorpionCageMissingMonastery; + ItemRequirement scorpionCageEmptyOrTaverley; + ItemRequirement scorpionCageTaverleyAndMonastery; + ItemRequirement scorpionCageFull; + + // Zones + Zone sorcerersTower3; + Zone sorcerersTower2; + Zone sorcerersTower1; + Zone taverleyDungeon; + Zone deepTaverleyDungeon1; + Zone deepTaverleyDungeon2; + Zone deepTaverleyDungeon3; + Zone deepTaverleyDungeon4; + Zone jailCell; + Zone taverleyScorpionRoom; + Zone upstairsMonastery; + Zone barbarianOutpost; + + // Miscellaneous requirements + SkillRequirement has70Agility; + SkillRequirement has80Agility; + ZoneRequirement inTaverleyDungeon; + ZoneRequirement inDeepTaverleyDungeon; + ZoneRequirement inJailCell; + ZoneRequirement inSorcerersTower1; + ZoneRequirement inSorcerersTower2; + ZoneRequirement inSorcerersTower3; + ZoneRequirement inTaverleyScorpionRoom; + ZoneRequirement inUpstairsMonastery; + ZoneRequirement inBarbarianOutpost; + ItemOnTileRequirement jailKeyNearby; + + // Steps + ObjectStep sorcerersTowerLadder0; + ObjectStep sorcerersTowerLadder1; + ObjectStep sorcerersTowerLadder2; + ConditionalStep goToTopOfTower; + + ConditionalStep beginQuest; + NpcStep speakToThormac; + + NpcStep speakToSeer1; + QuestStep enterTaverleyDungeon; + ObjectStep goThroughPipe; + ObjectStep goOverStrangeFloor; + NpcStep killJailerForKey; + NpcStep getDustyFromAdventurer; + ObjectStep enterDeeperTaverley; + ItemStep pickUpJailKey; + ObjectStep searchOldWall; + NpcStep catchTaverleyScorpion; + ObjectStep enterMonastery; + NpcStep catchMonasteryScorpion; + NpcStep catchOutpostScorpion; + ObjectStep enterOutpost; + NpcStep returnToThormac; ConditionalStep finishQuest; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - - Map steps = new HashMap<>(); - - ConditionalStep goToTopOfTower = new ConditionalStep(this, sorcerersTowerLadder0); - goToTopOfTower.addStep(inSorcerersTower1, sorcerersTowerLadder1); - goToTopOfTower.addStep(inSorcerersTower2, sorcerersTowerLadder2); - - ConditionalStep beginQuest = new ConditionalStep(this, goToTopOfTower); - beginQuest.addStep(inSorcerersTower3, speakToThormac); - - finishQuest = new ConditionalStep(this, goToTopOfTower, - "Return to Thormac to finish the quest.", scorpionCageFull); - finishQuest.addStep(inSorcerersTower3, returnToThormac); - - ConditionalStep goGetTaverleyScorpion = new ConditionalStep(this, enterTaverleyDungeon); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyScorpionRoom), catchTaverleyScorpion); - goGetTaverleyScorpion.addStep(new Conditions(inDeepTaverleyDungeon), searchOldWall); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, has80Agility), goOverStrangeFloor); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, has70Agility), goThroughPipe); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, dustyKey), enterDeeperTaverley); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, new Conditions(LogicType.OR, inJailCell, jailKey)), getDustyFromAdventurer); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon, jailKeyNearby), pickUpJailKey); - goGetTaverleyScorpion.addStep(new Conditions(inTaverleyDungeon), killJailerForKey); - - ConditionalStep scorpions = new ConditionalStep(this, finishQuest); - scorpions.addStep(scorpionCageMissingTaverley.alsoCheckBank(), goGetTaverleyScorpion); - - scorpions.addStep(new Conditions(scorpionCageMissingMonastery, inUpstairsMonastery), catchMonasteryScorpion); - scorpions.addStep(scorpionCageMissingMonastery.alsoCheckBank(), enterMonastery); - - scorpions.addStep(new Conditions(scorpionCageTaverleyAndMonastery, inBarbarianOutpost), catchOutpostScorpion); - scorpions.addStep(scorpionCageTaverleyAndMonastery.alsoCheckBank(), enterOutpost); - - steps.put(0, beginQuest); - steps.put(1, speakToSeer1); - steps.put(2, scorpions); - steps.put(3, scorpions); - - return steps; - } - @Override protected void setupZones() { @@ -114,8 +133,13 @@ protected void setupZones() @Override protected void setupRequirements() { - dustyKey = new KeyringRequirement("Dusty Key", configManager, KeyringCollection.DUSTY_KEY).isNotConsumed(); + has70Agility = new SkillRequirement(Skill.AGILITY, 70, true); + has80Agility = new SkillRequirement(Skill.AGILITY, 80, true); + + dustyKey = new KeyringRequirement("Dusty Key", KeyringCollection.DUSTY_KEY).isNotConsumed(); dustyKey.setTooltip("Not needed if you have level 70 Agility, can be obtained during the quest"); + dustyKey.setConditionToHide(has70Agility); + jailKey = new ItemRequirement("Jail Key", ItemID.JAIL_KEY); scorpionCageMissingTaverley = new ItemRequirement("Scorpion Cage", ItemID.SCORPIONCAGEEMPTY); @@ -143,15 +167,6 @@ protected void setupRequirements() gamesNecklace = new ItemRequirement("Games Necklace", ItemCollections.GAMES_NECKLACES); gloryOrCombatBracelet = new ItemRequirement("A charged glory or a combat bracelet", ItemCollections.AMULET_OF_GLORIES); gloryOrCombatBracelet.addAlternates(ItemCollections.COMBAT_BRACELETS); - fairyRingAccess = new QuestRequirement(QuestHelperQuest.FAIRYTALE_II__CURE_A_QUEEN, QuestState.IN_PROGRESS, "Fairy ring access"); - fairyRingAccess.setTooltip(QuestHelperQuest.FAIRYTALE_II__CURE_A_QUEEN.getName() + " is required to at least be started in order to use fairy rings"); - - } - - private void setupConditions() - { - has70Agility = new SkillRequirement(Skill.AGILITY, 70, true); - has80Agility = new SkillRequirement(Skill.AGILITY, 80, true); inSorcerersTower1 = new ZoneRequirement(sorcerersTower1); inSorcerersTower2 = new ZoneRequirement(sorcerersTower2); @@ -170,34 +185,26 @@ private void setupConditions() private void setupSteps() { - speakToThormac = new NpcStep(this, NpcID.THORMAC, new WorldPoint(2702, 3405, 3), "Speak to Thormac on the top floor of the Sorcerer's Tower south of Seer's Village."); + sorcerersTowerLadder0 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2701, 3408, 0), "Climb to the top of the Sorcerer's Tower south of Seers' Village."); + sorcerersTowerLadder1 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2704, 3403, 1), "Climb to the top of the Sorcerer's Tower south of Seers' Village."); + sorcerersTowerLadder2 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2699, 3405, 2), "Climb to the top of the Sorcerer's Tower south of Seers' Village."); + + goToTopOfTower = new ConditionalStep(this, sorcerersTowerLadder0); + goToTopOfTower.addStep(inSorcerersTower1, sorcerersTowerLadder1); + goToTopOfTower.addStep(inSorcerersTower2, sorcerersTowerLadder2); + + speakToThormac = new NpcStep(this, NpcID.THORMAC, new WorldPoint(2702, 3405, 3), ""); speakToThormac.addDialogStep("What do you need assistance with?"); - speakToThormac.addDialogStep("So how would I go about catching them then?"); - speakToThormac.addDialogStep("Ok, I will do it then"); - - sorcerersTowerLadder0 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2701, 3408, 0), - "Climb to the top of the Sorcerer's Tower south of Seers' Village."); - sorcerersTowerLadder1 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2704, 3403, 1), - "Climb to the top of the Sorcerer's Tower south of Seers' Village."); - sorcerersTowerLadder2 = new ObjectStep(this, ObjectID.LADDER, new WorldPoint(2699, 3405, 2), - "Climb to the top of the Sorcerer's Tower south of Seers' Village."); - speakToThormac.addSubSteps(sorcerersTowerLadder0, sorcerersTowerLadder1, sorcerersTowerLadder2); - - speakToSeer1 = new NpcStep(this, NpcID.SEER, new WorldPoint(2710, 3484, 0), - "Speak to a seer in Seer's Village."); + speakToThormac.addDialogStep("Yes."); + + beginQuest = new ConditionalStep(this, goToTopOfTower, "Speak to Thormac on the top floor of the Sorcerer's Tower south of Seer's Village."); + beginQuest.addStep(inSorcerersTower3, speakToThormac); + + speakToSeer1 = new NpcStep(this, NpcID.SEER, new WorldPoint(2710, 3484, 0), "Speak to a seer in Seer's Village."); speakToSeer1.addDialogStep("I need to locate some scorpions."); speakToSeer1.addDialogStep("Your friend Thormac sent me to speak to you."); - if (client.getRealSkillLevel(Skill.AGILITY) >= 70) - { - enterTaverleyDungeon = new ObjectStep(this, ObjectID.LADDER_OUTSIDE_TO_UNDERGROUND, new WorldPoint(2884, 3397, 0), - "Go to Taverley Dungeon. As you're 70 Agility, you don't need a dusty key.", scorpionCageMissingTaverley); - } - else - { - enterTaverleyDungeon = new ObjectStep(this, ObjectID.LADDER_OUTSIDE_TO_UNDERGROUND, new WorldPoint(2884, 3397, 0), - "Go to Taverley Dungeon. Bring a dusty key if you have one, otherwise you can get one in the dungeon.", scorpionCageMissingTaverley, dustyKey); - } + enterTaverleyDungeon = new ObjectStep(this, ObjectID.LADDER_OUTSIDE_TO_UNDERGROUND, new WorldPoint(2884, 3397, 0), "Go to Taverley Dungeon.", scorpionCageMissingTaverley, dustyKey); goOverStrangeFloor = new ObjectStep(this, ObjectID.TAVERLY_DUNGEON_FLOOR_SPIKES_SC, new WorldPoint(2879, 9813, 0), "Go over the strange floor."); @@ -212,53 +219,99 @@ private void setupSteps() getDustyFromAdventurer.addDialogStep("Yes please!"); enterDeeperTaverley = new ObjectStep(this, ObjectID.DEEPDUNGEONDOOR, new WorldPoint(2924, 9803, 0), "Enter the gate to the deeper Taverley dungeon.", dustyKey); - enterTaverleyDungeon.addSubSteps(goThroughPipe, goOverStrangeFloor, killJailerForKey, getDustyFromAdventurer, enterDeeperTaverley); + enterTaverleyDungeon.addSubSteps(goThroughPipe, goOverStrangeFloor, killJailerForKey, pickUpJailKey, getDustyFromAdventurer, enterDeeperTaverley); searchOldWall = new ObjectStep(this, ObjectID.SCORPIONWALL, new WorldPoint(2875, 9799, 0), "Search the Old wall."); - // TODO: Highlight item - catchTaverleyScorpion = new NpcStep(this, NpcID.QUESTSCORPIONA, "Use the scorpion cage on the scorpion.", scorpionCageMissingTaverley); + catchTaverleyScorpion = new NpcStep(this, NpcID.QUESTSCORPIONA, "Use the scorpion cage on the scorpion.", scorpionCageMissingTaverley.highlighted()); catchTaverleyScorpion.addIcon(ItemID.SCORPIONCAGEEMPTY); - enterMonastery = new ObjectStep(this, ObjectID.MONASTERYLADDER, new WorldPoint(3057, 3483, 0), - "Enter the Edgeville Monastery."); - // TODO: Highlight item - catchMonasteryScorpion = new NpcStep(this, NpcID.QUESTSCORPIONC, "Use the scorpion cage on the scorpion.", - scorpionCageMissingMonastery); + enterMonastery = new ObjectStep(this, ObjectID.MONASTERYLADDER, new WorldPoint(3057, 3483, 0), "Enter the Edgeville Monastery."); + enterMonastery.addDialogStep("Well can I join your order?"); + catchMonasteryScorpion = new NpcStep(this, NpcID.QUESTSCORPIONC, "Use the scorpion cage on the scorpion.", scorpionCageMissingMonastery.highlighted()); catchMonasteryScorpion.addIcon(ItemID.SCORPIONCAGEEMPTY); - enterOutpost = new ObjectStep(this, ObjectID.BARBARIANGATEL, new WorldPoint(2545, 3570, 0), - "Enter the Barbarian Outpost."); - // TODO: Highlight item - catchOutpostScorpion = new NpcStep(this, NpcID.QUESTSCORPIONB, new WorldPoint(2553, 3570, 0), - "Use the scorpion cage on the scorpion.", scorpionCageTaverleyAndMonastery); + enterOutpost = new ObjectStep(this, ObjectID.BARBARIANGATEL, new WorldPoint(2545, 3570, 0), "Enter the Barbarian Outpost."); + catchOutpostScorpion = new NpcStep(this, NpcID.QUESTSCORPIONB, new WorldPoint(2553, 3570, 0), "Use the scorpion cage on the scorpion.", scorpionCageTaverleyAndMonastery.highlighted()); catchOutpostScorpion.addIcon(ItemID.SCORPIONCAGEEMPTY); - returnToThormac = new NpcStep(this, NpcID.THORMAC, - "", scorpionCageFull); + returnToThormac = new NpcStep(this, NpcID.THORMAC, "", scorpionCageFull); + + finishQuest = new ConditionalStep(this, goToTopOfTower, "Return to Thormac to finish the quest.", scorpionCageFull); + finishQuest.addStep(inSorcerersTower3, returnToThormac); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, beginQuest); + steps.put(1, speakToSeer1); + + var goGetTaverleyScorpion = new ConditionalStep(this, enterTaverleyDungeon); + goGetTaverleyScorpion.addStep(and(inTaverleyScorpionRoom), catchTaverleyScorpion); + goGetTaverleyScorpion.addStep(and(inDeepTaverleyDungeon), searchOldWall); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, has80Agility), goOverStrangeFloor); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, has70Agility), goThroughPipe); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, dustyKey), enterDeeperTaverley); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, or(inJailCell, jailKey)), getDustyFromAdventurer); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon, jailKeyNearby), pickUpJailKey); + goGetTaverleyScorpion.addStep(and(inTaverleyDungeon), killJailerForKey); + + var scorpions = new ConditionalStep(this, finishQuest); + scorpions.addStep(scorpionCageMissingTaverley.alsoCheckBank(), goGetTaverleyScorpion); + + scorpions.addStep(and(scorpionCageMissingMonastery, inUpstairsMonastery), catchMonasteryScorpion); + scorpions.addStep(scorpionCageMissingMonastery.alsoCheckBank(), enterMonastery); + + scorpions.addStep(and(scorpionCageTaverleyAndMonastery, inBarbarianOutpost), catchOutpostScorpion); + scorpions.addStep(scorpionCageTaverleyAndMonastery.alsoCheckBank(), enterOutpost); + + steps.put(2, scorpions); + steps.put(3, scorpions); + + return steps; } @Override - public ArrayList getItemRequirements() + public List getGeneralRequirements() { - ArrayList reqs = new ArrayList<>(); - if (client.getRealSkillLevel(Skill.AGILITY) < 70) - { - reqs.add(dustyKey); - } + return List.of( + new QuestRequirement(QuestHelperQuest.ALFRED_GRIMHANDS_BARCRAWL, QuestState.FINISHED), + new SkillRequirement(Skill.PRAYER, 31) + ); + } - return reqs.isEmpty() ? null : reqs; + @Override + public List getItemRequirements() + { + return List.of( + dustyKey + ); } @Override - public ArrayList getItemRecommended() + public List getItemRecommended() { - return new ArrayList<>(Arrays.asList(antiDragonShield, antiPoison, food, teleRunesFalador, camelotTeleport, gamesNecklace, - gloryOrCombatBracelet)); + return List.of( + antiDragonShield, + antiPoison, + food, + teleRunesFalador, + camelotTeleport, + gamesNecklace, + gloryOrCombatBracelet + ); } @Override - public ArrayList getCombatRequirements() + public List getCombatRequirements() { - return new ArrayList<>(Collections.singletonList("The ability to run past level 172 black demons and level 64 poison spiders")); + return List.of( + "The ability to run past level 172 black demons and level 64 poison spiders" + ); } @Override @@ -270,36 +323,52 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.STRENGTH, 6625)); + return List.of( + new ExperienceReward(Skill.STRENGTH, 6625) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Ability to have Thormac turn a Battlestaff into a Mystic Staff for 40,000 Coins.")); + return List.of( + new UnlockReward("Ability to have Thormac turn a Battlestaff into a Mystic Staff for 40,000 Coins.") + ); } @Override - public ArrayList getPanels() + public List getPanels() { - ArrayList allSteps = new ArrayList<>(); - - allSteps.add(new PanelDetails("Talk to Thormac", new ArrayList<>(Collections.singletonList(speakToThormac)))); - allSteps.add(new PanelDetails("The first scorpion", new ArrayList<>(Arrays.asList(speakToSeer1, enterTaverleyDungeon, searchOldWall, catchTaverleyScorpion)))); - allSteps.add(new PanelDetails("The second scorpion", new ArrayList<>(Arrays.asList(enterMonastery, catchMonasteryScorpion)))); - allSteps.add(new PanelDetails("The third scorpion", new ArrayList<>(Arrays.asList(enterOutpost, catchOutpostScorpion)))); - allSteps.add(new PanelDetails("Finishing up", new ArrayList<>(Collections.singletonList(finishQuest)))); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Talk to Thormac", List.of( + beginQuest + ))); + + sections.add(new PanelDetails("The first scorpion", List.of( + speakToSeer1, + enterTaverleyDungeon, + searchOldWall, + catchTaverleyScorpion + ), List.of( + dustyKey + ))); + + sections.add(new PanelDetails("The second scorpion", List.of( + enterMonastery, + catchMonasteryScorpion + ))); + + sections.add(new PanelDetails("The third scorpion", List.of( + enterOutpost, + catchOutpostScorpion + ))); + + sections.add(new PanelDetails("Finishing up", List.of( + finishQuest + ))); + + return sections; } - @Override - public ArrayList getGeneralRequirements() - { - ArrayList reqs = new ArrayList<>(); - reqs.add(new QuestRequirement(QuestHelperQuest.ALFRED_GRIMHANDS_BARCRAWL, QuestState.FINISHED)); - reqs.add(new SkillRequirement(Skill.PRAYER, 31)); - - return reqs; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java index 0e7d7940a2..d69b6fa6d3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/EggSolver.java @@ -32,15 +32,14 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; +import java.awt.*; +import java.util.List; +import javax.annotation.Nullable; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.gameval.InterfaceID; import net.runelite.api.widgets.Widget; -import javax.annotation.Nullable; -import java.awt.*; -import java.util.List; - @Slf4j public class EggSolver extends DetailedOwnerStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java index 69ed9eef58..cd2246d656 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/scrambled/Scrambled.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcHintArrowRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; @@ -43,10 +44,6 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; -import net.runelite.api.QuestState; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; import java.util.ArrayList; import java.util.HashMap; @@ -54,7 +51,17 @@ import java.util.Map; import java.util.regex.Pattern; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.QuestState; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.VarbitID; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; /** * The quest guide for the "Scrambled" OSRS quest diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java index 4804a8acf8..63e4083bac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/seaslug/SeaSlug.java @@ -27,45 +27,151 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class SeaSlug extends BasicQuestHelper { - //Items Required - ItemRequirement swampPaste, glass, dampSticks, torch, litTorch, drySticks; + // Required items + ItemRequirement swampPaste; + + // Mid-quest requirements + ItemRequirement glass; + ItemRequirement dampSticks; + ItemRequirement torch; + ItemRequirement litTorch; + ItemRequirement drySticks; + + // Zones + Zone platformFirstFloor; + Zone platformGroundFloor; + Zone island; + + // Miscellaneous requirements + ZoneRequirement onPlatformGroundFloor; + ZoneRequirement onPlatformFirstFloor; + ZoneRequirement onPlatform; + ZoneRequirement onIsland; + + // Steps + NpcStep talkToCaroline; + NpcStep talkToHolgart; + NpcStep talkToHolgartWithSwampPaste; + NpcStep travelWithHolgart; + DetailedQuestStep pickupGlass; + DetailedQuestStep pickupDampSticks; + ObjectStep climbLadder; + NpcStep talkToKennith; + ObjectStep goDownLadder; + NpcStep goToIsland; + NpcStep goToIslandFromMainland; + NpcStep talkToKent; + NpcStep returnFromIsland; + NpcStep talkToBaileyForTorch; + DetailedQuestStep useGlassOnDampSticks; + DetailedQuestStep rubSticks; + ObjectStep goBackUpLadder; + NpcStep talkToKennithAgain; + ObjectStep kickWall; + NpcStep talkToKennithAfterKicking; + ObjectStep activateCrane; + ObjectStep goDownLadderAgain; + NpcStep returnWithHolgart; + NpcStep finishQuest; + NpcStep travelWithHolgartFreeingKennith; - Requirement onPlatformGroundFloor, onPlatformFirstFloor, onPlatform, onIsland; + @Override + protected void setupZones() + { + platformGroundFloor = new Zone(new WorldPoint(2760, 3271, 0), new WorldPoint(2795, 3293, 0)); + platformFirstFloor = new Zone(new WorldPoint(2760, 3271, 1), new WorldPoint(2795, 3293, 1)); + island = new Zone(new WorldPoint(2787, 3312, 0), new WorldPoint(2802, 3327, 0)); + } - QuestStep talkToCaroline, talkToHolgart, talkToHolgartWithSwampPaste, travelWithHolgart, pickupGlass, pickupDampSticks, - climbLadder, talkToKennith, goDownLadder, goToIsland, goToIslandFromMainland, talkToKent, returnFromIsland, talkToBaileyForTorch, useGlassOnDampSticks, - rubSticks, goBackUpLadder, talkToKennithAgain, kickWall, talkToKennithAfterKicking, activateCrane, goDownLadderAgain, - returnWithHolgart, finishQuest, travelWithHolgartFreeingKennith; + @Override + protected void setupRequirements() + { + swampPaste = new ItemRequirement("Swamp paste", ItemID.SWAMPPASTE); + dampSticks = new ItemRequirement("Damp sticks", ItemID.DAMP_STICKS); + dampSticks.setHighlightInInventory(true); + drySticks = new ItemRequirement("Dry sticks", ItemID.DRY_STICKS); + drySticks.setHighlightInInventory(true); + torch = new ItemRequirement("Unlit torch", ItemID.TORCH_UNLIT); + litTorch = new ItemRequirement("Lit torch", ItemID.TORCH_LIT); + glass = new ItemRequirement("Broken glass", ItemID.BROKEN_GLASS); + glass.setHighlightInInventory(true); - //Zones - Zone platformFirstFloor, platformGroundFloor, island; + onPlatformFirstFloor = new ZoneRequirement(platformFirstFloor); + onPlatformGroundFloor = new ZoneRequirement(platformGroundFloor); + onPlatform = new ZoneRequirement(platformFirstFloor, platformGroundFloor); + onIsland = new ZoneRequirement(island); + } + + public void setupSteps() + { + talkToCaroline = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline just north of Witchaven, east of East Ardougne."); + talkToCaroline.addDialogStep("Yes."); + talkToHolgart = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Talk to Holgart nearby and give him some swamp paste.", swampPaste); + talkToHolgartWithSwampPaste = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Give Holgart some swamp paste.", swampPaste); + talkToHolgart.addSubSteps(talkToHolgartWithSwampPaste); + travelWithHolgart = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart to the fishing platform."); + travelWithHolgart.addDialogStep("Will you take me there?"); + climbLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Climb the ladder in the north east corner of the platform."); + talkToKennith = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith from inside the cabin on the west side of the first floor."); + goDownLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); + goToIsland = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart to a nearby island."); + goToIslandFromMainland = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart north of Witchaven to find Kent."); + goToIsland.addSubSteps(goToIslandFromMainland); + + talkToKent = new NpcStep(this, NpcID.KENT, new WorldPoint(2794, 3322, 0), "Talk to Kent on the island."); + returnFromIsland = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2801, 3320, 0), "Return to the platform with Holgart."); + travelWithHolgartFreeingKennith = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2717, 3303, 0), + "Travel with Holgart to the fishing platform."); + returnFromIsland.addSubSteps(travelWithHolgartFreeingKennith); + + talkToBaileyForTorch = new NpcStep(this, NpcID.BAILEY, new WorldPoint(2764, 3275, 0), "Talk to Bailey for an unlit torch."); + pickupGlass = new DetailedQuestStep(this, "Pick up the broken glass in the room.", glass); + pickupDampSticks = new DetailedQuestStep(this, new WorldPoint(2784, 3289, 0), "Pick up the damp sticks in the north east corner of the platform.", dampSticks); + useGlassOnDampSticks = new DetailedQuestStep(this, "Use the broken glass on damp sticks to dry them.", glass, dampSticks); + rubSticks = new DetailedQuestStep(this, "Rub the dry sticks to light the unlit torch.", drySticks.highlighted()); + goBackUpLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Go up the ladder in the north east corner of the platform."); + talkToKennithAgain = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith to the west."); + kickWall = new ObjectStep(this, ObjectID.SLUG_BREAKABLE_PANEL, new WorldPoint(2768, 3289, 1), "Kick in the badly repaired wall east of Kennith."); + talkToKennithAfterKicking = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith again."); + activateCrane = new ObjectStep(this, ObjectID.SEASLUG_CRANE, new WorldPoint(2772, 3289, 1), "Rotate the crane east of Kennith's cabin."); + goDownLadderAgain = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); + returnWithHolgart = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart back to the mainland."); + finishQuest = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline to complete the quest."); + } @Override public Map loadSteps() { initializeRequirements(); - setupConditions(); setupSteps(); - Map steps = new HashMap<>(); + + var steps = new HashMap(); steps.put(0, talkToCaroline); @@ -73,57 +179,57 @@ public Map loadSteps() steps.put(2, talkToHolgartWithSwampPaste); - ConditionalStep investigateThePlatform = new ConditionalStep(this, travelWithHolgart); + var investigateThePlatform = new ConditionalStep(this, travelWithHolgart); investigateThePlatform.addStep(onPlatformFirstFloor, talkToKennith); investigateThePlatform.addStep(onPlatformGroundFloor, climbLadder); steps.put(3, investigateThePlatform); - ConditionalStep goFindKent = new ConditionalStep(this, travelWithHolgart); + var goFindKent = new ConditionalStep(this, travelWithHolgart); goFindKent.addStep(onPlatformGroundFloor, goToIsland); goFindKent.addStep(onPlatformFirstFloor, goDownLadder); steps.put(4, goFindKent); - ConditionalStep talkWithKent = new ConditionalStep(this, goToIslandFromMainland); + var talkWithKent = new ConditionalStep(this, goToIslandFromMainland); talkWithKent.addStep(onIsland, talkToKent); steps.put(5, talkWithKent); - ConditionalStep goToFirstFloor = new ConditionalStep(this, travelWithHolgartFreeingKennith); - goToFirstFloor.addStep(new Conditions(litTorch), goBackUpLadder); - goToFirstFloor.addStep(new Conditions(torch, drySticks), rubSticks); - goToFirstFloor.addStep(new Conditions(torch, glass, dampSticks), useGlassOnDampSticks); - goToFirstFloor.addStep(new Conditions(torch, glass), pickupDampSticks); - goToFirstFloor.addStep(new Conditions(torch), pickupGlass); + var goToFirstFloor = new ConditionalStep(this, travelWithHolgartFreeingKennith); + goToFirstFloor.addStep(litTorch, goBackUpLadder); + goToFirstFloor.addStep(and(torch, drySticks), rubSticks); + goToFirstFloor.addStep(and(torch, glass, dampSticks), useGlassOnDampSticks); + goToFirstFloor.addStep(and(torch, glass), pickupDampSticks); + goToFirstFloor.addStep(torch, pickupGlass); goToFirstFloor.addStep(onPlatform, talkToBaileyForTorch); - ConditionalStep lightTheTorch = new ConditionalStep(this, goToFirstFloor); + var lightTheTorch = new ConditionalStep(this, goToFirstFloor); lightTheTorch.addStep(onIsland, returnFromIsland); steps.put(6, lightTheTorch); - ConditionalStep freeKennith = new ConditionalStep(this, goToFirstFloor); + var freeKennith = new ConditionalStep(this, goToFirstFloor); freeKennith.addStep(onPlatformFirstFloor, talkToKennithAgain); steps.put(7, freeKennith); - ConditionalStep breakWall = new ConditionalStep(this, goToFirstFloor); + var breakWall = new ConditionalStep(this, goToFirstFloor); breakWall.addStep(onPlatformFirstFloor, kickWall); steps.put(8, breakWall); - ConditionalStep tellKennethYouBrokeWall = new ConditionalStep(this, goToFirstFloor); + var tellKennethYouBrokeWall = new ConditionalStep(this, goToFirstFloor); tellKennethYouBrokeWall.addStep(onPlatformFirstFloor, talkToKennithAfterKicking); steps.put(9, tellKennethYouBrokeWall); - ConditionalStep turnTheCrane = new ConditionalStep(this, goToFirstFloor); + var turnTheCrane = new ConditionalStep(this, goToFirstFloor); turnTheCrane.addStep(onPlatformFirstFloor, activateCrane); steps.put(10, turnTheCrane); - ConditionalStep finishUp = new ConditionalStep(this, finishQuest); + var finishUp = new ConditionalStep(this, finishQuest); finishUp.addStep(onPlatformGroundFloor, returnWithHolgart); finishUp.addStep(onPlatformFirstFloor, goDownLadderAgain); @@ -133,85 +239,27 @@ public Map loadSteps() } @Override - protected void setupRequirements() - { - swampPaste = new ItemRequirement("Swamp paste", ItemID.SWAMPPASTE); - dampSticks = new ItemRequirement("Damp sticks", ItemID.DAMP_STICKS); - dampSticks.setHighlightInInventory(true); - drySticks = new ItemRequirement("Dry sticks", ItemID.DRY_STICKS); - drySticks.setHighlightInInventory(true); - torch = new ItemRequirement("Unlit torch", ItemID.TORCH_UNLIT); - litTorch = new ItemRequirement("Lit torch", ItemID.TORCH_LIT); - glass = new ItemRequirement("Broken glass", ItemID.BROKEN_GLASS); - glass.setHighlightInInventory(true); - - } - - @Override - protected void setupZones() - { - platformGroundFloor = new Zone(new WorldPoint(2760, 3271, 0), new WorldPoint(2795, 3293, 0)); - platformFirstFloor = new Zone(new WorldPoint(2760, 3271, 1), new WorldPoint(2795, 3293, 1)); - island = new Zone(new WorldPoint(2787, 3312, 0), new WorldPoint(2802, 3327, 0)); - } - - public void setupConditions() - { - onPlatformFirstFloor = new ZoneRequirement(platformFirstFloor); - onPlatformGroundFloor = new ZoneRequirement(platformGroundFloor); - onPlatform = new ZoneRequirement(platformFirstFloor, platformGroundFloor); - onIsland = new ZoneRequirement(island); - } - - public void setupSteps() + public List getGeneralRequirements() { - talkToCaroline = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline just north of Witchaven, east of East Ardougne."); - talkToCaroline.addDialogStep("I suppose so, how do I get there?"); - talkToHolgart = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Talk to Holgart nearby and give him some swamp paste.", swampPaste); - talkToHolgartWithSwampPaste = new NpcStep(this, NpcID.HOLGARTLANDNOTRAVEL, new WorldPoint(2717, 3303, 0), "Give Holgart some swamp paste.", swampPaste); - talkToHolgart.addSubSteps(talkToHolgartWithSwampPaste); - travelWithHolgart = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart to the fishing platform."); - travelWithHolgart.addDialogStep("Will you take me there?"); - climbLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Climb the ladder in the north east corner of the platform."); - talkToKennith = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith from inside the cabin on the west side of the first floor."); - goDownLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); - goToIsland = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart to a nearby island."); - goToIslandFromMainland = new NpcStep(this, NpcID.HOLGARTLANDTRAVEL, new WorldPoint(2717, 3303, 0), "Travel with Holgart north of Witchaven to find Kent."); - goToIsland.addSubSteps(goToIsland); - - talkToKent = new NpcStep(this, NpcID.KENT, new WorldPoint(2794, 3322, 0), "Talk to Kent on the island."); - returnFromIsland = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2801, 3320, 0), "Return to the platform with Holgart."); - travelWithHolgartFreeingKennith = new NpcStep(this, NpcID.HOLGARTSUNKBOAT, new WorldPoint(2717, 3303, 0), - "Travel with Holgart to the fishing platform."); - returnFromIsland.addSubSteps(travelWithHolgartFreeingKennith); - - talkToBaileyForTorch = new NpcStep(this, NpcID.BAILEY, new WorldPoint(2764, 3275, 0), "Talk to Bailey for an unlit torch."); - pickupGlass = new DetailedQuestStep(this, "Pick up the broken glass in the room.", glass); - pickupDampSticks = new DetailedQuestStep(this, new WorldPoint(2784, 3289, 0), "Pick up the damp sticks in the north east corner of the platform.", dampSticks); - useGlassOnDampSticks = new DetailedQuestStep(this, "Use the broken glass on damp sticks to dry them.", glass, dampSticks); - rubSticks = new DetailedQuestStep(this, "Rub the dry sticks to light the unlit torch."); - goBackUpLadder = new ObjectStep(this, ObjectID.SEASLUG_LADDER, new WorldPoint(2784, 3286, 0), "Go up the ladder in the north east corner of the platform."); - talkToKennithAgain = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith to the west."); - kickWall = new ObjectStep(this, ObjectID.SLUG_BREAKABLE_PANEL, new WorldPoint(2768, 3289, 1), "Kick in the badly repaired wall east of Kennith."); - talkToKennithAfterKicking = new NpcStep(this, NpcID.KENNITH_PLATFORM, new WorldPoint(2765, 3289, 1), "Talk to Kennith again."); - activateCrane = new ObjectStep(this, ObjectID.SEASLUG_CRANE, new WorldPoint(2772, 3289, 1), "Rotate the crane east of Kennith's cabin."); - goDownLadderAgain = new ObjectStep(this, ObjectID.SEASLUG_LADDER_TOP, new WorldPoint(2784, 3286, 1), "Go back down the ladder."); - returnWithHolgart = new NpcStep(this, NpcID.HOLGARTPLATFORM, new WorldPoint(2781, 3274, 0), "Travel with Holgart back to the mainland."); - finishQuest = new NpcStep(this, NpcID.CAROLINE, new WorldPoint(2717, 3303, 0), "Talk to Caroline to complete the quest."); + return List.of( + new SkillRequirement(Skill.FIREMAKING, 30, true) + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(swampPaste); - return reqs; + return List.of( + swampPaste + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - return Collections.singletonList(new SkillRequirement(Skill.FIREMAKING, 30, true)); + return List.of( + "You can complete an Ardougne Medium Diary task by fishing from the fishing platform using a fishing rod or small fishing net (these can be bought from the fishing shop near quest start in Witchaven)." + ); } @Override @@ -223,35 +271,68 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.FISHING, 7125)); + return List.of( + new ExperienceReward(Skill.FISHING, 7175) + ); } @Override - public List getUnlockRewards() + public List getItemRewards() { - return Collections.singletonList(new UnlockReward("Access to the Fishing Platform")); + return List.of( + new ItemReward("Oyster pearls", ItemID.BIGOYSTERPEARLS, 1) + ); } - + @Override - public List getPanels() + public List getUnlockRewards() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToCaroline), - swampPaste)); - allSteps.add(new PanelDetails("Investigation", Arrays.asList(talkToHolgart, travelWithHolgart, - climbLadder, talkToKennith, goDownLadder, goToIsland))); - allSteps.add(new PanelDetails("Talking with Kent", Arrays.asList(talkToKent, returnFromIsland))); - allSteps.add(new PanelDetails("Saving Kennith", - Arrays.asList(talkToBaileyForTorch, pickupGlass, pickupDampSticks, useGlassOnDampSticks, rubSticks, goBackUpLadder, - talkToKennithAgain, kickWall, talkToKennithAfterKicking, activateCrane, goDownLadderAgain, returnWithHolgart, - finishQuest))); - - return allSteps; + return List.of( + new UnlockReward("Access to the Fishing Platform") + ); } @Override - public List getNotes() + public List getPanels() { - return Collections.singletonList("You can complete an Ardougne Medium Diary task by fishing from the fishing platform using a fishing rod or small fishing net (these can be bought from the fishing shop near quest start in Witchaven)."); + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToCaroline + ), List.of( + swampPaste + ))); + + sections.add(new PanelDetails("Investigation", List.of( + talkToHolgart, + travelWithHolgart, + climbLadder, + talkToKennith, + goDownLadder, + goToIsland + ))); + + sections.add(new PanelDetails("Talking with Kent", List.of( + talkToKent, + returnFromIsland + ))); + + sections.add(new PanelDetails("Saving Kennith", List.of( + talkToBaileyForTorch, + pickupGlass, + pickupDampSticks, + useGlassOnDampSticks, + rubSticks, + goBackUpLadder, + talkToKennithAgain, + kickWall, + talkToKennithAfterKicking, + activateCrane, + goDownLadderAgain, + returnWithHolgart, + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java index d181368198..5f98e76393 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/IncantationStep.java @@ -31,13 +31,10 @@ import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; -import java.util.Collections; - public class IncantationStep extends DetailedQuestStep { /** @@ -87,12 +84,9 @@ public class IncantationStep extends DetailedQuestStep private String[] incantationOrder; private int incantationPosition = 0; - public IncantationStep(QuestHelper questHelper, boolean reverse) + public IncantationStep(QuestHelper questHelper, boolean reverse, ItemRequirement sigilHighlighted) { - super(questHelper, "Click the demonic sigil and read the incantation."); - ItemRequirement sigilHighlighted = new ItemRequirement("Demonic sigil", ItemID.AGRITH_SIGIL); - sigilHighlighted.setHighlightInInventory(true); - this.addItemRequirements(Collections.singletonList(sigilHighlighted)); + super(questHelper, "Click the demonic sigil and read the incantation.", sigilHighlighted); this.reverse = reverse; } @@ -100,6 +94,7 @@ public IncantationStep(QuestHelper questHelper, boolean reverse) public void startUp() { super.startUp(); + incantationPosition = 0; updateHints(); } @@ -123,16 +118,17 @@ public void onMenuOptionClicked(MenuOptionClicked event) { var widget = event.getWidget(); - if (widget == null) { + if (widget == null) + { return; } - if (widget.getId() != InterfaceID.INVENTORY) + if (widget.getId() != InterfaceID.Inventory.ITEMS) { return; } - if ("Chant".equals(event.getMenuOption())) + if (event.getMenuOption().equals("Chant")) { incantationPosition = 0; } @@ -190,7 +186,8 @@ protected void updateHints() return; } - if (reverse) { + if (reverse) + { incantationOrder = new String[]{ WORDS[client.getVarbitValue(INCANTATION_WORD_5)], WORDS[client.getVarbitValue(INCANTATION_WORD_4)], @@ -198,7 +195,9 @@ protected void updateHints() WORDS[client.getVarbitValue(INCANTATION_WORD_2)], WORDS[client.getVarbitValue(INCANTATION_WORD_1)], }; - } else { + } + else + { incantationOrder = new String[]{ WORDS[client.getVarbitValue(INCANTATION_WORD_1)], WORDS[client.getVarbitValue(INCANTATION_WORD_2)], @@ -211,5 +210,6 @@ protected void updateHints() setText("Click the demonic sigil and read the incantation."); addText(incantString); + addText("If the highlight feels wrong, click the demonic sigil again."); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/SearchKilns.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/SearchKilns.java deleted file mode 100644 index 36faf85953..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/SearchKilns.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2020, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.helpers.quests.shadowofthestorm; - -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.steps.DetailedOwnerStep; -import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.ObjectID; -import net.runelite.api.gameval.VarbitID; -import net.runelite.client.eventbus.Subscribe; - -import java.util.Arrays; -import java.util.Collection; - -public class SearchKilns extends DetailedOwnerStep -{ - ObjectStep searchKiln1, searchKiln2, searchKiln3, searchKiln4; - - public SearchKilns(QuestHelper questHelper) - { - super(questHelper, "Search the kilns in Uzer until you find a book."); - } - - @Subscribe - public void onGameTick(GameTick event) - { - updateSteps(); - } - - @Override - protected void updateSteps() - { - int correctKiln = client.getVarbitValue(VarbitID.AGRITH_KILN); - if (correctKiln == 0) - { - startUpStep(searchKiln1); - } - else if (correctKiln == 1) - { - startUpStep(searchKiln2); - } - else if (correctKiln == 2) - { - startUpStep(searchKiln3); - } - else if (correctKiln == 3) - { - startUpStep(searchKiln4); - } - } - - @Override - protected void setupSteps() - { - searchKiln1 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_1, new WorldPoint(3468, 3124, 0), "Search the kilns in Uzer until you find a book."); - searchKiln2 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_2, new WorldPoint(3479, 3083, 0), "Search the kilns in Uzer until you find a book."); - searchKiln3 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_3, new WorldPoint(3473, 3093, 0), "Search the kilns in Uzer until you find a book."); - searchKiln4 = new ObjectStep(getQuestHelper(), ObjectID.AGRITH_KILN_4, new WorldPoint(3501, 3085, 0), "Search the kilns in Uzer until you find a book."); - } - - @Override - public Collection getSteps() - { - return Arrays.asList(searchKiln1, searchKiln2, searchKiln3, searchKiln4); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java index 8682b25778..621b8dd6f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowofthestorm/ShadowOfTheStorm.java @@ -30,18 +30,31 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.PuzzleWrapperStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.client.plugins.microbot.questhelper.steps.TileStep; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -50,118 +63,105 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class ShadowOfTheStorm extends BasicQuestHelper { - //Items Required - ItemRequirement darkItems, silverlight, strangeImplement, blackMushroomInk, pestle, vial, silverBar, silverlightHighlighted, blackMushroomHighlighted, - silverlightDyedEquipped, sigilMould, silverlightDyed, strangeImplementHighlighted, sigil, book, bookHighlighted, - sigilHighlighted, sigil2; - - //Items Recommended - ItemRequirement combatGear, coinsForCarpet, alKharidTeleport; - - Requirement inRuin, inThroneRoom,talkedToGolem, talkedToMatthew, inCircleSpot, sigilNearby, evilDaveMoved, baddenMoved, - reenMoved, golemMoved, golemRejected, golemReprogrammed, - inSecondCircleSpot; - - DetailedQuestStep talkToReen, talkToBadden, pickMushroom, dyeSilverlight, goIntoRuin, pickUpStrangeImplement, talkToEvilDave, enterPortal, - talkToDenath, talkToJennifer, talkToMatthew, smeltSigil, talkToGolem, readBook, enterRuinAfterBook, enterPortalAfterBook, - talkToMatthewAfterBook, standInCircle, pickUpSigil, leavePortal, tellDaveToReturn, pickUpImplementAfterRitual, - goUpToBadden, talkToBaddenAfterRitual, talkToReenAfterRitual, talkToTheGolemAfterRitual, useImplementOnGolem, pickUpSigil2, - talkToGolemAfterReprogramming, enterRuinAfterRecruiting, enterPortalAfterRecruiting, talkToMatthewToStartFight, killDemon, - standInCircleAgain, enterRuinNoDark, enterRuinForRitual, enterPortalForRitual, enterRuinForDave, enterPortalForFight, - enterRuinForFight, unequipDarklight; - - DetailedOwnerStep searchKiln; - - IncantationStep readIncantation, incantRitual; - - //Zones - Zone ruin, throneRoom, circleSpot, secondCircleSpot; - - @Override - public Map loadSteps() - { - Map steps = new HashMap<>(); - initializeRequirements(); - setupConditions(); - setupSteps(); - - steps.put(0, talkToReen); - steps.put(10, talkToBadden); - - ConditionalStep infiltrateCult = new ConditionalStep(this, pickMushroom); - infiltrateCult.addStep(new Conditions(silverlightDyed, strangeImplement, inRuin), talkToEvilDave); - infiltrateCult.addStep(new Conditions(silverlightDyed, inRuin), pickUpStrangeImplement); - infiltrateCult.addStep(silverlightDyed, goIntoRuin); - infiltrateCult.addStep(blackMushroomHighlighted, dyeSilverlight); - steps.put(20, infiltrateCult); - - ConditionalStep goTalkToDenath = new ConditionalStep(this, enterRuinNoDark); - goTalkToDenath.addStep(inThroneRoom, talkToDenath); - goTalkToDenath.addStep(inRuin, enterPortal); - steps.put(30, goTalkToDenath); - - ConditionalStep completeSubTasks = new ConditionalStep(this, enterRuinNoDark); - completeSubTasks.addStep(new Conditions(book, sigil, inThroneRoom), talkToMatthewAfterBook); - completeSubTasks.addStep(new Conditions(book, sigil, inRuin), enterPortalAfterBook); - completeSubTasks.addStep(new Conditions(book, sigil), enterRuinAfterBook); - completeSubTasks.addStep(new Conditions(talkedToGolem, sigil), searchKiln); - completeSubTasks.addStep(new Conditions(talkedToMatthew, sigil), talkToGolem); - completeSubTasks.addStep(new Conditions(talkedToMatthew, sigilMould), smeltSigil); - completeSubTasks.addStep(new Conditions(inThroneRoom, sigilMould), talkToMatthew); - completeSubTasks.addStep(inThroneRoom, talkToJennifer); - completeSubTasks.addStep(inRuin, enterPortal); - steps.put(40, completeSubTasks); - steps.put(50, completeSubTasks); - steps.put(60, completeSubTasks); - - ConditionalStep startRitual = new ConditionalStep(this, enterRuinForRitual); - startRitual.addStep(inThroneRoom, talkToMatthewAfterBook); - startRitual.addStep(inRuin, enterPortalForRitual); - steps.put(70, startRitual); - - ConditionalStep performRitual = new ConditionalStep(this, enterRuinForRitual); - performRitual.addStep(inCircleSpot, readIncantation); - performRitual.addStep(inThroneRoom, standInCircle); - performRitual.addStep(inRuin, enterPortalForRitual); - steps.put(80, performRitual); - - ConditionalStep prepareForSecondRitual = new ConditionalStep(this, enterRuinForDave); - prepareForSecondRitual.addStep(sigilNearby, pickUpSigil); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inThroneRoom), talkToMatthewToStartFight); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inRuin), enterPortalAfterRecruiting); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemMoved), enterRuinAfterRecruiting); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemReprogrammed), talkToGolemAfterReprogramming); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved, golemRejected), useImplementOnGolem); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved, reenMoved), talkToTheGolemAfterRitual); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, baddenMoved), talkToReenAfterRitual); - prepareForSecondRitual.addStep(new Conditions(strangeImplement, evilDaveMoved, inRuin), goUpToBadden); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved, inRuin), pickUpImplementAfterRitual); - prepareForSecondRitual.addStep(new Conditions(evilDaveMoved), talkToBaddenAfterRitual); - prepareForSecondRitual.addStep(inRuin, tellDaveToReturn); - prepareForSecondRitual.addStep(inThroneRoom, leavePortal); - - steps.put(90, prepareForSecondRitual); - steps.put(100, prepareForSecondRitual); - - ConditionalStep summonAgrith = new ConditionalStep(this, enterRuinAfterRecruiting); - summonAgrith.addStep(inSecondCircleSpot, incantRitual); - summonAgrith.addStep(inThroneRoom, standInCircleAgain); - summonAgrith.addStep(inRuin, enterPortalAfterRecruiting); - steps.put(110, summonAgrith); - - ConditionalStep defeatAgrith = new ConditionalStep(this, enterRuinForFight); - defeatAgrith.addStep(inThroneRoom, killDemon); - defeatAgrith.addStep(inRuin, enterPortalForFight); - steps.put(120, defeatAgrith); - - steps.put(124, unequipDarklight); - - return steps; - } + // Required items + ItemRequirement silverlight; + ItemRequirement darkItems; + ItemRequirement silverBar; + + // Recommended items + ItemRequirement combatGear; + ItemRequirement coinsForCarpet; + ItemRequirement alKharidTeleport; + + // Mid-quest item requirements + ItemRequirement strangeImplement; + ItemRequirement blackMushroomInk; + ItemRequirement pestle; + ItemRequirement vial; + ItemRequirement silverlightHighlighted; + ItemRequirement blackMushroomHighlighted; + ItemRequirement silverlightDyedEquipped; + ItemRequirement sigilMould; + ItemRequirement silverlightDyed; + ItemRequirement strangeImplementHighlighted; + ItemRequirement sigil; + ItemRequirement book; + ItemRequirement bookHighlighted; + ItemRequirement sigilHighlighted; + ItemRequirement sigil2; + + // Zones + Zone ruin; + Zone throneRoom; + Zone circleSpot; + Zone secondCircleSpot; + + // Miscellaneous requirements + ZoneRequirement inRuin; + ZoneRequirement inThroneRoom; + VarbitRequirement talkedToGolem; + VarbitRequirement talkedToMatthew; + ZoneRequirement inCircleSpot; + ItemOnTileRequirement sigilNearby; + VarbitRequirement evilDaveMoved; + VarbitRequirement baddenMoved; + VarbitRequirement reenMoved; + VarbitRequirement golemMoved; + VarbitRequirement golemRejected; + VarbitRequirement golemReprogrammed; + ZoneRequirement inSecondCircleSpot; + FreeInventorySlotRequirement freeSlot1; + + // Steps + NpcStep talkToReen; + NpcStep talkToBadden; + ObjectStep pickMushroom; + DetailedQuestStep dyeSilverlight; + ObjectStep goIntoRuin; + DetailedQuestStep pickUpStrangeImplement; + NpcStep talkToEvilDave; + ObjectStep enterPortal; + NpcStep talkToDenath; + NpcStep talkToJennifer; + NpcStep talkToMatthew; + DetailedQuestStep smeltSigil; + NpcStep talkToGolem; + DetailedQuestStep readBook; + ObjectStep enterRuinAfterBook; + ObjectStep enterPortalAfterBook; + NpcStep talkToMatthewAfterBook; + TileStep standInCircle; + ItemStep pickUpSigil; + ObjectStep leavePortal; + NpcStep tellDaveToReturn; + DetailedQuestStep pickUpImplementAfterRitual; + ObjectStep goUpToBadden; + NpcStep talkToBaddenAfterRitual; + NpcStep talkToReenAfterRitual; + NpcStep talkToTheGolemAfterRitual; + NpcStep useImplementOnGolem; + ItemStep pickUpSigil2; + NpcStep talkToGolemAfterReprogramming; + ObjectStep enterRuinAfterRecruiting; + ObjectStep enterPortalAfterRecruiting; + NpcStep talkToMatthewToStartFight; + NpcStep killDemon; + TileStep standInCircleAgain; + ObjectStep enterRuinNoDark; + ObjectStep enterRuinForRitual; + ObjectStep enterPortalForRitual; + ObjectStep enterRuinForDave; + ObjectStep enterPortalForFight; + ObjectStep enterRuinForFight; + DetailedQuestStep unequipDarklight; + ConditionalStep searchKilns; + PuzzleWrapperStep pwSearchKilns; + IncantationStep readIncantation; + PuzzleWrapperStep pwReadIncantation; + IncantationStep incantRitual; + PuzzleWrapperStep pwIncantRitual; @Override protected void setupZones() @@ -215,10 +215,6 @@ protected void setupRequirements() // Recommended alKharidTeleport = new ItemRequirement("Al Kharid Teleport", ItemCollections.AMULET_OF_GLORIES); alKharidTeleport.addAlternates(ItemCollections.RING_OF_DUELINGS); - } - - private void setupConditions() - { inRuin = new ZoneRequirement(ruin); inThroneRoom = new ZoneRequirement(throneRoom); inCircleSpot = new ZoneRequirement(circleSpot); @@ -233,6 +229,8 @@ private void setupConditions() golemRejected = new VarbitRequirement(VarbitID.AGRITH_CONVINCED_GOLEM, 1, Operation.GREATER_EQUAL); golemReprogrammed = new VarbitRequirement(VarbitID.AGRITH_CONVINCED_GOLEM, 2, Operation.GREATER_EQUAL); golemMoved = new VarbitRequirement(VarbitID.AGRITH_CONVINCED_GOLEM, 3, Operation.GREATER_EQUAL); + + freeSlot1 = new FreeInventorySlotRequirement(1); } private void setupSteps() @@ -254,7 +252,7 @@ private void setupSteps() talkToDenath = new NpcStep(this, NpcID.AGRITH_DENATH, new WorldPoint(2720, 4912, 2), "Talk to Denath next to the throne."); talkToDenath.addDialogStep("What do I have to do?"); talkToDenath.addSubSteps(enterRuinNoDark, enterPortal); - talkToJennifer = new NpcStep(this, NpcID.AGRITH_JENNIFER, new WorldPoint(2723, 4901, 2), "Talk to Jennifer."); + talkToJennifer = new NpcStep(this, NpcID.AGRITH_JENNIFER, new WorldPoint(2723, 4901, 2), "Talk to Jennifer.", freeSlot1); talkToJennifer.addDialogStep("Do you have the demonic sigil mould?"); talkToMatthew = new NpcStep(this, NpcID.AGRITH_MATTHEW, new WorldPoint(2727, 4897, 2), "Talk to Matthew."); talkToMatthew.addDialogStep("Do you know what happened to Josef?"); @@ -263,7 +261,20 @@ private void setupSteps() talkToGolem = new NpcStep(this, NpcID.GOLEM_FIXED_GOLEM, new WorldPoint(3485, 3088, 0), "Talk to the Golem in Uzer.", silverlightDyed, sigil, combatGear); talkToGolem.addDialogStep("Uzer"); talkToGolem.addDialogStep("Did you see anything happen last night?"); - searchKiln = new SearchKilns(this); + + var searchKiln1 = new ObjectStep(this, ObjectID.AGRITH_KILN_1, new WorldPoint(3468, 3124, 0), ""); + var searchKiln2 = new ObjectStep(this, ObjectID.AGRITH_KILN_2, new WorldPoint(3479, 3083, 0), ""); + var searchKiln3 = new ObjectStep(this, ObjectID.AGRITH_KILN_3, new WorldPoint(3473, 3093, 0), ""); + var searchKiln4 = new ObjectStep(this, ObjectID.AGRITH_KILN_4, new WorldPoint(3501, 3085, 0), ""); + + var kilnBuilder = new VarbitBuilder(VarbitID.AGRITH_KILN); + searchKilns = new ConditionalStep(this, searchKiln1, "Search the kilns in Uzer until you find a book."); + searchKilns.addStep(kilnBuilder.eq(1), searchKiln2); + searchKilns.addStep(kilnBuilder.eq(2), searchKiln3); + searchKilns.addStep(kilnBuilder.eq(3), searchKiln4); + + pwSearchKilns = searchKilns.puzzleWrapStep("Search Uzer for a book."); + readBook = new DetailedQuestStep(this, "Read the book.", bookHighlighted); enterRuinAfterBook = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Enter the Uzer ruins.", silverlightDyed, book, sigil); enterPortalAfterBook = new ObjectStep(this, ObjectID.GOLEM_PORTAL, new WorldPoint(2722, 4913, 0), "Enter the portal.", book, sigil); @@ -274,21 +285,23 @@ private void setupSteps() enterRuinForRitual = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Enter the Uzer ruins.", sigil, silverlightDyed, combatGear); enterPortalForRitual = new ObjectStep(this, ObjectID.GOLEM_PORTAL, new WorldPoint(2722, 4913, 0), "Enter the portal."); - standInCircle = new DetailedQuestStep(this, new WorldPoint(2718, 4902, 2), "Stand in the correct spot in the circle.", sigil); - readIncantation = new IncantationStep(this, true); - pickUpSigil = new ItemStep(this, "Pick up the sigil.", sigil); + standInCircle = new TileStep(this, new WorldPoint(2718, 4902, 2), "Stand in the correct spot in the circle.", sigil); + standInCircle.addSubSteps(enterRuinForRitual, enterPortalForRitual); + readIncantation = new IncantationStep(this, true, sigilHighlighted); + pwReadIncantation = readIncantation.puzzleWrapStepWithDefaultText("Click the demonic sigil and read the incantation."); + pickUpSigil = new ItemStep(this, "Pick up the demonic sigil from the circle.", sigil); leavePortal = new ObjectStep(this, ObjectID.AGRITH_PORTAL_CLOSING, new WorldPoint(2720, 4883, 2), "Leave the throne room."); enterRuinForDave = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Talk to Evil Dave in the Uzer ruins."); - tellDaveToReturn = new NpcStep(this, NpcID.AGRITH_DAVE, new WorldPoint(2721, 4900, 0), "Talk to Evil Dave."); + tellDaveToReturn = new NpcStep(this, NpcID.AGRITH_DAVE, new WorldPoint(2721, 4900, 0), "Talk to Evil Dave.", freeSlot1); tellDaveToReturn.addDialogStep("You've got to get back to the throne room!"); tellDaveToReturn.addSubSteps(enterRuinForDave); pickUpImplementAfterRitual = new DetailedQuestStep(this, new WorldPoint(2713, 4913, 0), "Pick up the strange implement in the north west corner of the ruin.", strangeImplement); - pickUpSigil2 = new ItemStep(this, "Pick up the sigil Tanya dropped.", sigil); + pickUpSigil2 = new ItemStep(this, "Pick up the demonic sigil Tanya dropped.", sigil); goUpToBadden = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_BASE, new WorldPoint(2722, 4885, 0), "Leave the ruins."); talkToBaddenAfterRitual = new NpcStep(this, NpcID.AGRITH_BADDEN, new WorldPoint(3490, 3090, 0), "Talk to Father Badden in Uzer.", sigil2); - talkToBaddenAfterRitual.addSubSteps(goUpToBadden); + talkToBaddenAfterRitual.addSubSteps(goUpToBadden, pickUpImplementAfterRitual); talkToReenAfterRitual = new NpcStep(this, NpcID.AGRITH_REEN, new WorldPoint(3490, 3090, 0), "Talk to Father Reen in Uzer.", sigil2); talkToReenAfterRitual.addDialogStep("Oh, don't be so simple-minded!"); @@ -303,8 +316,9 @@ private void setupSteps() talkToMatthewToStartFight = new NpcStep(this, NpcID.AGRITH_MATTHEW, new WorldPoint(2727, 4897, 2), "Talk to Matthew in the throne room.", silverlightDyed, sigil, combatGear); talkToMatthewToStartFight.addSubSteps(enterRuinAfterRecruiting, enterPortalAfterRecruiting); talkToMatthewToStartFight.addDialogStep("Yes."); - standInCircleAgain = new DetailedQuestStep(this, new WorldPoint(2720, 4903, 2), "Stand in the correct spot in the circle.", sigil); - incantRitual = new IncantationStep(this, false); + standInCircleAgain = new TileStep(this, new WorldPoint(2720, 4903, 2), "Stand in the correct spot in the circle.", sigil); + incantRitual = new IncantationStep(this, false, sigilHighlighted); + pwIncantRitual = incantRitual.puzzleWrapStepWithDefaultText("Click the demonic sigil and read the incantation."); enterRuinForFight = new ObjectStep(this, ObjectID.GOLEM_INSIDESTAIRS_TOP, new WorldPoint(3493, 3090, 0), "Enter the Uzer ruins to finish fighting Agrith-Naar.", silverlightDyed, combatGear); enterPortalForFight = new ObjectStep(this, ObjectID.GOLEM_PORTAL, new WorldPoint(2722, 4913, 0), "Enter the portal to finish fighting Agrith-Naar.", silverlightDyed, combatGear); killDemon = new NpcStep(this, NpcID.AGRITH_NAAR, "Kill Agrith-Naar. You can hurt him with any weapon, BUT YOU MUST DEAL THE FINAL BLOW WITH SILVERLIGHT.", silverlightDyedEquipped, combatGear); @@ -314,39 +328,142 @@ private void setupSteps() } @Override - public List getNotes() + public Map loadSteps() { - return Arrays.asList("You will need 3 black items for a part of the quest. Potential items would be:", - "- Desert shirt/robe dyed with black mushroom ink", "- Black armour", "- Priest gown top/bottom", "- Black wizard hat", - "- Dark mystic", "- Ghostly robes", "- Shade robes", "- Black dragonhide", "- Black cape", "- One of the various black holiday event items", "- Graceful outfit (dyed black)"); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToReen); + steps.put(10, talkToBadden); + + var infiltrateCult = new ConditionalStep(this, pickMushroom); + infiltrateCult.addStep(and(silverlightDyed, strangeImplement, inRuin), talkToEvilDave); + infiltrateCult.addStep(and(silverlightDyed, inRuin), pickUpStrangeImplement); + infiltrateCult.addStep(silverlightDyed, goIntoRuin); + infiltrateCult.addStep(blackMushroomHighlighted, dyeSilverlight); + steps.put(20, infiltrateCult); + + var goTalkToDenath = new ConditionalStep(this, enterRuinNoDark); + goTalkToDenath.addStep(inThroneRoom, talkToDenath); + goTalkToDenath.addStep(inRuin, enterPortal); + steps.put(30, goTalkToDenath); + + var completeSubTasks = new ConditionalStep(this, enterRuinNoDark); + completeSubTasks.addStep(and(book, sigil, inThroneRoom), talkToMatthewAfterBook); + completeSubTasks.addStep(and(book, sigil, inRuin), enterPortalAfterBook); + completeSubTasks.addStep(and(book, sigil), enterRuinAfterBook); + completeSubTasks.addStep(and(talkedToGolem, sigil), pwSearchKilns); + completeSubTasks.addStep(and(talkedToMatthew, sigil), talkToGolem); + completeSubTasks.addStep(and(talkedToMatthew, sigilMould), smeltSigil); + completeSubTasks.addStep(and(inThroneRoom, sigilMould), talkToMatthew); + completeSubTasks.addStep(inThroneRoom, talkToJennifer); + completeSubTasks.addStep(inRuin, enterPortal); + steps.put(40, completeSubTasks); + steps.put(50, completeSubTasks); + steps.put(60, completeSubTasks); + + var startRitual = new ConditionalStep(this, enterRuinForRitual); + startRitual.addStep(inThroneRoom, talkToMatthewAfterBook); + startRitual.addStep(inRuin, enterPortalForRitual); + steps.put(70, startRitual); + + var performRitual = new ConditionalStep(this, enterRuinForRitual); + performRitual.addStep(inCircleSpot, pwReadIncantation); + performRitual.addStep(inThroneRoom, standInCircle); + performRitual.addStep(inRuin, enterPortalForRitual); + steps.put(80, performRitual); + + var prepareForSecondRitual = new ConditionalStep(this, enterRuinForDave); + prepareForSecondRitual.addStep(sigilNearby, pickUpSigil); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inThroneRoom), talkToMatthewToStartFight); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemMoved, inRuin), enterPortalAfterRecruiting); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemMoved), enterRuinAfterRecruiting); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemReprogrammed), talkToGolemAfterReprogramming); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved, golemRejected), useImplementOnGolem); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved, reenMoved), talkToTheGolemAfterRitual); + prepareForSecondRitual.addStep(and(evilDaveMoved, baddenMoved), talkToReenAfterRitual); + prepareForSecondRitual.addStep(and(strangeImplement, evilDaveMoved, inRuin), goUpToBadden); + prepareForSecondRitual.addStep(and(evilDaveMoved, inRuin), pickUpImplementAfterRitual); + prepareForSecondRitual.addStep(and(evilDaveMoved), talkToBaddenAfterRitual); + prepareForSecondRitual.addStep(inRuin, tellDaveToReturn); + prepareForSecondRitual.addStep(inThroneRoom, leavePortal); + + steps.put(90, prepareForSecondRitual); + steps.put(100, prepareForSecondRitual); + + var summonAgrith = new ConditionalStep(this, enterRuinAfterRecruiting); + summonAgrith.addStep(inSecondCircleSpot, pwIncantRitual); + summonAgrith.addStep(inThroneRoom, standInCircleAgain); + summonAgrith.addStep(inRuin, enterPortalAfterRecruiting); + steps.put(110, summonAgrith); + + var defeatAgrith = new ConditionalStep(this, enterRuinForFight); + defeatAgrith.addStep(inThroneRoom, killDemon); + defeatAgrith.addStep(inRuin, enterPortalForFight); + steps.put(120, defeatAgrith); + + steps.put(124, unequipDarklight); + + return steps; } @Override - public List getCombatRequirements() + public List getGeneralRequirements() { - return Collections.singletonList("Agrith-Naar (level 100)"); + return List.of( + new QuestRequirement(QuestHelperQuest.THE_GOLEM, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.DEMON_SLAYER, QuestState.FINISHED), + new SkillRequirement(Skill.CRAFTING, 30, true) + ); } @Override public List getItemRequirements() { - return Arrays.asList(silverlight, darkItems, silverBar); + return List.of( + silverlight, + darkItems, + silverBar + ); } @Override public List getItemRecommended() { - return Arrays.asList(combatGear, coinsForCarpet, alKharidTeleport); + return List.of( + combatGear, + coinsForCarpet, + alKharidTeleport + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() + { + return List.of( + "Agrith-Naar (level 100)" + ); + } + + @Override + public List getNotes() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.THE_GOLEM, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.DEMON_SLAYER, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.CRAFTING, 30, true)); - return req; + return List.of( + "You will need 3 black items for a part of the quest. Potential items would be:", + "- Desert shirt/robe dyed with black mushroom ink", + "- Black armour", + "- Priest gown top/bottom", + "- Black wizard hat", + "- Dark mystic", + "- Ghostly robes", + "- Shade robes", + "- Black dragonhide", + "- Black cape", + "- One of the various black holiday event items", + "- Graceful outfit (dyed black)" + ); } @Override @@ -358,21 +475,70 @@ public QuestPointReward getQuestPointReward() @Override public List getItemRewards() { - return Arrays.asList( - new ItemReward("10,000 Experience Lamp (Any combat skill except Prayer)", ItemID.THOSF_REWARD_LAMP, 1), //4447 is placeholder for filter - new ItemReward("Darklight", ItemID.DARKLIGHT, 1)); + return List.of( + new ItemReward("10,000 Experience Lamp (Any combat skill except Prayer)", ItemID.THOSF_REWARD_LAMP, 1), //4447 is placeholder for filter + new ItemReward("Darklight", ItemID.DARKLIGHT, 1) + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - - allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToReen))); - allSteps.add(new PanelDetails("Infiltrate the cult", Arrays.asList(talkToBadden, pickMushroom, dyeSilverlight, goIntoRuin, pickUpStrangeImplement, talkToEvilDave, talkToDenath, talkToJennifer, talkToMatthew), silverlight, darkItems)); - allSteps.add(new PanelDetails("Uncovering the truth", Arrays.asList(smeltSigil, talkToGolem, searchKiln, readBook, talkToMatthewAfterBook, standInCircle, readIncantation), silverBar, silverlightDyed, combatGear)); - allSteps.add(new PanelDetails("Defeating Agrith-Naar", Arrays.asList(pickUpSigil, leavePortal, pickUpSigil2, tellDaveToReturn, talkToBaddenAfterRitual, talkToReenAfterRitual, talkToTheGolemAfterRitual, useImplementOnGolem, talkToGolemAfterReprogramming, - talkToMatthewToStartFight, standInCircleAgain, incantRitual, killDemon, unequipDarklight), silverlightDyed, combatGear)); - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToReen + ))); + + sections.add(new PanelDetails("Infiltrate the cult", List.of( + talkToBadden, + pickMushroom, + dyeSilverlight, + goIntoRuin, + pickUpStrangeImplement, + talkToEvilDave, + talkToDenath, + talkToJennifer, + talkToMatthew + ), List.of( + silverlight, + darkItems + ))); + + sections.add(new PanelDetails("Uncovering the truth", List.of( + smeltSigil, + talkToGolem, + pwSearchKilns, + readBook, + talkToMatthewAfterBook, + standInCircle, + pwReadIncantation + ), List.of( + silverBar, + silverlightDyed, + combatGear + ))); + + sections.add(new PanelDetails("Defeating Agrith-Naar", List.of( + pickUpSigil, + leavePortal, + pickUpSigil2, + tellDaveToReturn, + talkToBaddenAfterRitual, + talkToReenAfterRitual, + talkToTheGolemAfterRitual, + useImplementOnGolem, + talkToGolemAfterReprogramming, + talkToMatthewToStartFight, + standInCircleAgain, + pwIncantRitual, + killDemon, + unequipDarklight + ), List.of( + silverlightDyed, + combatGear + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java index 6ab1fd4999..e2ed47fd49 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shadowsofcustodia/ShadowsOfCustodia.java @@ -36,6 +36,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -43,7 +44,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; @@ -52,13 +61,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; - /** * The quest guide for the "Shadows of Custodia" OSRS quest */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java index 8530d771fc..9e1e565c21 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepherder/SheepHerder.java @@ -30,28 +30,30 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.tools.QuestTile; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class SheepHerder extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java index 1c57e98228..3f35bb5881 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sheepshearer/SheepShearer.java @@ -29,27 +29,35 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.ManualRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ItemContainerChanged; -import net.runelite.api.gameval.*; -import net.runelite.client.eventbus.Subscribe; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.IntStream; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ItemContainerChanged; +import net.runelite.api.gameval.InventoryID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; +import net.runelite.client.eventbus.Subscribe; public class SheepShearer extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java index 8065d58655..afda63320e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shieldofarrav/ShieldOfArravBlackArmGang.java @@ -41,7 +41,11 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java index df86791175..c7ce80886c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/shilovillage/ShiloVillage.java @@ -39,6 +39,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; @@ -49,109 +50,125 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - -import java.util.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; public class ShiloVillage extends BasicQuestHelper { - // Required - ItemRequirement spade, torchOrCandle, rope, bronzeWire, chisel, bones3; - - // Recommended - ItemRequirement combatGear, food, staminas, antipoison, prayerPotions, quickTeleport, papyrus, charcoal, - crumbleUndead; - - ItemRequirement belt, stonePlaque, tatteredScroll, crumpledScroll, zadimusCorpse, boneShard, beads, pommel, - beadsOfTheDead, boneKey, rashCorpse; - - Requirement emptySlot3, moundNearby, inCavern1, inCavern2, inCavern3, inCavern4, shownStone, shownCorpse, - hasReadTattered, hasReadCrumpled, revealedDoor, searchedDoor, doorOpened, nazNearby, corpseNearby; - - QuestStep talkToMosol, useBeltOnTrufitus, useSpadeOnGround, useTorchOnFissure, useRopeOnFissure, - lookAtMound, searchFissure, useChiselOnStone, enterDeeperCave, searchForTatteredScroll, searchForCrumpledScroll, - searchForCorpse, useCorpseOnTrufitus, useStonePlaqueOnTrufitus, readTattered, readCrumpled, buryCorpse; - - QuestStep searchRocksOnCairn, searchDolmen, useChiselOnPommel, useWireOnBeads; - - QuestStep searchPalms, searchDoors, makeKey, useKeyOnDoor, enterDoor, useBonesOnDoor, searchDolmenForFight, killNazastarool, - pickupCorpse; - - QuestStep enterCairnAgain, useCorpseOnDolmen; - - Zone cavern1, cavern2, cavern3, cavern4; + // Required items + ItemRequirement spade; + ItemRequirement torchOrCandle; + ItemRequirement rope; + ItemRequirement bronzeWire; + ItemRequirement chisel; + ItemRequirement bones3; + + // Recommended items + ItemRequirement combatGear; + ItemRequirement food; + ItemRequirement staminas; + ItemRequirement antipoison; + ItemRequirement prayerPotions; + ItemRequirement quickTeleport; + ItemRequirement papyrus; + ItemRequirement charcoal; + ItemRequirement crumbleUndead; + + // Mid-quest item requirements + ItemRequirement belt; + ItemRequirement stonePlaque; + ItemRequirement tatteredScroll; + ItemRequirement crumpledScroll; + ItemRequirement zadimusCorpse; + ItemRequirement boneShard; + ItemRequirement beads; + ItemRequirement pommel; + ItemRequirement beadsOfTheDead; + ItemRequirement boneKey; + ItemRequirement rashCorpse; + + // Zones + Zone cavern1; + Zone cavern2; + Zone cavern3; + Zone cavern4; + + // Miscellaneous requirements + FreeInventorySlotRequirement freeInvSlot1; + FreeInventorySlotRequirement freeInvSlot2; + ObjectCondition moundNearby; + ZoneRequirement inCavern1; + ZoneRequirement inCavern2; + ZoneRequirement inCavern3; + ZoneRequirement inCavern4; + Conditions shownStone; + Conditions shownCorpse; + Conditions hasReadTattered; + Conditions hasReadCrumpled; + VarbitRequirement revealedDoor; + Conditions searchedDoor; + VarbitRequirement doorOpened; + NpcInteractingRequirement nazNearby; + ItemOnTileRequirement corpseNearby; + + // Steps + NpcStep talkToMosol; + NpcStep showBeltToTrufitus; + ObjectStep useSpadeOnGround; + ObjectStep useTorchOnFissure; + ObjectStep useRopeOnFissure; + ObjectStep lookAtMound; + ObjectStep searchFissure; + ObjectStep useChiselOnStone; + ObjectStep enterDeeperCave; + ObjectStep searchForTatteredScroll; + ObjectStep searchForCrumpledScroll; + ObjectStep searchForCorpse; + NpcStep useCorpseOnTrufitus; + NpcStep useStonePlaqueOnTrufitus; + DetailedQuestStep readTattered; + DetailedQuestStep readCrumpled; + DetailedQuestStep buryCorpse; + ObjectStep searchRocksOnCairn; + ObjectStep searchDolmen; + DetailedQuestStep useChiselOnPommel; + DetailedQuestStep useWireOnBeads; + ObjectStep searchPalms; + ObjectStep searchDoors; + DetailedQuestStep makeKey; + ObjectStep useKeyOnDoor; + ObjectStep enterDoor; + ObjectStep useBonesOnDoor; + ObjectStep searchDolmenForFight; + NpcStep killNazastarool; + ItemStep pickupCorpse; + ObjectStep enterCairnAgain; + ObjectStep useCorpseOnDolmen; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - ConditionalStep goStartQuest = new ConditionalStep(this, talkToMosol); - goStartQuest.addStep(belt.alsoCheckBank(), useBeltOnTrufitus); - steps.put(0, goStartQuest); - - steps.put(1, useSpadeOnGround); - steps.put(2, useSpadeOnGround); - steps.put(3, useSpadeOnGround); - - ConditionalStep lightUpFissure = new ConditionalStep(this, useTorchOnFissure); - lightUpFissure.addStep(moundNearby, lookAtMound); - steps.put(4, lightUpFissure); - - ConditionalStep goUseRope = new ConditionalStep(this, useRopeOnFissure); - goUseRope.addStep(moundNearby, lookAtMound); - steps.put(5, goUseRope); - - ConditionalStep goGetItems = new ConditionalStep(this, searchFissure); - goGetItems.addStep(new Conditions(beadsOfTheDead, boneKey), useKeyOnDoor); - goGetItems.addStep(new Conditions(beadsOfTheDead, searchedDoor), makeKey); - goGetItems.addStep(new Conditions(beadsOfTheDead, revealedDoor), searchDoors); - goGetItems.addStep(new Conditions(beadsOfTheDead), searchPalms); - goGetItems.addStep(new Conditions(beads), useWireOnBeads); - goGetItems.addStep(new Conditions(pommel), useChiselOnPommel); - goGetItems.addStep(new Conditions(inCavern3), searchDolmen); - // Stone-plaque may be useless? - // Don't need to show Trufitus bone shard - // Reading tattered unlocks access to the island cavern - // Reading crumpled lets you use bronze wire on beads - goGetItems.addStep(new Conditions(stonePlaque, hasReadTattered, hasReadCrumpled, boneShard), searchRocksOnCairn); - goGetItems.addStep(new Conditions(stonePlaque, hasReadTattered, crumpledScroll, boneShard), readCrumpled); - goGetItems.addStep(new Conditions(stonePlaque, tatteredScroll, crumpledScroll, boneShard), readTattered); - goGetItems.addStep(new Conditions(stonePlaque, tatteredScroll, crumpledScroll, zadimusCorpse), buryCorpse); - goGetItems.addStep(new Conditions(inCavern2, stonePlaque, tatteredScroll, crumpledScroll), searchForCorpse); - goGetItems.addStep(new Conditions(inCavern2, stonePlaque, tatteredScroll), searchForCrumpledScroll); - goGetItems.addStep(new Conditions(inCavern2, stonePlaque), searchForTatteredScroll); - goGetItems.addStep(new Conditions(inCavern1, stonePlaque), enterDeeperCave); - goGetItems.addStep(inCavern1, useChiselOnStone); - goGetItems.addStep(moundNearby, lookAtMound); - steps.put(6, goGetItems); - steps.put(7, goGetItems); - steps.put(8, goGetItems); - steps.put(9, goGetItems); - - ConditionalStep goToDolem = new ConditionalStep(this, enterDoor); - goToDolem.addStep(inCavern4, useBonesOnDoor); - steps.put(10, goToDolem); - steps.put(11, goToDolem); - - ConditionalStep goDoFight = new ConditionalStep(this, enterDoor); - goDoFight.addStep(new Conditions(rashCorpse, inCavern3), useCorpseOnDolmen); - goDoFight.addStep(rashCorpse, enterCairnAgain); - goDoFight.addStep(corpseNearby, pickupCorpse); - goDoFight.addStep(nazNearby, killNazastarool); - goDoFight.addStep(inCavern4, searchDolmenForFight); - steps.put(12, goDoFight); - steps.put(13, goDoFight); - steps.put(14, goDoFight); - - return steps; + cavern1 = new Zone(new WorldPoint(2870, 9330, 0), new WorldPoint(2950, 9407, 0)); + cavern2 = new Zone(new WorldPoint(2878, 9282, 0), new WorldPoint(2942, 9333, 0)); + cavern3 = new Zone(new WorldPoint(2751, 9353, 0), new WorldPoint(2770, 9397, 0)); + cavern4 = new Zone(new WorldPoint(2833, 9463, 0), new WorldPoint(2943, 9533, 0)); } @Override @@ -177,7 +194,8 @@ protected void setupRequirements() charcoal = new ItemRequirement("Charcoal", ItemID.CHARCOAL); crumbleUndead = new ItemRequirement("Crumble undead spell for final boss", -1, -1); - emptySlot3 = new FreeInventorySlotRequirement(3); + freeInvSlot1 = new FreeInventorySlotRequirement(1); + freeInvSlot2 = new FreeInventorySlotRequirement(2); belt = new ItemRequirement("Wampum belt", ItemID.MOSOL_WAMPUM_BELT); stonePlaque = new ItemRequirement("Stone-plaque", ItemID.ZQPLAQUE); @@ -192,20 +210,8 @@ protected void setupRequirements() pommel = new ItemRequirement("Sword pommel", ItemID.ZQBEVSWORD); beads = new ItemRequirement("Bone beads", ItemID.ZQBONEBEADS); beadsOfTheDead = new ItemRequirement("Beads of the dead", ItemID.ZQDEADBEADS); - rashCorpse = new ItemRequirement("Rashiliya corpse", ItemID.ZQCORPSE); - } - - @Override - protected void setupZones() - { - cavern1 = new Zone(new WorldPoint(2870, 9330, 0), new WorldPoint(2950, 9407, 0)); - cavern2 = new Zone(new WorldPoint(2878, 9282, 0), new WorldPoint(2942, 9333, 0)); - cavern3 = new Zone(new WorldPoint(2751, 9353, 0), new WorldPoint(2770, 9397, 0)); - cavern4 = new Zone(new WorldPoint(2833, 9463, 0), new WorldPoint(2943, 9533, 0)); - } + rashCorpse = new ItemRequirement("Rashiliyia corpse", ItemID.ZQCORPSE); - public void setupConditions() - { moundNearby = new ObjectCondition(ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0)); inCavern1 = new ZoneRequirement(cavern1); inCavern2 = new ZoneRequirement(cavern2); @@ -218,25 +224,25 @@ public void setupConditions() ); shownStone = new Conditions(true, LogicType.OR, - new DialogRequirement("If you have found anything else that you need " + - "help with, please just let me know."), + new DialogRequirement("If you have found anything else that you need help with, please just let me know."), new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Trufitus identified the plaque") ); hasReadTattered = new Conditions(true, LogicType.OR, - new WidgetTextRequirement(220, 3, "Bervirius, son of King Danthalas"), + new WidgetTextRequirement(InterfaceID.Messagescroll.MESSCROLL3, "Bervirius, son of King Danthalas"), new VarplayerRequirement(VarPlayerID.ZOMBIEQUEEN, 9, Operation.GREATER_EQUAL) ); hasReadCrumpled = new Conditions(true, LogicType.OR, - new WidgetTextRequirement(222, 3, "Rashiliyia's rage went unchecked."), + new WidgetTextRequirement(InterfaceID.MessagescrollHandwriting.MESSAGESCROLL3_HW, "Rashiliyia's rage went unchecked."), beadsOfTheDead ); revealedDoor = new VarbitRequirement(VarbitID.ZQDOOR_MULTI, 1, Operation.GREATER_EQUAL); doorOpened = new VarbitRequirement(VarbitID.ZQDOOR_MULTI, 2, Operation.GREATER_EQUAL); searchedDoor = new Conditions(true, LogicType.OR, - new WidgetTextRequirement(229, 1, "Examining the door,") + // TODO: This might be able to use varbit ZQDOOR_MULTI == 1 + WidgetTextRequirement.messageBox("Examining the door,") ); nazNearby = new NpcInteractingRequirement(NpcID.ZQ_MAINZOMBIE1, NpcID.ZQ_MAINZOMBIE2, NpcID.ZQ_MAINZOMBIE3); @@ -246,56 +252,44 @@ public void setupConditions() public void setupSteps() { - talkToMosol = new NpcStep(this, NpcID.MOSOL_REI, new WorldPoint(2884, 2951, 0), - "Talk to Mosol Rei east of Shilo Village in south Karamja."); - talkToMosol.addDialogSteps("Why do I need to run?", "Rashiliyia? Who is she?", - "I'll go to see the Shaman.", "Yes, I'm sure and I'll take the Wampum belt to Trufitus."); + talkToMosol = new NpcStep(this, NpcID.MOSOL_REI, new WorldPoint(2884, 2951, 0), "Talk to Mosol Rei east of Shilo Village in south Karamja to receive a wampum belt.", freeInvSlot1); + talkToMosol.addDialogSteps("Why do I need to run?", "Rashiliyia? Who is she?", "I'll go to see the Shaman.", "Yes, I'm sure and I'll take the Wampum belt to Trufitus."); talkToMosol.addDialogStep(1, "What can we do?"); - useBeltOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), - "Use the belt on to Trufitus.", belt.highlighted()); - useBeltOnTrufitus.addIcon(ItemID.MOSOL_WAMPUM_BELT); - useBeltOnTrufitus.addDialogSteps("Mosol Rei said something about a legend?", "Why was it called Ah Za Rhoon?", - "Tell me more.", "I am going to search for Ah Za Rhoon!", - "Yes, I will seriously look for Ah Za Rhoon and I'd appreciate your help.", "Yes."); - useSpadeOnGround = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), - "Use a spade on the ground in south east Karamja.", spade.highlighted()); + + showBeltToTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), "Show the wampum belt to Trufitus in Tai Bwo Wannai village.", belt.highlighted()); + showBeltToTrufitus.addDialogStep("Mosol gave me something to show you."); + showBeltToTrufitus.addDialogStep("Mosol Rei said something about a legend?"); + showBeltToTrufitus.addDialogStep("Why was it called Ah Za Rhoon?"); + showBeltToTrufitus.addDialogStep("I am going to search for Ah Za Rhoon!"); + showBeltToTrufitus.addDialogStep("Yes."); + + useSpadeOnGround = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), "Use a spade on the ground in south east Karamja.", spade.highlighted()); useSpadeOnGround.addIcon(ItemID.SPADE); - lookAtMound = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), - "Look at the mound of earth in south east Karamja."); - useTorchOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), - "Use a lit torch or candle on the fissure.", torchOrCandle.highlighted()); + lookAtMound = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE, new WorldPoint(2922, 3000, 0), "Look at the mound of earth in south east Karamja."); + useTorchOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), "Use a lit torch or candle on the fissure.", torchOrCandle.highlighted()); useTorchOnFissure.addDialogStep("Yes"); useTorchOnFissure.addIcon(ItemID.LIT_CANDLE); useTorchOnFissure.addSubSteps(lookAtMound); - useRopeOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), - "Use a rope on the fissure.", rope.highlighted()); + useRopeOnFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE, new WorldPoint(2922, 3000, 0), "Use a rope on the fissure.", rope.highlighted()); useRopeOnFissure.addIcon(ItemID.ROPE); - searchFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE_WITHROPE, new WorldPoint(2922, 3000, 0), - "Right-click search the fissure."); + searchFissure = new ObjectStep(this, ObjectID.AHZARHOON_ENTRANCE_FISSURE_WITHROPE, new WorldPoint(2922, 3000, 0), "Right-click search the fissure."); searchFissure.addDialogStep("Yes, I'll give it a go!"); - useChiselOnStone = new ObjectStep(this, ObjectID.ZQSECRETSTONE, new WorldPoint(2901, 9379, 0), - "Use a chisel on the strange looking stone to the south.", chisel.highlighted()); + useChiselOnStone = new ObjectStep(this, ObjectID.ZQSECRETSTONE, new WorldPoint(2901, 9379, 0), "Use a chisel on the strange looking stone to the south.", chisel.highlighted()); useChiselOnStone.addIcon(ItemID.CHISEL); - enterDeeperCave = new ObjectStep(this, ObjectID.SECRETRUBBLE, new WorldPoint(2888, 9373, 0), - "Search the cave in to go deeper in the caverns."); + enterDeeperCave = new ObjectStep(this, ObjectID.SECRETRUBBLE, new WorldPoint(2888, 9373, 0), "Search the nearby cave-in to go deeper in the caverns."); enterDeeperCave.addDialogStep("Yes, I'll wriggle through."); - searchForTatteredScroll = new ObjectStep(this, ObjectID.SECRETRUBBLEBOOK, new WorldPoint(2885, 9318, 0), - "Search the loose rocks to the north for a tattered scroll."); + searchForTatteredScroll = new ObjectStep(this, ObjectID.SECRETRUBBLEBOOK, new WorldPoint(2885, 9318, 0), "Search the loose rocks to the north for a tattered scroll."); searchForTatteredScroll.addDialogStep("Yes, I'll carefully move the rocks to see what's behind them."); - searchForCrumpledScroll = new ObjectStep(this, ObjectID.ZQSACKS, new WorldPoint(2939, 9285, 0), - "Search the old sacks to the east for a crumpled scroll."); - searchForCorpse = new ObjectStep(this, ObjectID.ZQGALLOWS, new WorldPoint(2935, 9326, 0), - "Right-click search the gallows in the north east corner for a corpse."); + searchForCrumpledScroll = new ObjectStep(this, ObjectID.ZQSACKS, new WorldPoint(2939, 9285, 0), "Search the old sacks to the east for a crumpled scroll."); + searchForCorpse = new ObjectStep(this, ObjectID.ZQGALLOWS, new WorldPoint(2935, 9326, 0), "Right-click search the gallows in the north east corner for a corpse."); searchForCorpse.addDialogStep("Yes, I may find something else on the corpse."); - useCorpseOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), - "Use Zadimus's corpse on Trufitus.", zadimusCorpse.highlighted()); + useCorpseOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), "Use Zadimus's corpse on Trufitus.", zadimusCorpse.highlighted()); useCorpseOnTrufitus.addDialogStep("Is there any sacred ground around here?"); useCorpseOnTrufitus.addIcon(ItemID.ZQZADIMUSBONES); - useStonePlaqueOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), - "Use the stone-plaque on Trufitus.", stonePlaque.highlighted()); + useStonePlaqueOnTrufitus = new NpcStep(this, NpcID.TRUFITUS, new WorldPoint(2809, 3085, 0), "Use the stone-plaque on Trufitus.", stonePlaque.highlighted()); useStonePlaqueOnTrufitus.addIcon(ItemID.ZQPLAQUE); readTattered = new DetailedQuestStep(this, "Read the tattered scroll.", tatteredScroll.highlighted()); @@ -304,86 +298,152 @@ public void setupSteps() readCrumpled = new DetailedQuestStep(this, "Read the crumpled scroll.", crumpledScroll.highlighted()); readCrumpled.addDialogSteps("Yes please."); - buryCorpse = new DetailedQuestStep(this, new WorldPoint(2795, 3089, 0), - "Bury Zadimus's corpse in the middle of Tai Bwo Wannai.", zadimusCorpse.highlighted()); + buryCorpse = new DetailedQuestStep(this, new WorldPoint(2795, 3089, 0), "Bury Zadimus's corpse in the middle of Tai Bwo Wannai.", zadimusCorpse.highlighted()); buryCorpse.addIcon(ItemID.ZQZADIMUSBONES); - searchRocksOnCairn = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), - "Right-click search the rocks on Cairn Isle."); + searchRocksOnCairn = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), "Right-click search the rocks on Cairn Isle."); searchRocksOnCairn.addDialogSteps("Yes please, I can think of nothing nicer!"); - searchDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), - "Right-click search the dolmen to the south."); - useChiselOnPommel = new DetailedQuestStep(this, "Use a chisel on the pommel.", chisel.highlighted(), - pommel.highlighted()); - useWireOnBeads = new DetailedQuestStep(this, "Use bronze wire on the beads.", bronzeWire.highlighted(), - beads.highlighted()); + searchDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), "Right-click search the tomb dolmen to the south."); + useChiselOnPommel = new DetailedQuestStep(this, "Use a chisel on the pommel.", chisel.highlighted(), pommel.highlighted()); + useWireOnBeads = new DetailedQuestStep(this, "Use bronze wire on the beads.", bronzeWire.highlighted(), beads.highlighted()); - searchPalms = new ObjectStep(this, ObjectID.ZQQUEST_HIDYTREE, new WorldPoint(2916, 3093, 0), - "Search the palm trees in the north east of Karamja. Come equipped for a boss fight.", - List.of(beadsOfTheDead.equipped(), boneShard, chisel, bones3, - combatGear), List.of(crumbleUndead, food)); + searchPalms = new ObjectStep(this, ObjectID.ZQQUEST_HIDYTREE, new WorldPoint(2916, 3093, 0), "Search the palm trees in the north east of Karamja. Come equipped for a boss fight.", List.of(beadsOfTheDead.equipped(), boneShard, chisel, bones3, combatGear), List.of(crumbleUndead, food)); - searchDoors = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), - "Right-click search the doors behind the palm trees.", combatGear); + searchDoors = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), "Right-click search the carved doors behind the palm trees.", combatGear); // 8180 opened? makeKey = new DetailedQuestStep(this, "Use a chisel on the bone shard.", chisel.highlighted(), boneShard.highlighted()); - useKeyOnDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), - "Use the bone key on the doors behind the palm trees.", boneKey.highlighted()); + useKeyOnDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), "Use the bone key on the doors behind the palm trees.", boneKey.highlighted()); useKeyOnDoor.addIcon(ItemID.ZQBONEKEY); - enterDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), - "Enter the doors behind the palm trees.", beadsOfTheDead.equipped(), bones3, - combatGear); - useBonesOnDoor = new ObjectStep(this, ObjectID.THZQ_TOMBROOML1, new WorldPoint(2892, 9480, 0), - "Equip the beads of the dead, then make your way through the gate, down the rocks, then to the south west" + - " corner. Use bones on the door there.", - beadsOfTheDead.equipped(), bones3.highlighted()); + enterDoor = new ObjectStep(this, ObjectID.HILLSIDEDOORR_MULTI, new WorldPoint(2916, 3091, 0), "Enter the doors behind the palm trees.", beadsOfTheDead.equipped(), bones3, combatGear); + useBonesOnDoor = new ObjectStep(this, ObjectID.THZQ_TOMBROOML1, new WorldPoint(2892, 9480, 0), "Equip the beads of the dead, then make your way through the gate, down the rocks, then to the south west corner. Use bones on the door there.", beadsOfTheDead.equipped(), bones3.highlighted()); useBonesOnDoor.addIcon(ItemID.BONES); - searchDolmenForFight = new ObjectStep(this, ObjectID.ZQRASHDOLMEN, new WorldPoint(2893, 9488, 0), - "Search the dolmen, ready to fight."); - - killNazastarool = new NpcStep(this, NpcID.ZQ_MAINZOMBIE1, new WorldPoint(2892, 9488, 0), - "Defeat Nazastarool's 3 forms. You can safe spot them over the dolmen, and the Crumble Undead spell is very" + - " strong against them."); - ((NpcStep) killNazastarool).addAlternateNpcs(NpcID.ZQ_MAINZOMBIE2, NpcID.ZQ_MAINZOMBIE3); - ((NpcStep)killNazastarool).addSafeSpots(new WorldPoint(2894, 9486, 0), new WorldPoint(2891, 9486, 0)); + searchDolmenForFight = new ObjectStep(this, ObjectID.ZQRASHDOLMEN, new WorldPoint(2893, 9488, 0), "Search the tomb dolmen, ready to fight."); + + killNazastarool = new NpcStep(this, NpcID.ZQ_MAINZOMBIE1, new WorldPoint(2892, 9488, 0), "Defeat Nazastarool's 3 forms. You can safe spot them over the tomb dolmen. The Crumble Undead spell is very strong against them."); + killNazastarool.addAlternateNpcs(NpcID.ZQ_MAINZOMBIE2, NpcID.ZQ_MAINZOMBIE3); + killNazastarool.addSafeSpots(new WorldPoint(2894, 9486, 0), new WorldPoint(2891, 9486, 0)); pickupCorpse = new ItemStep(this, "Pickup Rashiliyia's corpse.", rashCorpse); - enterCairnAgain = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), - "Right-click search the rocks on Cairn Isle to enter the caverns again.", rashCorpse); + enterCairnAgain = new ObjectStep(this, ObjectID.ZQROCKS, new WorldPoint(2762, 2990, 0), "Right-click search the rocks on Cairn Isle to enter the caverns again.", rashCorpse); enterCairnAgain.addDialogSteps("Yes please, I can think of nothing nicer!"); - useCorpseOnDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), - "Use Rashiliyia's corpse on the dolmen to the south.", rashCorpse.highlighted()); + useCorpseOnDolmen = new ObjectStep(this, ObjectID.ZQDOLMEN, new WorldPoint(2767, 9365, 0), "Use Rashiliyia's corpse on the dolmen to the south.", rashCorpse.highlighted()); useCorpseOnDolmen.addIcon(ItemID.ZQCORPSE); } @Override - public List getItemRequirements() + public Map loadSteps() { - return Arrays.asList(spade, torchOrCandle, rope, bronzeWire, chisel, bones3); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + var goStartQuest = new ConditionalStep(this, talkToMosol); + goStartQuest.addStep(belt.alsoCheckBank(), showBeltToTrufitus); + steps.put(0, goStartQuest); + + steps.put(1, useSpadeOnGround); + steps.put(2, useSpadeOnGround); + steps.put(3, useSpadeOnGround); + + var lightUpFissure = new ConditionalStep(this, useTorchOnFissure); + lightUpFissure.addStep(moundNearby, lookAtMound); + steps.put(4, lightUpFissure); + + var goUseRope = new ConditionalStep(this, useRopeOnFissure); + goUseRope.addStep(moundNearby, lookAtMound); + steps.put(5, goUseRope); + + var goGetItems = new ConditionalStep(this, searchFissure); + goGetItems.addStep(and(beadsOfTheDead, boneKey), useKeyOnDoor); + goGetItems.addStep(and(beadsOfTheDead, searchedDoor), makeKey); + goGetItems.addStep(and(beadsOfTheDead, revealedDoor), searchDoors); + goGetItems.addStep(and(beadsOfTheDead), searchPalms); + goGetItems.addStep(beads, useWireOnBeads); + goGetItems.addStep(pommel, useChiselOnPommel); + goGetItems.addStep(inCavern3, searchDolmen); + // Stone-plaque may be useless? + // Don't need to show Trufitus bone shard + // Reading tattered unlocks access to the island cavern + // Reading crumpled lets you use bronze wire on beads + goGetItems.addStep(and(stonePlaque, hasReadTattered, hasReadCrumpled, boneShard), searchRocksOnCairn); + goGetItems.addStep(and(stonePlaque, hasReadTattered, crumpledScroll, boneShard), readCrumpled); + goGetItems.addStep(and(stonePlaque, tatteredScroll, crumpledScroll, boneShard), readTattered); + goGetItems.addStep(and(stonePlaque, tatteredScroll, crumpledScroll, zadimusCorpse), buryCorpse); + goGetItems.addStep(and(inCavern2, stonePlaque, tatteredScroll, crumpledScroll), searchForCorpse); + goGetItems.addStep(and(inCavern2, stonePlaque, tatteredScroll), searchForCrumpledScroll); + goGetItems.addStep(and(inCavern2, stonePlaque), searchForTatteredScroll); + goGetItems.addStep(and(inCavern1, stonePlaque), enterDeeperCave); + goGetItems.addStep(inCavern1, useChiselOnStone); + goGetItems.addStep(moundNearby, lookAtMound); + steps.put(6, goGetItems); + steps.put(7, goGetItems); + steps.put(8, goGetItems); + steps.put(9, goGetItems); + + var goToDolem = new ConditionalStep(this, enterDoor); + goToDolem.addStep(inCavern4, useBonesOnDoor); + steps.put(10, goToDolem); + steps.put(11, goToDolem); + + var goDoFight = new ConditionalStep(this, enterDoor); + goDoFight.addStep(and(rashCorpse, inCavern3), useCorpseOnDolmen); + goDoFight.addStep(rashCorpse, enterCairnAgain); + goDoFight.addStep(corpseNearby, pickupCorpse); + goDoFight.addStep(nazNearby, killNazastarool); + goDoFight.addStep(inCavern4, searchDolmenForFight); + steps.put(12, goDoFight); + steps.put(13, goDoFight); + steps.put(14, goDoFight); + + return steps; } @Override - public List getItemRecommended() + public List getGeneralRequirements() { - return Arrays.asList(combatGear, food, staminas, antipoison, prayerPotions, quickTeleport, - papyrus, charcoal, crumbleUndead); + return List.of( + new QuestRequirement(QuestHelperQuest.JUNGLE_POTION, QuestState.FINISHED), + new SkillRequirement(Skill.CRAFTING, 20), + new SkillRequirement(Skill.AGILITY, 32) + ); } + @Override + public List getItemRequirements() + { + return List.of( + spade, + torchOrCandle, + rope, + bronzeWire, + chisel, + bones3 + ); + } @Override - public List getCombatRequirements() + public List getItemRecommended() { - return Collections.singletonList("Nazastarool 3 times (levels 68, 91, 93) (safespottable)"); + return List.of( + combatGear, + food, + staminas, + antipoison, + prayerPotions, + quickTeleport, + papyrus, + charcoal, + crumbleUndead + ); } @Override - public List getGeneralRequirements() + public List getCombatRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.JUNGLE_POTION, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.CRAFTING, 20)); - req.add(new SkillRequirement(Skill.AGILITY, 32)); - return req; + return List.of( + "Nazastarool 3 times (levels 68, 91, 93) (safespottable)" + ); } @Override @@ -395,33 +455,77 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.CRAFTING, 3875)); + return List.of( + new ExperienceReward(Skill.CRAFTING, 3875) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to Shilo Village"), - new UnlockReward("Ability to mine gem rocks in Shilo Village")); + return List.of( + new UnlockReward("Access to Shilo Village"), + new UnlockReward("Ability to mine gem rocks in Shilo Village") + ); } - @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Exploring", - Arrays.asList(talkToMosol, useBeltOnTrufitus, useSpadeOnGround, useTorchOnFissure, useRopeOnFissure, - searchFissure, useChiselOnStone, enterDeeperCave, searchForTatteredScroll, searchForCrumpledScroll, - searchForCorpse, buryCorpse, readTattered, readCrumpled), spade, torchOrCandle, rope, chisel)); - - allSteps.add(new PanelDetails("Free Raiysha", - Arrays.asList(searchRocksOnCairn, searchDolmen, useChiselOnPommel, useWireOnBeads, searchPalms, - searchDoors, makeKey, useKeyOnDoor, enterDoor, useBonesOnDoor, searchDolmenForFight, killNazastarool, - pickupCorpse, enterCairnAgain, useCorpseOnDolmen), List.of(chisel, bronzeWire, bones3), - List.of(combatGear, food, crumbleUndead, prayerPotions))); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Exploring", List.of( + talkToMosol, + showBeltToTrufitus, + useSpadeOnGround, + useTorchOnFissure, + useRopeOnFissure, + searchFissure, + useChiselOnStone, + enterDeeperCave, + searchForTatteredScroll, + searchForCrumpledScroll, + searchForCorpse, + buryCorpse, + readTattered, + readCrumpled + ), List.of( + spade, + torchOrCandle, + rope, + chisel + ), List.of( + freeInvSlot1 + ))); + + sections.add(new PanelDetails("Free Rashiliyia", List.of( + searchRocksOnCairn, + searchDolmen, + useChiselOnPommel, + useWireOnBeads, + searchPalms, + searchDoors, + makeKey, + useKeyOnDoor, + enterDoor, + useBonesOnDoor, + searchDolmenForFight, + killNazastarool, + pickupCorpse, + enterCairnAgain, + useCorpseOnDolmen + ), List.of( + chisel, + bronzeWire, + bones3 + ), List.of( + combatGear, + food, + crumbleUndead, + prayerPotions, + freeInvSlot2 + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java index 5072ce38e9..8bf650269e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/sinsofthefather/DoorPuzzleStep.java @@ -40,9 +40,9 @@ import javax.inject.Inject; import java.awt.*; -import java.util.*; import java.util.List; import java.util.Queue; +import java.util.*; @Slf4j public class DoorPuzzleStep extends DetailedQuestStep @@ -60,7 +60,7 @@ public class DoorPuzzleStep extends DetailedQuestStep private boolean solving = false; - static class PuzzleLine + public static class PuzzleLine { public int[] cells; @@ -96,7 +96,11 @@ public DoorPuzzleStep(BasicQuestHelper questHelper) super(questHelper, "Solve the puzzle by marking the highlighted squares."); } - private PuzzleLine[] solve() + /** + * Entry point used in-game – reads the sums from the puzzle widgets + * and solves the Kakurasu grid. + */ + public PuzzleLine[] solve() { int[] rowSums = new int[SIZE]; int[] colSums = new int[SIZE]; @@ -114,32 +118,81 @@ private PuzzleLine[] solve() } PuzzleState solved = newSolveState(rowSums, colSums); - return solveGrid(solved); + return solveGrid(solved, rowSums, colSums); + } + + /** + * Intended for testing purposes, so we can easily feed in our own puzzles + */ + static PuzzleLine[] solveForSums(int[] rowSums, int[] colSums) + { + DoorPuzzleStep step = new DoorPuzzleStep(null); + PuzzleState solved = step.newSolveState(rowSums, colSums); + return step.solveGrid(solved, rowSums, colSums); + } + + private boolean gridSatisfiesSums(PuzzleLine[] grid, int[] rowSums, int[] colSums) + { + for (int r = 0; r < SIZE; r++) + { + int rowSum = 0; + for (int c = 0; c < SIZE; c++) + { + if (grid[r].cells[c] == FILLED) + { + rowSum += (c + 1); + } + } + if (rowSum != rowSums[r]) + { + return false; + } + } + for (int c = 0; c < SIZE; c++) + { + int colSum = 0; + for (int r = 0; r < SIZE; r++) + { + if (grid[r].cells[c] == FILLED) + { + colSum += (r + 1); + } + } + if (colSum != colSums[c]) + { + return false; + } + } + + return true; } - private PuzzleLine[] solveGrid(PuzzleState puzzleState) + private PuzzleLine[] solveGrid(PuzzleState puzzleState, int[] rowSums, int[] colSums) { int iterations = 0; Queue puzzleStates = new LinkedList<>(); puzzleStates.add(puzzleState); int MAX_ITERATIONS = 20; - while (iterations < MAX_ITERATIONS) + while (iterations < MAX_ITERATIONS && !puzzleStates.isEmpty()) { PuzzleState solution = checkSolutionOverlaps(puzzleStates.remove()); - if (solution == null && puzzleStates.isEmpty()) + if (solution == null) { - return null; + continue; } - else if (solution != null && solution.numberOfGray == 0) - { // If solved - return solution.grid; - } - /* If unable to find answer, assume a square if filled or empty and then try solving again */ - if (solution != null) + if (solution.numberOfGray == 0) { - puzzleStates.add(setFirstUnknownTo(solution, FILLED)); - puzzleStates.add(setFirstUnknownTo(solution, EMPTY)); + if (gridSatisfiesSums(solution.grid, rowSums, colSums)) + { + return solution.grid; + } + + iterations++; + continue; } + /* If unable to find answer, assume a square is filled or empty and then try solving again */ + puzzleStates.add(setFirstUnknownTo(solution, FILLED)); + puzzleStates.add(setFirstUnknownTo(solution, EMPTY)); iterations++; } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java index bc9e2f210b..c81693fed2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/swansong/FishMonkfish.java @@ -31,7 +31,11 @@ import net.runelite.api.ItemContainer; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InventoryID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; import java.util.Arrays; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java index 381941bd11..d9594b25c1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/taibwowannaitrio/TaiBwoWannaiTrio.java @@ -589,7 +589,7 @@ public ArrayList getPanels() smallFishingNet, pestleAndMortar, spear, agilityPotion4, rangedOrMagic, tinderbox, slicedBananaOrKnife, logsForFire)); allSteps.add(new PanelDetails("Gathering quest materials", Arrays.asList(fishKarambwaji, goToLubufu, getMoreVessel, fillVessel, getRum, sliceBanana, makeBananaRum), smallFishingNet, slicedBananaOrKnife)); - allSteps.add(new PanelDetails("Helping Tiadechel", talkToTiadeche1, giveVessel, askAboutResearch)); + allSteps.add(new PanelDetails("Helping Tiadeche", talkToTiadeche1, giveVessel, askAboutResearch)); allSteps.add(new PanelDetails("Collecting final items", Arrays.asList(pickupSeaweed, getJogreBones, burnBones, pickupBurntBones, makeKarambwanjiPaste, usePasteOnBones, getPoisonKarambwan, cookBones, cookKarambwan, usePestleOnKarambwan, usePasteOnSpear), tinderbox, karambwanji, pestleAndMortar)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java index 60ac9eb2ff..04178d1a78 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/templeofikov/TempleOfIkov.java @@ -56,13 +56,13 @@ public class TempleOfIkov extends BasicQuestHelper { //Items Required - ItemRequirement pendantOfLucien, bootsOfLightness, limpwurt20, yewOrBetterBow, knife, lightSource, lever, iceArrows20, iceArrows, shinyKey, + ItemRequirement pendantOfLucien, bootsOfLightness, limpwurt20, yewOrBetterBow, throwableWeapon, yewOrBetterBowOrThrowableWeapon, knife, lightSource, lever, iceArrows20, iceArrowsWithThrowableWeapon, enoughArrows, iceArrows, shinyKey, armadylPendant, staffOfArmadyl, pendantOfLucienEquipped, bootsOfLightnessEquipped, iceArrowsEquipped; Requirement emptyInventorySpot; Requirement belowMinus1Weight, below4Weight, inEntryRoom, inNorthRoom, inBootsRoom, dontHaveBoots, inMainOrNorthRoom, - leverNearby, pulledLever, inArrowRoom, hasEnoughArrows, lesNearby, inLesRoom, inWitchRoom, inDemonArea, + leverNearby, pulledLever, inArrowRoom, hasArrowsWithThrowableWeapon, hasEnoughArrows, lesNearby, inLesRoom, inWitchRoom, inDemonArea, inArmaRoom; QuestStep talkToLucien, prepare, prepareBelow0, enterDungeonForBoots, enterDungeon, goDownToBoots, getBoots, goUpFromBoots, pickUpLever, @@ -181,12 +181,18 @@ protected void setupRequirements() yewOrBetterBow = new ItemRequirement("Yew, magic, or dark bow", ItemID.YEW_SHORTBOW).isNotConsumed(); yewOrBetterBow.addAlternates(ItemID.YEW_LONGBOW, ItemID.TRAIL_COMPOSITE_BOW_YEW, ItemID.MAGIC_SHORTBOW, ItemID.MAGIC_SHORTBOW_I, ItemID.MAGIC_LONGBOW, ItemID.DARKBOW); + throwableWeapon = new ItemRequirement("Throwable Weapon", ItemCollections.THROWING_KNIVES); + throwableWeapon.addAlternates(ItemCollections.DARTS); + throwableWeapon.addAlternates(ItemCollections.THROWING_AXES); + yewOrBetterBowOrThrowableWeapon = new ItemRequirements(LogicType.OR, "Yew, magic, dark bow, or thrown ranged weapons (darts, knives, thrownaxes)", yewOrBetterBow, throwableWeapon); knife = new ItemRequirement("Knife to get the boots of lightness", ItemID.KNIFE).isNotConsumed(); lightSource = new ItemRequirement("A light source to get the boots of lightness", ItemCollections.LIGHT_SOURCES).isNotConsumed(); iceArrows20 = new ItemRequirement("Ice arrows", ItemID.ICE_ARROW, 20); iceArrows = new ItemRequirement("Ice arrows", ItemID.ICE_ARROW); + iceArrowsWithThrowableWeapon = new ItemRequirements(LogicType.AND, "Ice Arrow with Throwable Weapon", iceArrows, throwableWeapon); + enoughArrows = new ItemRequirements(LogicType.OR, "Sufficient Arrows", iceArrows20, iceArrowsWithThrowableWeapon); iceArrowsEquipped = new ItemRequirement("Ice arrows", ItemID.ICE_ARROW, 1, true); lever = new ItemRequirement("Lever", ItemID.IKOV_LEVER); lever.setHighlightInInventory(true); @@ -236,10 +242,11 @@ public void setupConditions() inBootsRoom = new ZoneRequirement(bootsRoom); inMainOrNorthRoom = new Conditions(LogicType.OR, inEntryRoom, inNorthRoom, inLesRoom); - pulledLever = new Conditions(true, LogicType.OR, new WidgetTextRequirement(229, 1, "You hear the clunking of some hidden machinery.")); + pulledLever = new Conditions(true, LogicType.OR, new WidgetTextRequirement(229, 3, "You hear the clunking of some hidden machinery.")); leverNearby = new ObjectCondition(ObjectID.IKOV_MENDEDLEVER, new WorldPoint(2671, 9804, 0)); inArrowRoom = new ZoneRequirement(arrowRoom1, arrowRoom2, arrowRoom3); - hasEnoughArrows = new Conditions(true, LogicType.OR, iceArrows20); + hasArrowsWithThrowableWeapon = new Conditions(true, LogicType.AND, iceArrows, throwableWeapon); + hasEnoughArrows = new Conditions(true, LogicType.OR, iceArrows20, hasArrowsWithThrowableWeapon); lesNearby = new NpcCondition(NpcID.IKOV_FIREWARRIOR); inWitchRoom = new ZoneRequirement(witchRoom); @@ -256,20 +263,20 @@ public void setupSteps() talkToLucien.addDialogSteps("I'm a mighty hero!", "That sounds like a laugh!"); prepare = new DetailedQuestStep(this, "Get your weight below 0kg. You can get boots of lightness from the Temple of Ikov north of East Ardougne for -4.5kg.", - pendantOfLucienEquipped, limpwurt20, yewOrBetterBow); + pendantOfLucienEquipped, limpwurt20, yewOrBetterBowOrThrowableWeapon); prepareBelow0 = new DetailedQuestStep(this, "Get your weight below 0kg.", - pendantOfLucienEquipped, limpwurt20, yewOrBetterBow); + pendantOfLucienEquipped, limpwurt20, yewOrBetterBowOrThrowableWeapon); prepare.addSubSteps(prepareBelow0); enterDungeonForBoots = new ObjectStep(this, ObjectID.LADDER_CELLAR, new WorldPoint(2677, 3405, 0), "Enter the Temple of Ikov. You can get Boots of Lightness inside to get -4.5kg.", - pendantOfLucienEquipped, knife, lightSource, limpwurt20, yewOrBetterBow); + pendantOfLucienEquipped, knife, lightSource, limpwurt20, yewOrBetterBowOrThrowableWeapon); enterDungeon = new ObjectStep(this, ObjectID.LADDER_CELLAR, new WorldPoint(2677, 3405, 0), - "Enter the Temple of Ikov north of East Ardougne.", pendantOfLucienEquipped, yewOrBetterBow, limpwurt20); + "Enter the Temple of Ikov north of East Ardougne.", pendantOfLucienEquipped, yewOrBetterBowOrThrowableWeapon, limpwurt20); enterDungeon.addSubSteps(enterDungeonForBoots); @@ -285,7 +292,7 @@ public void setupSteps() pullLever = new ObjectStep(this, ObjectID.IKOV_MENDEDLEVER, new WorldPoint(2671, 9804, 0), "Pull the lever."); enterArrowRoom = new ObjectStep(this, ObjectID.IKOV_MENDEDLEVERDOORL, new WorldPoint(2662, 9803, 0), "Enter the south gate."); - collectArrows = new ObjectStep(this, ObjectID.IKOV_CHESTCLOSED, "Search the chests in the ice area of this room until you have at least 20 Ice Arrows or more to be safe. A random chest has the arrows each time.", iceArrows20); + collectArrows = new ObjectStep(this, ObjectID.IKOV_CHESTCLOSED, "Search the chests in the ice area of this room until you have at least 20 Ice Arrows or more to be safe. If using a throwable weapon (darts, knives) a single Ice Arrow is sufficient. A random chest has the arrows each time.", enoughArrows); collectArrows.setHideWorldArrow(true); collectArrows.addAlternateObjects(ObjectID.IKOV_CHESTOPEN); @@ -300,10 +307,10 @@ public void setupSteps() goSearchThievingLever.addSubSteps(goPullThievingLever); tryToEnterWitchRoom = new ObjectStep(this, ObjectID.IKOV_FIREWARRIORDOOR, new WorldPoint(2646, 9870, 0), - "Try to enter the far north door. Be prepared to fight Lesarkus, who can only be hurt by ice arrows.", yewOrBetterBow, iceArrowsEquipped); + "Try to enter the far north door. Be prepared to fight Lesarkus, who can only be hurt by ice arrows.", yewOrBetterBowOrThrowableWeapon, iceArrowsEquipped); fightLes = new NpcStep(this, NpcID.IKOV_FIREWARRIOR, new WorldPoint(2646, 9866, 0), - "Kill the Fire Warrior of Lesarkus. He can only be hurt by the ice arrows.", yewOrBetterBow, iceArrowsEquipped); + "Kill the Fire Warrior of Lesarkus. He can only be hurt by the ice arrows.", yewOrBetterBowOrThrowableWeapon, iceArrowsEquipped); enterDungeonKilledLes = new ObjectStep(this, ObjectID.LADDER_CELLAR, new WorldPoint(2677, 3405, 0), "Enter the Temple of Ikov north of East Ardougne.", pendantOfLucienEquipped, limpwurt20); @@ -351,7 +358,7 @@ public void setupSteps() public List getItemRequirements() { ArrayList reqs = new ArrayList<>(); - reqs.add(yewOrBetterBow); + reqs.add(yewOrBetterBowOrThrowableWeapon); reqs.add(limpwurt20); reqs.add(knife); reqs.add(lightSource); @@ -405,7 +412,7 @@ public List getPanels() allSteps.add(new PanelDetails("Defeat Lesarkus", Arrays.asList(prepare, enterDungeon, goDownToBoots, getBoots, goUpFromBoots, pickUpLever, useLeverOnHole, pullLever, enterArrowRoom, collectArrows, returnToMainRoom, goSearchThievingLever, - tryToEnterWitchRoom, fightLes), pendantOfLucien, yewOrBetterBow, knife, lightSource, limpwurt20)); + tryToEnterWitchRoom, fightLes), pendantOfLucien, yewOrBetterBowOrThrowableWeapon, knife, lightSource, limpwurt20)); allSteps.add(new PanelDetails("Explore deeper", Arrays.asList(enterLesDoor, giveWineldaLimps, pickUpKey, pushWall, makeChoice, returnToLucien))); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java index 2d193ec06a..072b4eceb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thecurseofarrav/TheCurseOfArrav.java @@ -50,6 +50,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.QuestState; import net.runelite.api.Skill; +import net.runelite.api.annotations.Varbit; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java index 5bfbab6f2a..efe8d25fee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thedigsite/TheDigSite.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Zoinkwiz + * Copyright (c) 2026, pajlada * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +33,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; @@ -43,145 +47,188 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestSyncStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; - -import java.util.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarPlayerID; +import net.runelite.api.gameval.VarbitID; public class TheDigSite extends BasicQuestHelper { - //Items Required - ItemRequirement pestleAndMortar, vialHighlighted, tinderbox, tea, ropes2, rope, opal, charcoal, specimenBrush, specimenJar, panningTray, - panningTrayFull, trowel, varrock2, digsiteTeleports, sealedLetter, specialCup, teddybear, skull, nitro, nitrate, chemicalCompound, groundCharcoal, invitation, talisman, - mixedChemicals, mixedChemicals2, arcenia, powder, liquid, tablet, key, unstampedLetter, trowelHighlighted, tinderboxHighlighted, chemicalCompoundHighlighted; - - Requirement talkedToFemaleStudent, talkedToOrangeStudent, talkedToGreenStudent, talkedToGuide, letterStamped, hasTeddy, hasSkull, hasSpecialCup, - femaleStudentQ1Learnt, orangeStudentQ1Learnt, greenStudentQ1Learnt, femaleStudentQ2Learnt, orangeStudentQ2Learnt, greenStudentQ2Learnt, femaleStudentQ3Learnt, - femaleExtorting, orangeStudentQ3Learnt, greenStudentQ3Learnt, syncedUp, syncedUp2, syncedUp3, givenTalismanIn, rope1Added, rope2Added, - inUndergroundTemple1, inDougRoom,openedBarrel, searchedBricks, hasKeyOrPowderOrMixtures, openPowderChestNearby, inUndergroundTemple2, - knowStateAsJustStartedQuest, knowStateAsJustCompletedFirstExam, knowStateAsJustCompletedSecondExam; - - QuestStep talkToExaminer, talkToHaig, talkToExaminer2, searchBush, takeTray, talkToGuide, panWater, pickpocketWorkmen, talkToFemaleStudent, talkToFemaleStudent2, - talkToOrangeStudent, talkToOrangeStudent2, talkToGreenStudent, talkToGreenStudent2, takeTest1, talkToFemaleStudent3, talkToOrangeStudent3, talkToGreenStudent3, - takeTest2, talkToFemaleStudent4, takeTest3, getJar, getBrush, digForTalisman, talkToExpert, useInvitationOnWorkman, useRopeOnWinch, goDownWinch, pickUpRoot, - searchBricks, goUpRope, goDownToDoug, talkToDoug, goUpFromDoug, unlockChest, searchChest, useTrowelOnBarrel, useVialOnBarrel, usePowderOnExpert, useLiquidOnExpert, - mixNitroWithNitrate, grindCharcoal, addCharcoal, addRoot, goDownToExplode, useCompound, useTinderbox, takeTablet, useTabletOnExpert, syncStep, talkToFemaleStudent5, - talkToOrangeStudent4, talkToGreenStudent4, useRopeOnWinch2, goDownToExplode2, goDownForTablet, goUpWithTablet, searchPanningTray; - - //Zones - Zone undergroundTemple1, dougRoom, undergroundTemple2; + // Required items + ItemRequirement pestleAndMortar; + ItemRequirement vial; + ItemRequirement tinderbox; + ItemRequirement tea; + ItemRequirement ropes2; + ItemRequirement rope; + ItemRequirement opal; + ItemRequirement charcoal; + + // Recommended items + ItemRequirement varrock2; + ItemRequirement digsiteTeleports; + + // Mid-quest item requirements + ItemRequirement specimenBrush; + ItemRequirement specimenJar; + ItemRequirement panningTray; + ItemRequirement panningTrayFull; + ItemRequirement trowel; + ItemRequirement sealedLetter; + ItemRequirement specialCup; + ItemRequirement teddybear; + ItemRequirement skull; + ItemRequirement nitro; + ItemRequirement nitrate; + ItemRequirement chemicalCompound; + ItemRequirement groundCharcoal; + ItemRequirement invitation; + ItemRequirement talisman; + ItemRequirement mixedChemicals; + ItemRequirement mixedChemicals2; + ItemRequirement arcenia; + + ItemRequirement powder; + ItemRequirement liquid; + ItemRequirement tablet; + ItemRequirement key; + ItemRequirement unstampedLetter; + ItemRequirement trowelHighlighted; + ItemRequirement chemicalCompoundHighlighted; + + // Zones + Zone undergroundTemple1; + Zone undergroundTemple2; + Zone dougRoom; + + // Miscellaneous requirements + Conditions talkedToFemaleStudent; + Conditions talkedToOrangeStudent; + Conditions talkedToGreenStudent; + VarbitRequirement talkedToGuide; + VarbitRequirement letterStamped; + Conditions hasTeddy; + Conditions hasSkull; + Conditions hasSpecialCup; + Conditions femaleStudentQ1Learnt; + Conditions orangeStudentQ1Learnt; + Conditions greenStudentQ1Learnt; + Conditions femaleStudentQ2Learnt; + Conditions orangeStudentQ2Learnt; + Conditions greenStudentQ2Learnt; + Conditions femaleStudentQ3Learnt; + Conditions femaleExtorting; + Conditions orangeStudentQ3Learnt; + Conditions greenStudentQ3Learnt; + Conditions syncedUp; + Conditions syncedUp2; + Conditions syncedUp3; + VarbitRequirement givenTalismanIn; + VarbitRequirement rope1Added; + VarbitRequirement rope2Added; + ZoneRequirement inUndergroundTemple1; + ZoneRequirement inDougRoom; + VarbitRequirement openedBarrel; + VarbitRequirement searchedBricks; + Conditions hasKeyOrPowderOrMixtures; + ObjectCondition openPowderChestNearby; + ZoneRequirement inUndergroundTemple2; + Conditions knowStateAsJustStartedQuest; + Conditions knowStateAsJustCompletedFirstExam; + Conditions knowStateAsJustCompletedSecondExam; + + // Steps + NpcStep talkToExaminer; + NpcStep talkToHaig; + NpcStep talkToExaminer2; + + ObjectStep searchBush; + DetailedQuestStep takeTray; + NpcStep talkToGuide; + ObjectStep panWater; + DetailedQuestStep searchPanningTray; + + NpcStep pickpocketWorkmen; + NpcStep talkToFemaleStudent; + NpcStep talkToOrangeStudent; + NpcStep talkToGreenStudent; + NpcStep talkToFemaleStudent2; + NpcStep talkToOrangeStudent2; + NpcStep talkToGreenStudent2; + NpcStep takeTest1; + + NpcStep talkToFemaleStudent3; + NpcStep talkToOrangeStudent3; + NpcStep talkToGreenStudent3; + NpcStep takeTest2; + + NpcStep talkToFemaleStudent5; + NpcStep talkToOrangeStudent4; + NpcStep talkToGreenStudent4; + NpcStep talkToFemaleStudent4; + NpcStep takeTest3; + + ObjectStep getJar; + NpcStep getBrush; + ObjectStep digForTalisman; + NpcStep talkToExpert; + + NpcStep useInvitationOnWorkman; + ObjectStep useRopeOnWinch; + ObjectStep goDownWinch; + ItemStep pickUpRoot; + ObjectStep searchBricks; + + ObjectStep goUpRope; + ObjectStep useRopeOnWinch2; + ObjectStep goDownToDoug; + NpcStep talkToDoug; + ObjectStep goUpFromDoug; + ObjectStep unlockChest; + ObjectStep searchChest; + ObjectStep useTrowelOnBarrel; + ObjectStep useVialOnBarrel; + NpcStep usePowderOnExpert; + NpcStep useLiquidOnExpert; + DetailedQuestStep mixNitroWithNitrate; + DetailedQuestStep grindCharcoal; + DetailedQuestStep addCharcoal; + DetailedQuestStep addRoot; + ObjectStep goDownToExplode; + ObjectStep goDownToExplode2; + ObjectStep useCompound; + + ObjectStep useTinderbox; + DetailedQuestStep waitForBricksToBlowUp; + ObjectStep takeTablet; + ObjectStep goDownForTablet; + + ObjectStep goUpWithTablet; + NpcStep useTabletOnExpert; + + QuestSyncStep syncStep; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); - - steps.put(0, talkToExaminer); - - ConditionalStep returnWithLetter = new ConditionalStep(this, talkToHaig); - // This is used to set knowStateAsJustStartedQuest to true - returnWithLetter.addStep(new Conditions(LogicType.NOR, knowStateAsJustStartedQuest), talkToExaminer); - returnWithLetter.addStep(letterStamped, talkToExaminer2); - steps.put(1, returnWithLetter); - - ConditionalStep goTakeTest1 = new ConditionalStep(this, syncStep); - // Sets the state of knowStateAsJustCompleted to true for ConditionalStep after this - goTakeTest1.addStep(new Conditions(LogicType.NOR, knowStateAsJustCompletedFirstExam), takeTest1); - - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, orangeStudentQ1Learnt, greenStudentQ1Learnt), takeTest1); - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, orangeStudentQ1Learnt, talkedToGreenStudent), talkToGreenStudent2); - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, orangeStudentQ1Learnt, hasSkull, specimenBrush), - talkToGreenStudent); - - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, talkedToOrangeStudent, hasSkull, specimenBrush), talkToOrangeStudent2); - goTakeTest1.addStep(new Conditions(femaleStudentQ1Learnt, hasSpecialCup, hasSkull, specimenBrush), talkToOrangeStudent); - - goTakeTest1.addStep(new Conditions(talkedToFemaleStudent, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent2); - goTakeTest1.addStep(new Conditions(hasTeddy, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent); - - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, hasSpecialCup), pickpocketWorkmen); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, panningTrayFull, talkedToGuide), searchPanningTray); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, panningTray, talkedToGuide), panWater); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy, panningTray), talkToGuide); - goTakeTest1.addStep(new Conditions(syncedUp, hasTeddy), takeTray); - goTakeTest1.addStep(syncedUp, searchBush); - steps.put(2, goTakeTest1); - - ConditionalStep goTakeTest2 = new ConditionalStep(this, syncStep); - // Sets the state of knowStateAsJustCompletedFirstExam to true for ConditionalStep after this - goTakeTest1.addStep(new Conditions(LogicType.NOR, knowStateAsJustCompletedSecondExam), takeTest2); - - goTakeTest2.addStep(new Conditions(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt, greenStudentQ2Learnt), takeTest2); - goTakeTest2.addStep(new Conditions(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt), talkToGreenStudent3); - goTakeTest2.addStep(new Conditions(syncedUp2, femaleStudentQ2Learnt), talkToOrangeStudent3); - goTakeTest2.addStep(syncedUp2, talkToFemaleStudent3); - steps.put(3, goTakeTest2); - - ConditionalStep goTakeTest3 = new ConditionalStep(this, syncStep); - goTakeTest3.addStep(new Conditions(femaleStudentQ3Learnt, orangeStudentQ3Learnt, greenStudentQ3Learnt), takeTest3); - goTakeTest3.addStep(new Conditions(syncedUp3, femaleStudentQ3Learnt, orangeStudentQ3Learnt), talkToGreenStudent4); - goTakeTest3.addStep(new Conditions(syncedUp3, femaleStudentQ3Learnt), talkToOrangeStudent4); - goTakeTest3.addStep(new Conditions(syncedUp3, femaleExtorting), talkToFemaleStudent5); - goTakeTest3.addStep(syncedUp3, talkToFemaleStudent4); - steps.put(4, goTakeTest3); - - ConditionalStep findTalisman = new ConditionalStep(this, getJar); - findTalisman.addStep(new Conditions(givenTalismanIn), useInvitationOnWorkman); - findTalisman.addStep(new Conditions(talisman), talkToExpert); - findTalisman.addStep(new Conditions(specimenJar, specimenBrush), digForTalisman); - findTalisman.addStep(new Conditions(specimenJar), getBrush); - steps.put(5, findTalisman); - - ConditionalStep learnHowToMakeExplosives = new ConditionalStep(this, useRopeOnWinch2); - learnHowToMakeExplosives.addStep(inDougRoom, talkToDoug); - learnHowToMakeExplosives.addStep(new Conditions(inUndergroundTemple1, arcenia), goUpRope); - learnHowToMakeExplosives.addStep(inUndergroundTemple1, pickUpRoot); - learnHowToMakeExplosives.addStep(new Conditions(rope2Added), goDownToDoug); - - ConditionalStep makeExplosives = new ConditionalStep(this, goDownWinch); - makeExplosives.addStep(new Conditions(chemicalCompound, inUndergroundTemple1), useCompound); - - makeExplosives.addStep(inDougRoom, goUpFromDoug); - makeExplosives.addStep(new Conditions(inUndergroundTemple1, arcenia), goUpRope); - makeExplosives.addStep(inUndergroundTemple1, pickUpRoot); - - makeExplosives.addStep(new Conditions(chemicalCompound), goDownToExplode); - makeExplosives.addStep(new Conditions(arcenia, mixedChemicals2), addRoot); - makeExplosives.addStep(new Conditions(arcenia, mixedChemicals, groundCharcoal), addCharcoal); - makeExplosives.addStep(new Conditions(arcenia, mixedChemicals), grindCharcoal); - makeExplosives.addStep(new Conditions(arcenia, nitrate, nitro), mixNitroWithNitrate); - makeExplosives.addStep(new Conditions(arcenia, powder, nitro), usePowderOnExpert); - makeExplosives.addStep(new Conditions(arcenia, powder, liquid), useLiquidOnExpert); - makeExplosives.addStep(new Conditions(arcenia, powder, liquid), useVialOnBarrel); - makeExplosives.addStep(new Conditions(arcenia, powder, openedBarrel), useVialOnBarrel); - makeExplosives.addStep(new Conditions(arcenia, powder), useTrowelOnBarrel); - makeExplosives.addStep(new Conditions(openPowderChestNearby, arcenia), searchChest); - makeExplosives.addStep(arcenia, unlockChest); - - ConditionalStep discovery = new ConditionalStep(this, useRopeOnWinch); - discovery.addStep(hasKeyOrPowderOrMixtures, makeExplosives); - discovery.addStep(searchedBricks, learnHowToMakeExplosives); - discovery.addStep(new Conditions(inUndergroundTemple1, arcenia), searchBricks); - discovery.addStep(inUndergroundTemple1, pickUpRoot); - discovery.addStep(rope1Added, goDownWinch); - steps.put(6, discovery); - - ConditionalStep explodeWall = new ConditionalStep(this, goDownToExplode2); - explodeWall.addStep(inUndergroundTemple1, useTinderbox); - steps.put(7, explodeWall); - - ConditionalStep completeQuest = new ConditionalStep(this, goDownForTablet); - completeQuest.addStep(new Conditions(tablet.alsoCheckBank(), inUndergroundTemple2), goUpWithTablet); - completeQuest.addStep(new Conditions(tablet.alsoCheckBank()), useTabletOnExpert); - completeQuest.addStep(inUndergroundTemple2, takeTablet); - steps.put(8, completeQuest); - - return steps; + undergroundTemple1 = new Zone(new WorldPoint(3359, 9800, 0), new WorldPoint(3393, 9855, 0)); + undergroundTemple2 = new Zone(new WorldPoint(3360, 9734, 0), new WorldPoint(3392, 9790, 0)); + dougRoom = new Zone(new WorldPoint(3340, 9809, 0), new WorldPoint(3357, 9826, 0)); } @Override @@ -189,10 +236,9 @@ protected void setupRequirements() { pestleAndMortar = new ItemRequirement("Pestle and mortar", ItemID.PESTLE_AND_MORTAR).isNotConsumed(); pestleAndMortar.setHighlightInInventory(true); - vialHighlighted = new ItemRequirement("Vial", ItemID.VIAL_EMPTY); - vialHighlighted.setHighlightInInventory(true); + vial = new ItemRequirement("Vial", ItemID.VIAL_EMPTY); + vial.setHighlightInInventory(true); tinderbox = new ItemRequirement("Tinderbox", ItemID.TINDERBOX).isNotConsumed(); - tinderboxHighlighted = tinderbox.highlighted(); tea = new ItemRequirement("Cup of tea", ItemID.CUP_OF_TEA); ropes2 = new ItemRequirement("Rope", ItemID.ROPE, 2); rope = new ItemRequirement("Rope", ItemID.ROPE); @@ -203,6 +249,10 @@ protected void setupRequirements() charcoal = new ItemRequirement("Charcoal", ItemID.CHARCOAL); charcoal.setTooltip("Obtainable during quest by searching specimen trays"); charcoal.setHighlightInInventory(true); + + varrock2 = new ItemRequirement("Varrock teleports", ItemID.POH_TABLET_VARROCKTELEPORT, 2); + digsiteTeleports = new ItemRequirement("Digsite teleports", ItemID.TELEPORTSCROLL_DIGSITE, 2); + specimenBrush = new ItemRequirement("Specimen brush", ItemID.SPECIMEN_BRUSH).isNotConsumed(); specimenJar = new ItemRequirement("Specimen jar", ItemID.SPECIMEN_JAR).isNotConsumed(); panningTray = new ItemRequirement("Panning tray", ItemID.TRAY_EMPTY).isNotConsumed(); @@ -213,8 +263,6 @@ protected void setupRequirements() trowelHighlighted = new ItemRequirement("Trowel", ItemID.TROWEL).isNotConsumed(); trowelHighlighted.setHighlightInInventory(true); trowelHighlighted.setTooltip("You can get another from one of the Examiners"); - varrock2 = new ItemRequirement("Varrock teleports", ItemID.POH_TABLET_VARROCKTELEPORT, 2); - digsiteTeleports = new ItemRequirement("Digsite teleports", ItemID.TELEPORTSCROLL_DIGSITE, 2); sealedLetter = new ItemRequirement("Sealed letter", ItemID.RECOMMENDEDLETTER); sealedLetter.setTooltip("You can get another from Curator Haig in the Varrock Museum"); specialCup = new ItemRequirement("Special cup", ItemID.ROCK_SAMPLE2); @@ -251,28 +299,15 @@ protected void setupRequirements() key.setHighlightInInventory(true); unstampedLetter = new ItemRequirement("Unstamped letter", ItemID.DIGPLAINLETTER); unstampedLetter.setTooltip("You can get another from the Exam Centre's examiners"); - } - @Override - protected void setupZones() - { - undergroundTemple1 = new Zone(new WorldPoint(3359, 9800, 0), new WorldPoint(3393, 9855, 0)); - undergroundTemple2 = new Zone(new WorldPoint(3360, 9734, 0), new WorldPoint(3392, 9790, 0)); - dougRoom = new Zone(new WorldPoint(3340, 9809, 0), new WorldPoint(3357, 9826, 0)); - } - - public void setupConditions() - { inUndergroundTemple1 = new ZoneRequirement(undergroundTemple1); inUndergroundTemple2 = new ZoneRequirement(undergroundTemple2); inDougRoom = new ZoneRequirement(dougRoom); - knowStateAsJustStartedQuest = new Conditions(true, new VarplayerRequirement(VarPlayerID.ITEXAMLEVEL, 1, Operation.LESS_EQUAL)); knowStateAsJustCompletedFirstExam = new Conditions(true, new VarplayerRequirement(VarPlayerID.ITEXAMLEVEL, 2, Operation.LESS_EQUAL)); knowStateAsJustCompletedSecondExam = new Conditions(true, new VarplayerRequirement(VarPlayerID.ITEXAMLEVEL, 3, Operation.LESS_EQUAL)); - syncedUp = new Conditions(true, LogicType.OR, knowStateAsJustStartedQuest, new WidgetTextRequirement(InterfaceID.Questjournal.TITLE, "The Dig Site")); @@ -282,14 +317,13 @@ public void setupConditions() new DialogRequirement("Hey! Excellent!")); syncedUp3 = new Conditions(true, LogicType.OR, knowStateAsJustCompletedSecondExam, - new WidgetTextRequirement(119, 2, "The Dig Site"), + new WidgetTextRequirement(InterfaceID.Questjournal.TITLE, "The Dig Site"), new DialogRequirement("You got all the questions correct, well done!"), new DialogRequirement("Great, I'm getting good at this.")); talkedToGuide = new VarbitRequirement(VarbitID.ITDIGSITETEA, 1); tea = tea.hideConditioned(talkedToGuide); - // Exam questions 1 talkedToFemaleStudent = new Conditions(true, LogicType.OR, new DialogRequirement("Hey! My lucky mascot!"), @@ -302,7 +336,7 @@ public void setupConditions() orangeGivenAnswer1Diary.addRange(20, 35); talkedToOrangeStudent = new Conditions(true, LogicType.OR, new DialogRequirement("Look what I found!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "to find it and return it to him.")); + new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "He has lost his Special Cup")); orangeStudentQ1Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("The people eligible to use the digsite are:"), orangeGivenAnswer1Diary); @@ -312,7 +346,7 @@ public void setupConditions() talkedToGreenStudent = new Conditions(true, LogicType.OR, new DialogRequirement("Oh wow! You've found it!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "to him; maybe someone has picked it up?")); + new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "He has lost his Animal Skull")); greenStudentQ1Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("The study of Earth Sciences is:"), greenGivenAnswer1Diary); @@ -341,7 +375,7 @@ public void setupConditions() new DialogRequirement("OK, I'll see what I can turn up for you."), new DialogRequirement("Well, I have seen people get them from panning"), new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to bring her an opal")); - WidgetTextRequirement femaleGivenAnswer3Diary = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to speak to the student in the purple skirt about"); + WidgetTextRequirement femaleGivenAnswer3Diary = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to bring her an opal"); femaleGivenAnswer3Diary.addRange(56, 63); femaleStudentQ3Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("Sample preparation: Samples cleaned"), @@ -354,7 +388,7 @@ public void setupConditions() orangeGivenAnswer3Diary); WidgetTextRequirement greenGivenAnswer3Diary = new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I need to speak to the student in the green top about the"); - greenGivenAnswer3Diary.addRange(56, 63); + greenGivenAnswer3Diary.addRange(54, 63); greenStudentQ3Learnt = new Conditions(true, LogicType.OR, new DialogRequirement("Specimen brush use: Brush carefully"), greenGivenAnswer3Diary); @@ -366,25 +400,24 @@ public void setupConditions() rope2Added = new VarbitRequirement(VarbitID.ITDIGSITEWINCH2, 1); // 45 - 54 - hasTeddy = new Conditions(LogicType.OR, teddybear, talkedToFemaleStudent); - hasSkull = new Conditions(LogicType.OR, skull, talkedToGreenStudent); - hasSpecialCup = new Conditions(LogicType.OR, specialCup, talkedToOrangeStudent); + hasTeddy = or(teddybear, talkedToFemaleStudent); + hasSkull = or(skull, talkedToGreenStudent); + hasSpecialCup = or(specialCup, talkedToOrangeStudent); letterStamped = new VarbitRequirement(VarbitID.ITCURATORLETTER, 1); - searchedBricks = new VarbitRequirement(VarbitID.ITDIGSITEHINT, 1); openPowderChestNearby = new ObjectCondition(ObjectID.DIGCHESTOPEN); openedBarrel = new VarbitRequirement(VarbitID.ITDIGSITEBARREL, 1); - hasKeyOrPowderOrMixtures = new Conditions(LogicType.OR, - key, powder, nitrate, mixedChemicals, mixedChemicals2, chemicalCompound, openPowderChestNearby); + hasKeyOrPowderOrMixtures = or(key, powder, nitrate, mixedChemicals, mixedChemicals2, chemicalCompound, openPowderChestNearby); } public void setupSteps() { talkToExaminer = new NpcStep(this, NpcID.EXAMINER, new WorldPoint(3362, 3337, 0), "Talk to an Examiner in the Exam Centre south east of Varrock."); talkToExaminer.addDialogStep("Can I take an exam?"); - ((NpcStep) (talkToExaminer)).addAlternateNpcs(NpcID.QIP_DIGSITE_EXAMINER_02, NpcID.QIP_DIGSITE_EXAMINER_03); + talkToExaminer.addDialogStep("Yes."); + talkToExaminer.addAlternateNpcs(NpcID.QIP_DIGSITE_EXAMINER_02, NpcID.QIP_DIGSITE_EXAMINER_03); talkToHaig = new NpcStep(this, NpcID.CURATOR, new WorldPoint(3257, 3448, 0), "Talk to Curator Haig in the Varrock Museum.", unstampedLetter); talkToExaminer2 = new NpcStep(this, NpcID.EXAMINER, new WorldPoint(3362, 3337, 0), "Return to an Examiner in the Exam Centre south east of Varrock.", sealedLetter); @@ -397,8 +430,8 @@ public void setupSteps() panWater.addSubSteps(searchPanningTray); pickpocketWorkmen = new NpcStep(this, NpcID.DIGWORKMAN1, new WorldPoint(3372, 3390, 0), "Pickpocket workmen until you get an animal skull and a specimen brush.", true); - ((NpcStep) (pickpocketWorkmen)).addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); - ((NpcStep) (pickpocketWorkmen)).setMaxRoamRange(100); + pickpocketWorkmen.addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); + pickpocketWorkmen.setMaxRoamRange(100); talkToFemaleStudent = new NpcStep(this, NpcID.STUDENT2, new WorldPoint(3345, 3425, 0), "Talk to the female student in the north west of the Digsite twice.", teddybear); talkToOrangeStudent = new NpcStep(this, NpcID.STUDENT3, new WorldPoint(3369, 3419, 0), "Talk to the student in an orange shirt in the north east of the Digsite twice.", specialCup); talkToGreenStudent = new NpcStep(this, NpcID.STUDENT1, new WorldPoint(3362, 3398, 0), "Talk to the student in a green shirt in the south of the Digsite twice.", skull); @@ -429,21 +462,22 @@ public void setupSteps() "Brush carefully and slowly using short strokes.", "Handle bones very carefully and keep them away from other samples."); getJar = new ObjectStep(this, ObjectID.QIP_DIGSITE_CUPBOARDSHUT, new WorldPoint(3355, 3332, 0), "Search the cupboard on the south wall of the west room of the Exam Centre for a specimen jar."); - ((ObjectStep) (getJar)).addAlternateObjects(ObjectID.QIP_DIGSITE_CUPBOARDOPEN); + getJar.addAlternateObjects(ObjectID.QIP_DIGSITE_CUPBOARDOPEN); getBrush = new NpcStep(this, NpcID.DIGWORKMAN1, new WorldPoint(3372, 3390, 0), "Pickpocket workmen until you get a specimen brush.", true); - ((NpcStep) (getBrush)).addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); - ((NpcStep) (getBrush)).setMaxRoamRange(100); + getBrush.addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); + getBrush.setMaxRoamRange(100); // NOTE: May not need pick digForTalisman = new ObjectStep(this, ObjectID.DIGDUGUPSOIL2, new WorldPoint(3374, 3438, 0), "Dig in the north east dig spot in the Digsite until you get a talisman.", trowelHighlighted, specimenJar, specimenBrush); digForTalisman.addIcon(ItemID.TROWEL); + digForTalisman.addSubSteps(getBrush); talkToExpert = new NpcStep(this, NpcID.ARCHAEOLOGICAL_EXPERT, new WorldPoint(3357, 3334, 0), "Talk to the Archaeological expert in the Exam Centre.", talisman); useInvitationOnWorkman = new NpcStep(this, NpcID.DIGWORKMAN1, new WorldPoint(3360, 3415, 0), "Use the invitation on any workman.", true, invitation); useInvitationOnWorkman.addIcon(ItemID.DIGEXPERTSCROLL); useInvitationOnWorkman.addDialogStep("I lost the letter you gave me."); - ((NpcStep) (useInvitationOnWorkman)).addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); - ((NpcStep) (useInvitationOnWorkman)).setMaxRoamRange(100); + useInvitationOnWorkman.addAlternateNpcs(NpcID.QIP_DIGSITE_DIGWORKMAN_03, NpcID.QIP_DIGSITE_DIGWORKMAN_04); + useInvitationOnWorkman.setMaxRoamRange(100); useRopeOnWinch = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Use a rope on the west winch.", rope); useRopeOnWinch.addIcon(ItemID.ROPE); goDownWinch = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the west winch."); @@ -463,7 +497,7 @@ public void setupSteps() useTrowelOnBarrel = new ObjectStep(this, ObjectID.DIGBARRELCLOSED, new WorldPoint(3364, 3378, 0), "Use a trowel on the barrel west of the chest's tent.", trowelHighlighted); useTrowelOnBarrel.addIcon(ItemID.TROWEL); - useVialOnBarrel = new ObjectStep(this, ObjectID.DIGBARRELCLOSED, new WorldPoint(3364, 3378, 0), "Use a vial on the barrel west of the chest's tent.", vialHighlighted); + useVialOnBarrel = new ObjectStep(this, ObjectID.DIGBARRELCLOSED, new WorldPoint(3364, 3378, 0), "Use a vial on the barrel west of the chest's tent.", vial); useVialOnBarrel.addIcon(ItemID.VIAL_EMPTY); usePowderOnExpert = new NpcStep(this, NpcID.ARCHAEOLOGICAL_EXPERT, new WorldPoint(3357, 3334, 0), "Use the powder on the Archaeological expert in the Exam Centre.", powder); usePowderOnExpert.addIcon(ItemID.UNIDENTIFIED_POWDER); @@ -471,7 +505,7 @@ public void setupSteps() useLiquidOnExpert.addIcon(ItemID.UNIDENTIFIED_LIQUID); mixNitroWithNitrate = new DetailedQuestStep(this, "Mix the nitroglycerin and ammonium nitrate together.", nitro, nitrate); grindCharcoal = new DetailedQuestStep(this, "Grind charcoal with a pestle and mortar.", pestleAndMortar, charcoal); - addCharcoal = new DetailedQuestStep(this, "Add charcoal to the vial.", groundCharcoal, mixedChemicals); + addCharcoal = new DetailedQuestStep(this, "Add the ground charcoal to the vial.", groundCharcoal, mixedChemicals); addRoot = new DetailedQuestStep(this, "Add arcenia root to the vial.", arcenia, mixedChemicals2); goDownToExplode = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the rope on the west winch.", chemicalCompound, tinderbox); goDownToExplode2 = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the rope on the west winch.", tinderbox); @@ -479,8 +513,10 @@ public void setupSteps() useCompound = new ObjectStep(this, ObjectID.DIGBLASTBRICK, new WorldPoint(3378, 9824, 0), "Use the compound on the bricks to the south.", chemicalCompoundHighlighted); useCompound.addIcon(ItemID.DIGCOMPOUND); - useTinderbox = new ObjectStep(this, ObjectID.DIGBLASTBRICK, new WorldPoint(3378, 9824, 0), "Use a tinderbox on the bricks to the south.", tinderboxHighlighted); + useTinderbox = new ObjectStep(this, ObjectID.DIGBLASTBRICK, new WorldPoint(3378, 9824, 0), "Use a tinderbox on the bricks to the south.", tinderbox.highlighted()); useTinderbox.addIcon(ItemID.TINDERBOX); + waitForBricksToBlowUp = new DetailedQuestStep(this, new WorldPoint(3378, 9824, 0), "Use a tinderbox on the bricks to the south."); + useTinderbox.addSubSteps(waitForBricksToBlowUp); takeTablet = new ObjectStep(this, ObjectID.QIP_DIGSITE_ZAROS_STONE_TABLET_MULTILOC, new WorldPoint(3373, 9746, 0), "Take the stone tablet in the south room."); goDownForTablet = new ObjectStep(this, ObjectID.DIGWINCH1, new WorldPoint(3353, 3417, 0), "Climb down the rope on the west winch."); takeTablet.addSubSteps(goDownForTablet); @@ -490,35 +526,159 @@ public void setupSteps() useTabletOnExpert.addIcon(ItemID.ZAROSSTONETABLET); useTabletOnExpert.addSubSteps(goUpWithTablet); - syncStep = new DetailedQuestStep(this, "Open the quest's journal to sync your current quest state."); + syncStep = new QuestSyncStep(this, getQuest(), "Open the quest's journal to sync your current quest state."); } @Override - public List getNotes() + public Map loadSteps() { - return Collections.singletonList("This quest helper is susceptible to getting out of sync with the actual quest. If this happens to you, opening up the quest's journal should fix it."); + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToExaminer); + + var returnWithLetter = new ConditionalStep(this, talkToHaig); + // This is used to set knowStateAsJustStartedQuest to true + returnWithLetter.addStep(nor(knowStateAsJustStartedQuest), talkToExaminer); + returnWithLetter.addStep(letterStamped, talkToExaminer2); + steps.put(1, returnWithLetter); + + var goTakeTest1 = new ConditionalStep(this, syncStep); + // Sets the state of knowStateAsJustCompleted to true for ConditionalStep after this + goTakeTest1.addStep(nor(knowStateAsJustCompletedFirstExam), takeTest1); + + goTakeTest1.addStep(and(femaleStudentQ1Learnt, orangeStudentQ1Learnt, greenStudentQ1Learnt), takeTest1); + goTakeTest1.addStep(and(femaleStudentQ1Learnt, orangeStudentQ1Learnt, talkedToGreenStudent), talkToGreenStudent2); + goTakeTest1.addStep(and(femaleStudentQ1Learnt, orangeStudentQ1Learnt, hasSkull, specimenBrush), talkToGreenStudent); + + goTakeTest1.addStep(and(femaleStudentQ1Learnt, talkedToOrangeStudent, hasSkull, specimenBrush), talkToOrangeStudent2); + goTakeTest1.addStep(and(femaleStudentQ1Learnt, hasSpecialCup, hasSkull, specimenBrush), talkToOrangeStudent); + + goTakeTest1.addStep(and(talkedToFemaleStudent, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent2); + goTakeTest1.addStep(and(hasTeddy, hasSpecialCup, hasSkull, specimenBrush), talkToFemaleStudent); + + goTakeTest1.addStep(and(syncedUp, hasTeddy, hasSpecialCup), pickpocketWorkmen); + goTakeTest1.addStep(and(syncedUp, hasTeddy, panningTrayFull, talkedToGuide), searchPanningTray); + goTakeTest1.addStep(and(syncedUp, hasTeddy, panningTray, talkedToGuide), panWater); + goTakeTest1.addStep(and(syncedUp, hasTeddy, panningTray), talkToGuide); + goTakeTest1.addStep(and(syncedUp, hasTeddy), takeTray); + goTakeTest1.addStep(syncedUp, searchBush); + steps.put(2, goTakeTest1); + + var goTakeTest2 = new ConditionalStep(this, syncStep); + // Sets the state of knowStateAsJustCompletedFirstExam to true for ConditionalStep after this + goTakeTest1.addStep(nor(knowStateAsJustCompletedSecondExam), takeTest2); + + goTakeTest2.addStep(and(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt, greenStudentQ2Learnt), takeTest2); + goTakeTest2.addStep(and(syncedUp2, femaleStudentQ2Learnt, orangeStudentQ2Learnt), talkToGreenStudent3); + goTakeTest2.addStep(and(syncedUp2, femaleStudentQ2Learnt), talkToOrangeStudent3); + goTakeTest2.addStep(syncedUp2, talkToFemaleStudent3); + steps.put(3, goTakeTest2); + + var goTakeTest3 = new ConditionalStep(this, syncStep); + goTakeTest3.addStep(and(femaleStudentQ3Learnt, orangeStudentQ3Learnt, greenStudentQ3Learnt), takeTest3); + goTakeTest3.addStep(and(syncedUp3, femaleStudentQ3Learnt, orangeStudentQ3Learnt), talkToGreenStudent4); + goTakeTest3.addStep(and(syncedUp3, femaleStudentQ3Learnt), talkToOrangeStudent4); + goTakeTest3.addStep(and(syncedUp3, femaleExtorting), talkToFemaleStudent5); + goTakeTest3.addStep(syncedUp3, talkToFemaleStudent4); + steps.put(4, goTakeTest3); + + var findTalisman = new ConditionalStep(this, getJar); + findTalisman.addStep(and(givenTalismanIn), useInvitationOnWorkman); + findTalisman.addStep(and(talisman), talkToExpert); + findTalisman.addStep(and(specimenJar, specimenBrush), digForTalisman); + findTalisman.addStep(and(specimenJar), getBrush); + steps.put(5, findTalisman); + + var learnHowToMakeExplosives = new ConditionalStep(this, useRopeOnWinch2); + learnHowToMakeExplosives.addStep(inDougRoom, talkToDoug); + learnHowToMakeExplosives.addStep(and(inUndergroundTemple1, arcenia), goUpRope); + learnHowToMakeExplosives.addStep(inUndergroundTemple1, pickUpRoot); + learnHowToMakeExplosives.addStep(and(rope2Added), goDownToDoug); + + var makeExplosives = new ConditionalStep(this, goDownWinch); + makeExplosives.addStep(and(chemicalCompound, inUndergroundTemple1), useCompound); + + makeExplosives.addStep(inDougRoom, goUpFromDoug); + makeExplosives.addStep(and(inUndergroundTemple1, arcenia), goUpRope); + makeExplosives.addStep(inUndergroundTemple1, pickUpRoot); + + makeExplosives.addStep(chemicalCompound, goDownToExplode); + makeExplosives.addStep(and(arcenia, mixedChemicals2), addRoot); + makeExplosives.addStep(and(arcenia, mixedChemicals, groundCharcoal), addCharcoal); + makeExplosives.addStep(and(arcenia, mixedChemicals), grindCharcoal); + makeExplosives.addStep(and(arcenia, nitrate, nitro), mixNitroWithNitrate); + makeExplosives.addStep(and(arcenia, powder, nitro), usePowderOnExpert); + makeExplosives.addStep(and(arcenia, powder, liquid), useLiquidOnExpert); + makeExplosives.addStep(and(arcenia, powder, liquid), useVialOnBarrel); + makeExplosives.addStep(and(arcenia, powder, openedBarrel), useVialOnBarrel); + makeExplosives.addStep(and(arcenia, powder), useTrowelOnBarrel); + makeExplosives.addStep(and(openPowderChestNearby, arcenia), searchChest); + makeExplosives.addStep(arcenia, unlockChest); + + var discovery = new ConditionalStep(this, useRopeOnWinch); + discovery.addStep(hasKeyOrPowderOrMixtures, makeExplosives); + discovery.addStep(searchedBricks, learnHowToMakeExplosives); + discovery.addStep(and(inUndergroundTemple1, arcenia), searchBricks); + discovery.addStep(inUndergroundTemple1, pickUpRoot); + discovery.addStep(rope1Added, goDownWinch); + steps.put(6, discovery); + + var explodeWall = new ConditionalStep(this, goDownToExplode2); + explodeWall.addStep(inUndergroundTemple1, useTinderbox); + steps.put(7, explodeWall); + + var completeQuest = new ConditionalStep(this, goDownForTablet); + completeQuest.addStep(and(tablet.alsoCheckBank(), inUndergroundTemple2), goUpWithTablet); + completeQuest.addStep(and(tablet.alsoCheckBank()), useTabletOnExpert); + completeQuest.addStep(inUndergroundTemple2, takeTablet); + completeQuest.addStep(inUndergroundTemple1, waitForBricksToBlowUp); + steps.put(8, completeQuest); + + return steps; + } + + @Override + public List getGeneralRequirements() + { + return List.of( + new SkillRequirement(Skill.AGILITY, 10, true), + new SkillRequirement(Skill.HERBLORE, 10, true), + new SkillRequirement(Skill.THIEVING, 25) + ); } @Override public List getItemRequirements() { - return Arrays.asList(pestleAndMortar, vialHighlighted, tinderbox, tea, ropes2, opal, charcoal); + return List.of( + pestleAndMortar, + vial, + tinderbox, + tea, + ropes2, + opal, + charcoal + ); } @Override public List getItemRecommended() { - return Arrays.asList(digsiteTeleports, varrock2); + return List.of( + digsiteTeleports, + varrock2 + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - ArrayList req = new ArrayList<>(); - req.add(new SkillRequirement(Skill.AGILITY, 10, true)); - req.add(new SkillRequirement(Skill.HERBLORE, 10, true)); - req.add(new SkillRequirement(Skill.THIEVING, 25)); - return req; + return List.of( + "This quest helper is susceptible to getting out of sync with the actual quest. If this happens to you, opening up the quest's journal should fix it." + ); } @Override @@ -530,38 +690,114 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Arrays.asList( - new ExperienceReward(Skill.MINING, 15300), - new ExperienceReward(Skill.HERBLORE, 2000)); + return List.of( + new ExperienceReward(Skill.MINING, 15300), + new ExperienceReward(Skill.HERBLORE, 2000) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Gold Bars", ItemID.GOLD_BAR, 2)); + return List.of( + new ItemReward("Gold Bars", ItemID.GOLD_BAR, 2) + ); } @Override public List getUnlockRewards() { - return Collections.singletonList(new UnlockReward("Ability to clean specimens in the Varrock Museum")); + return List.of( + new UnlockReward("Ability to clean specimens in the Varrock Museum") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(talkToExaminer, talkToHaig, talkToExaminer2, searchBush, takeTray, talkToGuide, panWater, pickpocketWorkmen, talkToFemaleStudent, talkToFemaleStudent2, - talkToOrangeStudent, talkToOrangeStudent2, talkToGreenStudent, talkToGreenStudent2, takeTest1), tea)); - - allSteps.add(new PanelDetails("Exam 2", Arrays.asList(talkToFemaleStudent3, talkToOrangeStudent3, talkToGreenStudent3, takeTest2))); - allSteps.add(new PanelDetails("Exam 3", Arrays.asList(talkToFemaleStudent4, talkToFemaleStudent5, talkToOrangeStudent4, - talkToGreenStudent4, takeTest3), opal)); - allSteps.add(new PanelDetails("Discovery", Arrays.asList(getJar, digForTalisman, talkToExpert, useInvitationOnWorkman), trowel, specimenBrush)); - allSteps.add(new PanelDetails("Digging deeper", Arrays.asList(useRopeOnWinch, goDownWinch, pickUpRoot, searchBricks, goUpRope, useRopeOnWinch2, goDownToDoug, - talkToDoug, goUpFromDoug, unlockChest, searchChest, useTrowelOnBarrel, useVialOnBarrel, useLiquidOnExpert, usePowderOnExpert, mixNitroWithNitrate, grindCharcoal, addCharcoal, addRoot, goDownToExplode, - useCompound, useTinderbox, takeTablet, useTabletOnExpert), ropes2, trowelHighlighted, pestleAndMortar, vialHighlighted, tinderboxHighlighted, charcoal)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToExaminer, + talkToHaig, + talkToExaminer2, + searchBush, + takeTray, + talkToGuide, + panWater, + pickpocketWorkmen, + talkToFemaleStudent, + talkToFemaleStudent2, + talkToOrangeStudent, + talkToOrangeStudent2, + talkToGreenStudent, + talkToGreenStudent2, + takeTest1 + ), List.of( + tea + ))); + + sections.add(new PanelDetails("Exam 2", List.of( + talkToFemaleStudent3, + talkToOrangeStudent3, + talkToGreenStudent3, + takeTest2 + ))); + + sections.add(new PanelDetails("Exam 3", List.of( + talkToFemaleStudent4, + talkToFemaleStudent5, + talkToOrangeStudent4, + talkToGreenStudent4, + takeTest3 + ), List.of( + opal + ))); + + sections.add(new PanelDetails("Discovery", List.of( + getJar, + digForTalisman, + talkToExpert, + useInvitationOnWorkman + ), List.of( + trowel, + specimenBrush + ))); + + sections.add(new PanelDetails("Digging deeper", List.of( + useRopeOnWinch, + goDownWinch, + pickUpRoot, + searchBricks, + goUpRope, + useRopeOnWinch2, + goDownToDoug, + talkToDoug, + goUpFromDoug, + unlockChest, + searchChest, + useTrowelOnBarrel, + useVialOnBarrel, + useLiquidOnExpert, + usePowderOnExpert, + mixNitroWithNitrate, + grindCharcoal, + addCharcoal, + addRoot, + goDownToExplode, + useCompound, + useTinderbox, + takeTablet, + useTabletOnExpert + ), List.of( + ropes2, + trowelHighlighted, + pestleAndMortar, + vial, + tinderbox, + charcoal + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java index 4c3b5719ac..df73c851db 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefinaldawn/TheFinalDawn.java @@ -50,6 +50,9 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; import net.runelite.client.plugins.microbot.questhelper.steps.*; + +import java.util.*; + import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; import net.runelite.api.QuestState; @@ -61,8 +64,6 @@ import net.runelite.api.gameval.*; import net.runelite.client.eventbus.Subscribe; -import java.util.*; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; /** @@ -509,7 +510,6 @@ private int getSumOfLitBraziers() new WorldPoint(1286, 9438, 1), new WorldPoint(1289, 9435, 1), new WorldPoint(1296, 9435, 1) - ); int total = 0; @@ -612,9 +612,12 @@ protected void setupRequirements() combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); + // Technically only applies for the cultist fight to have these foods available, but as they're recommended last + // It shouldn't impact any existing suggestions for players + food.addAlternates(ItemID.COOKED_LIZARD, ItemID.BREAM_FISH_COOKED); food.setUrlSuffix("Food"); - prayerPotions = new ItemRequirement("Prayer potions", ItemCollections.PRAYER_POTIONS, 3); + prayerPotions.addAlternates(ItemID._4DOSEMOONLIGHTPOTION, ItemID._3DOSEMOONLIGHTPOTION, ItemID._2DOSEMOONLIGHTPOTION, ItemID._1DOSEMOONLIGHTPOTION); whistle = new ItemRequirement("Quetzal whistle", ItemID.HG_QUETZALWHISTLE_BASIC); whistle.addAlternates(ItemID.HG_QUETZALWHISTLE_ENHANCED, ItemID.HG_QUETZALWHISTLE_PERFECTED); @@ -825,7 +828,7 @@ public void setupSteps() enterPassage.addDialogSteps("Enter the passage."); pickBlueChest = new ObjectStep(this, ObjectID.TWILIGHT_TEMPLE_METZLI_CHAMBER_CHEST_CLOSED, new WorldPoint(1723, 9709, 0), "Picklock the chest in the " + "hidden room. Be ready for a fight afterwards."); - fightEnforcer = new NpcStep(this, NpcID.VMQ4_TEMPLE_GUARD_BOSS_FIGHT, new WorldPoint(1712, 9706, 0), "Defeat the enforcer. You cannot use prayers" + + fightEnforcer = new NpcStep(this, NpcID.VMQ4_TEMPLE_GUARD_BOSS_FIGHT, new WorldPoint(1712, 9706, 0), "Defeat the enforcer. You cannot use prayers, or teleport out" + ". Step away each time he goes to attack, and step behind him or sideways if he says 'Traitor!' or 'Thief!'."); pickUpEmissaryScroll = new ItemStep(this, "Pick up the emissary scroll.", emissaryScroll); readEmissaryScroll = new DetailedQuestStep(this, "Read the emissary scroll.", emissaryScroll.highlighted()); @@ -884,7 +887,7 @@ public void setupSteps() showSackToVibia = showSackToVibiaNotPuzzleWrapped.puzzleWrapStep(true); showSackToVibiaNotPuzzleWrapped.addSubSteps(goF2ToF1HideoutEnd, goToF0HideoutEnd); - takePotato.addSubSteps(removePotatoesFromSack, takeKnife, takeCoinPurse, goToF1Hideout, goDownFromF2Hideout, goF1ToF2Hideout, useKnifeOnPottedFan, + takePotato.addSubSteps(takeKnife, takeCoinPurse, goToF1Hideout, goDownFromF2Hideout, goF1ToF2Hideout, useKnifeOnPottedFan, fillCoinPurse, emptyCoinPurse, useBranchOnCoinPurse, goToF0Hideout, goToF0HideoutEnd, goF2ToF1HideoutEnd, showSackToVibia); searchBodyForKey = new NpcStep(this, NpcID.VMQ4_JANUS_HOUSE_JANUS_UNCONSCIOUS, new WorldPoint(1647, 3093, 0), "Search Janus."); @@ -1242,7 +1245,7 @@ public List getPanels() civitasTeleport ))); panels.add(new PanelDetails("The hideout", List.of(talkToQueen, talkToCaptainVibia, inspectWindow, giveBonesOrMeatToDog, enterDoorCode, takePotato, - takeKnife, goToF1Hideout, takeCoinPurse, goF1ToF2Hideout, useKnifeOnPottedFan, fillCoinPurse, useBranchOnCoinPurse, showSackToVibia, + removePotatoesFromSack, takeKnife, goToF1Hideout, takeCoinPurse, goF1ToF2Hideout, useKnifeOnPottedFan, fillCoinPurse, useBranchOnCoinPurse, showSackToVibia, searchBodyForKey, enterTrapdoor, talkToQueenToGoCamTorum), List.of(bone), List.of())); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java index 88a68fe21a..d2142ed6bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theforsakentower/JugPuzzle.java @@ -48,7 +48,6 @@ import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.text.Rs2TextSanitizer; import java.util.*; import java.util.regex.Matcher; @@ -98,7 +97,7 @@ protected void updateSteps() if (widget != null) { - String text = Rs2TextSanitizer.sanitizeWidgetMultilineText(widget.getText()); + String text = widget.getText().replace("
", " "); Matcher jugOnJugMatcher = JUG_VALUES_MATCHER.matcher(text); Matcher jugEmptiedMatcher = JUG_EMPTIED.matcher(text); Matcher jugFilledMatcher = JUG_FILLED.matcher(text); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java index 9eeb50b5f3..28db2ffcf3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremennikisles/TheFremennikIsles.java @@ -632,7 +632,7 @@ public List getPanels() allSteps.add(new PanelDetails("Collecting beard tax", Arrays.asList(collectFromHringAgain, collectFromRaum, collectFromSkuliAgain, collectFromKeepaAgain, collectFromFlosi, talkToGjukiAfterCollection2))); allSteps.add(new PanelDetails("Spy on Mawnis again", Arrays.asList(talkToSlugToSpyAgain, goSpyOnMawnisAgain, reportBackToSlugAgain, talkToGjukiAfterSpy2, talkToMawnisWithDecree))); allSteps.add(prepareForCombatPanel); - allSteps.add(new PanelDetails("Killing the king", Arrays.asList(enterCave, killTrolls, enterKingRoom, killKing, decapitateKing, finishQuest), yakBottom, yakTop, roundShield, meleeWeapon, food)); + allSteps.add(new PanelDetails("Killing the king", Arrays.asList(enterCave, killTrolls, enterKingRoom, killKing, decapitateKing, finishQuest), roundShield, meleeWeapon, food)); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java index 1dca85d6b7..6ff93e4e06 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thefremenniktrials/TheFremennikTrials.java @@ -49,7 +49,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -298,7 +302,7 @@ protected void setupRequirements() petRock = new ItemRequirement("Pet rock", ItemID.VT_USELESS_ROCK).isNotConsumed(); petRock.setTooltip("You can get another from Askeladden"); - emptySlot4 = new ItemRequirement("4 empty inventory slots", -1, 4); + emptySlot4 = new ItemRequirement("Empty inventory slots for vegetables and a pet rock", -1, 4); goldenWool = new ItemRequirement("Golden wool", ItemID.VIKING_GOLDEN_WOOL); goldenFleece = new ItemRequirement("Golden fleece", ItemID.VIKING_GOLDEN_FLEECE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java index e3d178d04c..9c5d0faa82 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thegolem/TheGolem.java @@ -32,6 +32,8 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.TeleportItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitBuilder; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; @@ -40,7 +42,15 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -48,14 +58,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; - public class TheGolem extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java index 74be88eb58..af474f4d6d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theheartofdarkness/TheHeartOfDarkness.java @@ -27,6 +27,7 @@ import com.google.common.collect.Lists; import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; +import net.runelite.client.plugins.microbot.questhelper.domain.QuetzalDestination; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.secretsofthenorth.ArrowChestPuzzleStep; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; @@ -37,6 +38,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NoFollowerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.InInstanceRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; @@ -93,6 +95,8 @@ public class TheHeartOfDarkness extends BasicQuestHelper ItemRequirement towerKey, book, poem, scrapOfPaper1, scrapOfPaper2, scrapOfPaper3, completedNote, emissaryHood, emissaryTop, emissaryBottom, emissaryBoots, emissaryRobesEquipped, emissaryRobes, airIcon, waterIcon, earthIcon, fireIcon; + NoFollowerRequirement noFollower; + Requirement atTeomat, builtLandingInOverlook, talkedToSergius, talkedToCaritta, talkedToFelius, princeIsFollowing, inFirstTrialRoom, inSecondTrialRoom, southEastGateUnlocked, southWestChestOpened, hasReadPoem, knowAboutDirections, inArrowPuzzle, combatStarted, startedInvestigation, freeInvSlots4; @@ -406,6 +410,7 @@ protected void setupRequirements() fireIcon = new ItemRequirement("Fire icon", ItemID.VMQ3_RUINS_FIRE_STATUE_REPAIR); + noFollower = new NoFollowerRequirement("No pet following you"); } private void setupConditions() @@ -542,15 +547,11 @@ private void setupSteps() { talkToItzlaAtTeomat = new NpcStep(this, NpcID.VMQ2_ITZLA_VIS, new WorldPoint(1454, 3173, 0), "Talk to Prince Itzla Arkan at the Teomat. You" + " can travel here using Renu the quetzal."); - WidgetHighlight teomatWidget = new WidgetHighlight(874, 15, true); - teomatWidget.setModelIdRequirement(51205); - talkToItzlaAtTeomat.addWidgetHighlight(teomatWidget); + talkToItzlaAtTeomat.addWidgetHighlight(WidgetHighlight.createQuetzalHighlight(QuetzalDestination.THE_TEOMAT)); talkToItzlaAtTeomat.addDialogStep("Yes."); travelToGorge = new NpcStep(this, NpcID.QUETZAL_CHILD_GREEN_NOOP, new WorldPoint(1437, 3169, 0), "Travel on Renu to the Quetzacalli Gorge."); ((NpcStep) travelToGorge).addAlternateNpcs(NpcID.QUETZAL_CHILD_GREEN_FEED, NpcID.QUETZAL_CHILD_GREEN, NpcID.QUETZAL_CHILD_ORANGE, NpcID.QUETZAL_CHILD_BLUE, NpcID.QUETZAL_CHILD_CYAN, NpcID.QUETZAL_CHILD_GREEN_ORANGE); - WidgetHighlight gorgeWidget = new WidgetHighlight(874, 15, true); - gorgeWidget.setModelIdRequirement(54539); - travelToGorge.addWidgetHighlight(gorgeWidget); + travelToGorge.addWidgetHighlight(WidgetHighlight.createQuetzalHighlight(QuetzalDestination.QUETZACALLI_GORGE)); talkToBartender = new NpcStep(this, NpcID.QUETZACALLI_BARTENDER, new WorldPoint(1499, 3224, 0), "Talk to the Bartender in the pub in the Gorge.", coins.quantity(30)); // Told about ground room, 11123 1->0 @@ -635,7 +636,7 @@ private void setupSteps() talkToFelius = new NpcStep(this, NpcID.VMQ3_RECRUIT_1_VIS, new WorldPoint(1659, 3224, 0), "Talk to Felius outside the tower."); talkToCaritta = new NpcStep(this, NpcID.VMQ3_RECRUIT_2_VIS, new WorldPoint(1659, 3224, 0), "Talk to Caritta outside the tower."); talkToPrinceAfterRecruits = new NpcStep(this, NpcID.VMQ3_ITZLA_VIS_CITIZEN, new WorldPoint(1656, 3219, 0), "Talk to the prince at the Tower " + - "of Ascension to the south-east of the salvager overlook again."); + "of Ascension to the south-east of the salvager overlook again.", noFollower); talkToPrinceAfterRecruits.addDialogStep("Could you remind me what Ximoua is?"); talkToJanus = new NpcStep(this, NpcID.VMQ3_FOREBEARER_JANUS_VIS, new WorldPoint(1638, 3224, 0), "Talk to Forebearer Janus inside the tower."); @@ -966,6 +967,7 @@ private void setupSteps() talkToServius = new NpcStep(this, NpcID.VMQ3_SERVIUS_VIS, new WorldPoint(1681, 3168, 0), "Talk to Servius, Teokan of Ralos in the palace" + " in Civitas illa Fortis to complete the quest."); + talkToServius.addWidgetHighlight(WidgetHighlight.createQuetzalHighlight(QuetzalDestination.CIVITAS_ILLA_FORTIS)); talkToServius.addTeleport(civitasIllaFortisTeleport); } @@ -1154,7 +1156,7 @@ public List getPanels() allSteps.add(new PanelDetails("Final Trial", List.of(fightPrinceSidebar, talkToJanusAfterPrinceFight))); allSteps.add(new PanelDetails("Cult", List.of(talkToJanusAfterAllTrials, searchChestForEmissaryRobes, talkToItzlaToFollow, enterTemple, talkToItzlaAfterSermon, talkToFides))); allSteps.add(new PanelDetails("The Old Ones", List.of(enterRuins, takePickaxe, mineRocks, pullFirstLever, climbDownLedge, slideAlongIceLedge, pullSecondLever, jumpOverFrozenPlatforms, pullThirdLever, - pullFourthLever, pullChain, inspectAirMarkings, inspectEarthMarkings, searchAirUrn, searchEarthUrn, inspectWaterMarkings, inspectFireMarkings, + pullFourthLever, pullChain, climbDownIceShortcut, inspectAirMarkings, inspectEarthMarkings, searchAirUrn, searchEarthUrn, inspectWaterMarkings, inspectFireMarkings, searchFireUrn, searchWaterUrn, fixWaterStatue, fixFireStatue, fixEarthStatue, fixAirStatue, activateFirstStatue, activateSecondStatue, activateThirdStatue, activateFourthStatue, enterFinalBossRoom, defeatAmoxliatlSidebar, talkToServius), List.of(combatGear, freeInvSlots4), List.of(food, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theidesofmilk/TheIdesOfMilk.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theidesofmilk/TheIdesOfMilk.java new file mode 100644 index 0000000000..8df4efc5d0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theidesofmilk/TheIdesOfMilk.java @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2026, adamsbytes + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.helpers.quests.theidesofmilk; + +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; +import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.CombatLevelRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; +import net.runelite.client.plugins.microbot.questhelper.util.QHObjectID; +import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; + +public class TheIdesOfMilk extends BasicQuestHelper +{ + // Recommended items + ItemRequirement combatGear; + ItemRequirement food; + + // Mid-quest item requirements + ItemRequirement husbandryBook; + ItemRequirement milkSample1; + ItemRequirement milkSample2; + + // Zones + Zone lumbridgeCastleF1; + + // Miscellaneous requirements + VarbitRequirement gillieInformed; + ZoneRequirement inLumbridgeCastleF1; + NpcCondition brutusNearby; + + // Steps + NpcStep talkToCassius; + NpcStep talkToGillie; + NpcStep talkToSeth; + ObjectStep searchShelves; + NpcStep returnToCassiusWithBook; + NpcStep talkToCassiusAboutBook; + DetailedQuestStep drinkMilkSample1; + NpcStep talkToCassiusAfterDrink; + ObjectStep goUpToLumbridgeCastleF1; + NpcStep talkToDuke; + NpcStep talkToGillieAgain; + DetailedQuestStep drinkMilkSample2; + NpcStep talkToGillieAfterDrink; + ObjectStep openBullPen; + NpcStep killBrutus; + NpcStep talkToGillieAfterFight; + NpcStep finishQuest; + + @Override + protected void setupZones() + { + lumbridgeCastleF1 = new Zone(new WorldPoint(3203, 3206, 1), new WorldPoint(3218, 3231, 1)); + } + + @Override + protected void setupRequirements() + { + husbandryBook = new ItemRequirement("The groats principles", ItemID.COWQUEST_HUSBANDRY_BOOK); + husbandryBook.canBeObtainedDuringQuest(); + + milkSample1 = new ItemRequirement("Milk sample", ItemID.COWQUEST_MILK_SAMPLE_1); + milkSample1.canBeObtainedDuringQuest(); + milkSample1.setTooltip("You can get another from Cassius"); + + milkSample2 = new ItemRequirement("Milk sample", ItemID.COWQUEST_MILK_SAMPLE_2); + milkSample2.canBeObtainedDuringQuest(); + milkSample2.setTooltip("You can get another from Cassius"); + + gillieInformed = new VarbitRequirement(VarbitID.COWQUEST_GILLIE_INFORMATION, 1); + inLumbridgeCastleF1 = new ZoneRequirement(lumbridgeCastleF1); + + combatGear = new ItemRequirement("Combat gear", -1, -1).isNotConsumed(); + combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); + + food = new ItemRequirement("Food", -1, -1); + food.setDisplayItemId(BankSlotIcons.getFood()); + } + + public void setupSteps() + { + talkToCassius = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Speak to Cassius by the pond north-west of Lumbridge to start the quest.", true); + talkToCassius.addDialogStep("Yes."); + + talkToGillie = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Speak to Gillie Groats at the cow field east of Lumbridge."); + talkToGillie.addDialogStep("Can you share what makes your cows so productive?"); + + talkToSeth = new NpcStep(this, NpcID.FAVOUR_SETH_GROATS, + new WorldPoint(3228, 3291, 0), + "Speak to Seth Groats at his farmhouse east of the River Lum."); + + searchShelves = new ObjectStep(this, ObjectID.COWQUEST_SETH_SHELF, + new WorldPoint(3227, 3287, 0), + "Search the shelves in Seth's farmhouse for 'The groats principles'."); + + returnToCassiusWithBook = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Return to Cassius with the book.", true, husbandryBook); + + talkToCassiusAboutBook = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Talk to Cassius.", true); + returnToCassiusWithBook.addSubSteps(talkToCassiusAboutBook); + + drinkMilkSample1 = new DetailedQuestStep(this, + "Drink the milk sample near Cassius.", milkSample1.highlighted()); + + talkToCassiusAfterDrink = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Talk to Cassius after drinking the milk sample.", true); + + goUpToLumbridgeCastleF1 = new ObjectStep(this, QHObjectID.LUMBRIDGE_CASTLE_F0_SOUTH_STAIRCASE, + new WorldPoint(3205, 3208, 0), + "Speak to Duke Horacio on the first floor of Lumbridge Castle.", milkSample2); + + talkToDuke = new NpcStep(this, NpcID.DUKE_OF_LUMBRIDGE, + new WorldPoint(3210, 3220, 1), + "Speak to Duke Horacio on the first floor of Lumbridge Castle.", milkSample2); + talkToDuke.addSubSteps(goUpToLumbridgeCastleF1); + + talkToGillieAgain = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Speak to Gillie Groats at the cow field."); + + drinkMilkSample2 = new DetailedQuestStep(this, + "Drink the milk sample near Gillie.", milkSample2.highlighted()); + + talkToGillieAfterDrink = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Talk to Gillie Groats after drinking the milk sample."); + + brutusNearby = new NpcCondition(NpcID.COWBOSS); + + openBullPen = new ObjectStep(this, ObjectID.FENCEGATE_L_COWBOSS_START, + new WorldPoint(3262, 3294, 0), + "Open the bull pen gate in the north-east corner of the cow field to fight the Bull (level 30).", + combatGear, food); + openBullPen.addDialogStep("Yes."); + + killBrutus = new NpcStep(this, NpcID.COWBOSS, + new WorldPoint(3262, 3294, 0), + "Kill the Bull (level 30). Protect from Melee blocks his basic attacks (max hit 3). Dodge his ground slam ('snorts') and charge ('growls') by walking through him. Special attacks can hit over 15.", + combatGear, food); + openBullPen.addSubSteps(killBrutus); + + talkToGillieAfterFight = new NpcStep(this, NpcID.GILLIE_THE_MILKMAID, + new WorldPoint(3253, 3270, 0), + "Speak to Gillie Groats after defeating the Bull."); + + finishQuest = new NpcStep(this, NpcID.COWBOSS_FARMER, + new WorldPoint(3171, 3277, 0), + "Return to Cassius to complete the quest. You can then speak to Gillie Groats for a cow bell amulet and magic lamp (1,000 XP combat/Prayer).", true); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToCassius); + steps.put(1, talkToCassius); + steps.put(2, talkToCassius); + + var cInvestigate = new ConditionalStep(this, talkToGillie); + cInvestigate.addStep(gillieInformed, talkToSeth); + steps.put(3, cInvestigate); + + var cGetBook = new ConditionalStep(this, searchShelves); + cGetBook.addStep(husbandryBook, returnToCassiusWithBook); + steps.put(4, cGetBook); + var cReturnBook = new ConditionalStep(this, talkToCassiusAboutBook); + cReturnBook.addStep(husbandryBook, returnToCassiusWithBook); + steps.put(5, cReturnBook); + + steps.put(6, drinkMilkSample1); + steps.put(8, talkToCassiusAfterDrink); + var cTalkToDuke = new ConditionalStep(this, goUpToLumbridgeCastleF1); + cTalkToDuke.addStep(inLumbridgeCastleF1, talkToDuke); + steps.put(10, cTalkToDuke); + steps.put(12, talkToGillieAgain); + steps.put(14, drinkMilkSample2); + steps.put(16, talkToGillieAfterDrink); + var cFightBrutus = new ConditionalStep(this, openBullPen); + cFightBrutus.addStep(brutusNearby, killBrutus); + steps.put(18, cFightBrutus); + steps.put(20, talkToGillieAfterFight); + steps.put(21, finishQuest); + + return steps; + } + + @Override + public List getGeneralRecommended() + { + return List.of( + new CombatLevelRequirement(15) + ); + } + + @Override + public List getItemRecommended() + { + return List.of(combatGear, food); + } + + @Override + public List getCombatRequirements() + { + return List.of("Bull (level 30)"); + } + + @Override + public QuestPointReward getQuestPointReward() + { + return new QuestPointReward(1); + } + + @Override + public List getUnlockRewards() + { + return List.of( + new UnlockReward("Access to the cow boss"), + new UnlockReward("Cow bell amulet and magic lamp (1,000 XP combat/Prayer) from Gillie Groats") + ); + } + + @Override + public List getPanels() + { + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToCassius + ))); + + sections.add(new PanelDetails("Investigation", List.of( + talkToGillie, + talkToSeth, + searchShelves + ))); + + sections.add(new PanelDetails("Milk tasting", List.of( + returnToCassiusWithBook, + drinkMilkSample1, + talkToCassiusAfterDrink + ))); + + sections.add(new PanelDetails("The Duke's opinion", List.of( + talkToDuke, + talkToGillieAgain, + drinkMilkSample2, + talkToGillieAfterDrink + ))); + + sections.add(new PanelDetails("The bull fight", List.of( + openBullPen, + talkToGillieAfterFight + ), combatGear, food)); + + sections.add(new PanelDetails("Finishing up", List.of( + finishQuest + ))); + + return sections; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java index 905025d564..74cf09c84d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theknightssword/TheKnightsSword.java @@ -27,13 +27,10 @@ import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.requirements.ComplexRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; @@ -43,97 +40,99 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - +// TODO: fix typo in Sir Vyvin's name public class TheKnightsSword extends BasicQuestHelper { - //Items Required - ItemRequirement pickaxe, redberryPie, ironBars, bluriteOre, bluriteSword, portrait; + // Required items + ItemRequirement redberryPie; + ItemRequirement ironBars; + ItemRequirement bluriteOre; + ItemRequirement pickaxe; - //Items Recommended - ItemRequirement varrockTeleport, faladorTeleports, homeTele; - ComplexRequirement searchCupboardReq; + // Recommended items + ItemRequirement varrockTeleport; + ItemRequirement faladorTeleports; + ItemRequirement homeTele; - Requirement inDungeon, inFaladorCastle1, inFaladorCastle2, inFaladorCastle2Bedroom, sirVyinNotInRoom; + // Mid-quest item requirements + ItemRequirement bluriteSword; + ItemRequirement portrait; - QuestStep talkToSquire, talkToReldo, talkToThurgo, talkToThurgoAgain, talkToSquire2, goUpCastle1, goUpCastle2, searchCupboard, enterDungeon, - mineBlurite, givePortraitToThurgo, bringThurgoOre, finishQuest; + // Zones + Zone dungeon; + Zone faladorCastle1; + Zone faladorCastle2; + Zone faladorCastle2Bedroom; - //Zones - Zone dungeon, faladorCastle1, faladorCastle2, faladorCastle2Bedroom; + // Miscellaneous requirements + NpcRequirement sirVyvinNotInRoom; + ZoneRequirement inDungeon; + ZoneRequirement inFaladorCastle1; + ZoneRequirement inFaladorCastle2; + ZoneRequirement inFaladorCastle2Bedroom; - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); + // Steps + NpcStep talkToSquire; - steps.put(0, talkToSquire); - steps.put(1, talkToReldo); - steps.put(2, talkToThurgo); - steps.put(3, talkToThurgoAgain); - steps.put(4, talkToSquire2); + NpcStep talkToReldo; - ConditionalStep getPortrait = new ConditionalStep(this, goUpCastle1); - getPortrait.addStep(portrait.alsoCheckBank(), givePortraitToThurgo); - getPortrait.addStep(inFaladorCastle2, searchCupboard); - getPortrait.addStep(inFaladorCastle1, goUpCastle2); + NpcStep talkToThurgo; - steps.put(5, getPortrait); + NpcStep talkToThurgoAgain; - ConditionalStep returnSwordToSquire = new ConditionalStep(this, enterDungeon); - returnSwordToSquire.addStep(bluriteSword.alsoCheckBank(), finishQuest); - returnSwordToSquire.addStep(bluriteOre.alsoCheckBank(), bringThurgoOre); - returnSwordToSquire.addStep(inDungeon, mineBlurite); + NpcStep talkToSquire2; - steps.put(6, returnSwordToSquire); + ObjectStep goUpCastle1; + ObjectStep goUpCastle2; + ObjectStep searchCupboard; + NpcStep givePortraitToThurgo; - return steps; + ObjectStep enterDungeon; + ObjectStep mineBlurite; + NpcStep bringThurgoOre; + NpcStep finishQuest; + + @Override + protected void setupZones() + { + dungeon = new Zone(new WorldPoint(2979, 9538, 0), new WorldPoint(3069, 9602, 0)); + faladorCastle1 = new Zone(new WorldPoint(2954, 3328, 1), new WorldPoint(2997, 3353, 1)); + faladorCastle2 = new Zone(new WorldPoint(2980, 3331, 2), new WorldPoint(2986, 3346, 2)); + faladorCastle2Bedroom = new Zone(new WorldPoint(2981, 3336, 2), new WorldPoint(2986, 3331, 2)); } @Override protected void setupRequirements() { redberryPie = new ItemRequirement("Redberry pie", ItemID.REDBERRY_PIE); + redberryPie.setTooltip("Purchasable from the grand exchange, or for ironmen: 10 cooking to cook one, or 32 cooking and a chef's hat to buy one from the Cooks' Guild."); ironBars = new ItemRequirement("Iron bar", ItemID.IRON_BAR, 2); bluriteOre = new ItemRequirement("Blurite ore", ItemID.BLURITE_ORE); - bluriteSword = new ItemRequirement("Blurite sword", ItemID.FALADIAN_SWORD); pickaxe = new ItemRequirement("Any pickaxe", ItemCollections.PICKAXES).isNotConsumed(); + varrockTeleport = new ItemRequirement("A teleport to Varrock", ItemID.POH_TABLET_VARROCKTELEPORT); - faladorTeleports = new ItemRequirement("Teleports to Falador", ItemID.POH_TABLET_FALADORTELEPORT, 4); - homeTele = new ItemRequirement("A teleport near Mudskipper Point, such as POH teleport or Fairy Ring to AIQ", - ItemID.NZONE_TELETAB_RIMMINGTON, 2); + faladorTeleports = new ItemRequirement("Teleports to Falador", ItemID.POH_TABLET_FALADORTELEPORT, 3); + homeTele = new ItemRequirement("A teleport near Mudskipper Point, such as POH teleport or Fairy Ring to AIQ", ItemID.NZONE_TELETAB_RIMMINGTON, 2); + + bluriteSword = new ItemRequirement("Blurite sword", ItemID.FALADIAN_SWORD); portrait = new ItemRequirement("Portrait", ItemID.KNIGHTS_PORTRAIT); - } - public void setupConditions() - { inDungeon = new ZoneRequirement(dungeon); inFaladorCastle1 = new ZoneRequirement(faladorCastle1); inFaladorCastle2 = new ZoneRequirement(faladorCastle2); inFaladorCastle2Bedroom = new ZoneRequirement(faladorCastle2Bedroom); - sirVyinNotInRoom = new NpcCondition(NpcID.SIR_VYVIN, faladorCastle2Bedroom); - NpcRequirement sirVyinNotInRoom = new NpcRequirement("Sir Vyin not in the bedroom.", NpcID.SIR_VYVIN, true, faladorCastle2Bedroom); - ZoneRequirement playerIsUpstairs = new ZoneRequirement("Upstairs", faladorCastle2); - searchCupboardReq = new ComplexRequirement(LogicType.AND, "Sir Vyin not in the bedroom.", playerIsUpstairs, sirVyinNotInRoom); - } - - @Override - protected void setupZones() - { - dungeon = new Zone(new WorldPoint(2979, 9538, 0), new WorldPoint(3069, 9602, 0)); - faladorCastle1 = new Zone(new WorldPoint(2954, 3328, 1), new WorldPoint(2997, 3353, 1)); - faladorCastle2 = new Zone(new WorldPoint(2980, 3331, 2), new WorldPoint(2986, 3346, 2)); - faladorCastle2Bedroom = new Zone(new WorldPoint(2981, 3336, 2), new WorldPoint(2986, 3331, 2)); + sirVyvinNotInRoom = new NpcRequirement("Sir Vyvin not in the bedroom.", NpcID.SIR_VYVIN, true, faladorCastle2Bedroom); } public void setupSteps() @@ -142,60 +141,118 @@ public void setupSteps() talkToSquire.addDialogStep("And how is life as a squire?"); talkToSquire.addDialogStep("I can make a new sword if you like..."); talkToSquire.addDialogStep("So would these dwarves make another one?"); - talkToSquire.addDialogStep("Ok, I'll give it a go."); talkToSquire.addDialogStep("Yes."); + talkToSquire.addTeleport(faladorTeleports.quantity(1)); + talkToReldo = new NpcStep(this, NpcID.RELDO_NORMAL, new WorldPoint(3211, 3494, 0), "Talk to Reldo in Varrock Castle's library."); talkToReldo.addDialogStep("What do you know about the Imcando dwarves?"); + talkToReldo.addTeleport(varrockTeleport.quantity(1)); + talkToThurgo = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Talk to Thurgo south of Port Sarim and give him a redberry pie.", redberryPie); talkToThurgo.addDialogStep("Would you like a redberry pie?"); + talkToThurgo.addTeleport(homeTele.quantity(1)); + talkToThurgoAgain = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Talk to Thurgo again."); talkToThurgoAgain.addDialogStep("Can you make a special sword for me?"); + talkToSquire2 = new NpcStep(this, NpcID.SQUIRE, new WorldPoint(2978, 3341, 0), "Talk to the Squire in Falador Castle's courtyard."); + talkToSquire2.addTeleport(faladorTeleports.quantity(1)); + goUpCastle1 = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_LADDER_UP, new WorldPoint(2994, 3341, 0), "Climb up the east ladder in Falador Castle."); + goUpCastle2 = new ObjectStep(this, ObjectID.FAI_FALADOR_CASTLE_STAIRS, new WorldPoint(2985, 3338, 1), "Go up the staircase west of the ladder on the 1st floor."); - searchCupboard = new ObjectStep(this, ObjectID.VYVINCUPBOARDOPEN, new WorldPoint(2985, 3336, 2), "Search the cupboard in the room south of the staircase. You'll need Sir Vyvin to be in the other room.", searchCupboardReq); - ((ObjectStep)searchCupboard).addAlternateObjects(ObjectID.VYVINCUPBOARDSHUT); // 2271 is the closed cupboard - givePortraitToThurgo = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Bring Thurgo the portrait.", ironBars, portrait); + + searchCupboard = new ObjectStep(this, ObjectID.VYVINCUPBOARDOPEN, new WorldPoint(2985, 3336, 2), "Search the cupboard in the room south of the staircase. You'll need Sir Vyvin to be in the other room.", sirVyvinNotInRoom); + searchCupboard.addAlternateObjects(ObjectID.VYVINCUPBOARDSHUT); + + givePortraitToThurgo = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Bring Thurgo the portrait.", pickaxe, ironBars, portrait); givePortraitToThurgo.addDialogStep("About that sword..."); + givePortraitToThurgo.addTeleport(homeTele.quantity(1)); + enterDungeon = new ObjectStep(this, ObjectID.FAI_TRAPDOOR, new WorldPoint(3008, 3150, 0), "Go down the ladder south of Port Sarim. Be prepared for ice giants and ice warriors to attack you.", pickaxe, ironBars); + mineBlurite = new ObjectStep(this, ObjectID.BLURITE_ROCK_1, new WorldPoint(3049, 9566, 0), "Mine a blurite ore in the eastern cavern.", pickaxe); + bringThurgoOre = new NpcStep(this, NpcID.THURGO, new WorldPoint(3000, 3145, 0), "Return to Thurgo with a blurite ore and two iron bars.", bluriteOre, ironBars); bringThurgoOre.addDialogStep("Can you make that replacement sword now?"); + finishQuest = new NpcStep(this, NpcID.SQUIRE, new WorldPoint(2978, 3341, 0), "Return to the Squire with the sword to finish the quest.", bluriteSword); + finishQuest.addTeleport(faladorTeleports.quantity(1)); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToSquire); + steps.put(1, talkToReldo); + steps.put(2, talkToThurgo); + steps.put(3, talkToThurgoAgain); + steps.put(4, talkToSquire2); + + var getPortrait = new ConditionalStep(this, goUpCastle1); + getPortrait.addStep(portrait.alsoCheckBank(), givePortraitToThurgo); + getPortrait.addStep(inFaladorCastle2, searchCupboard); + getPortrait.addStep(inFaladorCastle1, goUpCastle2); + + steps.put(5, getPortrait); + + var returnSwordToSquire = new ConditionalStep(this, enterDungeon); + returnSwordToSquire.addStep(bluriteSword.alsoCheckBank(), finishQuest); + returnSwordToSquire.addStep(bluriteOre.alsoCheckBank(), bringThurgoOre); + returnSwordToSquire.addStep(inDungeon, mineBlurite); + + steps.put(6, returnSwordToSquire); + + return steps; + } + + @Override + public List getGeneralRequirements() + { + return List.of( + new SkillRequirement(Skill.MINING, 10, true) + ); } @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(redberryPie); - reqs.add(ironBars); - reqs.add(pickaxe); - return reqs; + return List.of( + redberryPie, + ironBars, + pickaxe + ); } @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - reqs.add(varrockTeleport); - reqs.add(faladorTeleports); - reqs.add(homeTele); - return reqs; + return List.of( + varrockTeleport, + faladorTeleports, + homeTele + ); } @Override public List getCombatRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Able to survive attacks from Ice Warriors (level 57) and Ice Giants (level 53)"); - return reqs; + return List.of( + "Able to survive attacks from Ice Warriors (level 57) and Ice Giants (level 53)" + ); } @Override - public List getGeneralRequirements() + public List getNotes() { - return Collections.singletonList(new SkillRequirement(Skill.MINING, 10, true)); + return List.of( + "You can make progress towards the Falador Easy Diary task by mining an additional Blurite ore and smelting another Blurite bar, it will be required for smithing Blurite limbs." + ); } @Override @@ -207,33 +264,57 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.SMITHING, 12725)); + return List.of( + new ExperienceReward(Skill.SMITHING, 12725) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("The ability to smelt Blurite ore."), - new UnlockReward("The ability to smith Blurite bars.")); + return List.of( + new UnlockReward("The ability to smelt Blurite ore."), + new UnlockReward("The ability to smith Blurite bars.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - - allSteps.add(new PanelDetails("Starting off", Arrays.asList(talkToSquire, talkToReldo))); - allSteps.add(new PanelDetails("Finding an Imcando", Arrays.asList(talkToThurgo, talkToThurgoAgain), redberryPie)); - allSteps.add(new PanelDetails("Find the portrait", Arrays.asList(talkToSquire2, goUpCastle1, goUpCastle2, searchCupboard, givePortraitToThurgo))); - allSteps.add(new PanelDetails("Making the sword", Arrays.asList(enterDungeon, mineBlurite, bringThurgoOre), pickaxe, ironBars)); - allSteps.add(new PanelDetails("Return the sword", Collections.singletonList(finishQuest))); - return allSteps; - } + var sections = new ArrayList(); - @Override - public List getNotes() - { - return Collections.singletonList("You can make progress towards the Falador Easy Diary task by mining an additional Blurite ore and smelting another Blurite bar, it will be required for smithing Blurite limbs."); + sections.add(new PanelDetails("Starting off", List.of( + talkToSquire, + talkToReldo + ))); + + sections.add(new PanelDetails("Finding an Imcando", List.of( + talkToThurgo, + talkToThurgoAgain + ), List.of( + redberryPie + ))); + + sections.add(new PanelDetails("Find the portrait", List.of( + talkToSquire2, + goUpCastle1, + goUpCastle2, + searchCupboard, + givePortraitToThurgo + ))); + + sections.add(new PanelDetails("Making the sword", List.of(enterDungeon, + mineBlurite, + bringThurgoOre + ), List.of( + pickaxe, + ironBars + ))); + + sections.add(new PanelDetails("Return the sword", List.of( + finishQuest + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java index 2ea3c3713e..fe6427589f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thelosttribe/TheLostTribe.java @@ -40,82 +40,131 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcEmoteStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.client.plugins.microbot.questhelper.steps.emote.QuestEmote; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - public class TheLostTribe extends BasicQuestHelper { - //Items Required - ItemRequirement pickaxe, lightSource, brooch, book, key, silverware, treaty; - - //Items Recommended - ItemRequirement varrockTeleport, faladorTeleport, lumbridgeTeleports; - - Requirement inBasement, inLumbridgeF0, inLumbridgeF1, inLumbridgeF2, inTunnels, inMines, - foundRobes, inHamBase, foundSilverwareOrToldOnSigmund, bobKnows, hansKnows; - - DetailedQuestStep goDownFromF2, talkToSigmund, talkToDuke, goDownFromF1, talkToHans, goUpToF1, - goDownIntoBasement, usePickaxeOnRubble, climbThroughHole, grabBrooch, climbOutThroughHole, goUpFromBasement, - showBroochToDuke, searchBookcase, readBook, talkToGenerals, walkToMistag, emoteAtMistag, pickpocketSigmund, - unlockChest, enterHamLair, searchHamCrates, talkToKazgar, talkToMistagForEnd, talkToBob, talkToAllAboutCellar; - - ConditionalStep goToF1Steps, goDownToBasement, goTalkToSigmundToStart, findGoblinWitnessSteps, goTalkToDukeAfterHans, - goMineRubble, enterTunnels, goShowBroochToDuke, goTalkToDukeAfterEmote, goTravelToMistag, goGetKey, goOpenRobeChest, - goIntoHamLair, goToDukeWithSilverware, travelToMakePeace; - - //Zones - Zone basement, lumbridgeF0, lumbridgeF1, lumbridgeF2, tunnels, mines, hamBase; + // Required items + ItemRequirement pickaxe; + ItemRequirement lightSource; + + // Recommended item + ItemRequirement varrockTeleport; + ItemRequirement faladorTeleport; + ItemRequirement lumbridgeTeleports; + + // Mid-quest item requirements + ItemRequirement brooch; + ItemRequirement book; + ItemRequirement key; + ItemRequirement silverware; + ItemRequirement treaty; + + // Zones + Zone basement; + Zone lumbridgeF0; + Zone lumbridgeF1; + Zone lumbridgeF2; + Zone tunnels; + Zone mines; + Zone hamBase; + + // Miscellaneous requirements + ZoneRequirement inBasement; + ZoneRequirement inLumbridgeF0; + ZoneRequirement inLumbridgeF1; + ZoneRequirement inLumbridgeF2; + ZoneRequirement inTunnels; + ZoneRequirement inMines; + VarbitRequirement foundRobes; + ZoneRequirement inHamBase; + VarbitRequirement foundSilverwareOrToldOnSigmund; + VarbitRequirement bobKnows; + VarbitRequirement hansKnows; + + // Steps + ObjectStep goDownIntoBasement; + ObjectStep goDownFromF1; + ObjectStep goUpToF1; + ObjectStep goUpFromBasement; + ObjectStep goDownFromF2; + ObjectStep climbOutThroughHole; + ConditionalStep goToF1Steps; + + NpcStep talkToSigmund; + ConditionalStep goTalkToSigmundToStart; + + NpcStep talkToHans; + NpcStep talkToBob; + NpcStep talkToAllAboutCellar; + ConditionalStep findGoblinWitnessSteps; + + NpcStep talkToDuke; + ConditionalStep goTalkToDukeAfterHans; + + ConditionalStep goDownToBasement; + ObjectStep usePickaxeOnRubble; + ConditionalStep goMineRubble; + + ObjectStep climbThroughHole; + ConditionalStep enterTunnels; + DetailedQuestStep grabBrooch; + NpcStep showBroochToDuke; + ConditionalStep goShowBroochToDuke; + + ObjectStep searchBookcase; + DetailedQuestStep readBook; + + NpcStep talkToGenerals; + + NpcEmoteStep walkToMistag; + NpcEmoteStep emoteAtMistag; + ConditionalStep goTravelToMistag; + + ConditionalStep goTalkToDukeAfterEmote; + + NpcStep pickpocketSigmund; + ConditionalStep goGetKey; + ObjectStep unlockChest; + ConditionalStep goOpenRobeChest; + ObjectStep enterHamLair; + ObjectStep searchHamCrates; + ConditionalStep goIntoHamLair; + ConditionalStep goToDukeWithSilverware; + + NpcStep talkToKazgar; + NpcStep talkToMistagForEnd; + ConditionalStep travelToMakePeace; @Override - public Map loadSteps() + protected void setupZones() { - initializeRequirements(); - setupConditions(); - setupSteps(); - setupConditionalSteps(); - Map steps = new HashMap<>(); - - steps.put(0, goTalkToSigmundToStart); - steps.put(1, findGoblinWitnessSteps); - steps.put(2, goTalkToDukeAfterHans); - steps.put(3, goMineRubble); - - ConditionalStep goGrabBrooch = new ConditionalStep(this, enterTunnels); - goGrabBrooch.addStep(brooch, goShowBroochToDuke); - goGrabBrooch.addStep(inTunnels, grabBrooch); - steps.put(4, goGrabBrooch); - - ConditionalStep getBook = new ConditionalStep(this, searchBookcase); - getBook.addStep(book, readBook); - steps.put(5, getBook); - - steps.put(6, talkToGenerals); - - ConditionalStep makeContactSteps = new ConditionalStep(this, goTravelToMistag); - makeContactSteps.addStep(inMines, emoteAtMistag); - makeContactSteps.addStep(inTunnels, walkToMistag); - - steps.put(7, makeContactSteps); - steps.put(8, goTalkToDukeAfterEmote); - - ConditionalStep revealSigmund = new ConditionalStep(this, goGetKey); - revealSigmund.addStep(silverware.alsoCheckBank(), goToDukeWithSilverware); - revealSigmund.addStep(foundRobes, goIntoHamLair); - revealSigmund.addStep(key, goOpenRobeChest); - steps.put(9, revealSigmund); - - steps.put(10, travelToMakePeace); - - return steps; + basement = new Zone(new WorldPoint(3208, 9614, 0), new WorldPoint(3219, 9625, 0)); + lumbridgeF0 = new Zone(new WorldPoint(3136, 3136, 0), new WorldPoint(3328, 3328, 0)); + lumbridgeF1 = new Zone(new WorldPoint(3203, 3206, 1), new WorldPoint(3217, 3231, 1)); + lumbridgeF2 = new Zone(new WorldPoint(3203, 3206, 2), new WorldPoint(3217, 3231, 2)); + tunnels = new Zone(new WorldPoint(3221, 9602, 0), new WorldPoint(3308, 9661, 0)); + mines = new Zone(new WorldPoint(3309, 9600, 0), new WorldPoint(3327, 9655, 0)); + hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); } @Override @@ -136,22 +185,7 @@ protected void setupRequirements() varrockTeleport = new ItemRequirement("Varrock teleport", ItemID.POH_TABLET_VARROCKTELEPORT); lumbridgeTeleports = new ItemRequirement("Lumbridge teleports", ItemID.POH_TABLET_LUMBRIDGETELEPORT, 3); faladorTeleport = new ItemRequirement("Falador teleport", ItemID.POH_TABLET_FALADORTELEPORT); - } - @Override - protected void setupZones() - { - basement = new Zone(new WorldPoint(3208, 9614, 0), new WorldPoint(3219, 9625, 0)); - lumbridgeF0 = new Zone(new WorldPoint(3136, 3136, 0), new WorldPoint(3328, 3328, 0)); - lumbridgeF1 = new Zone(new WorldPoint(3203, 3206, 1), new WorldPoint(3217, 3231, 1)); - lumbridgeF2 = new Zone(new WorldPoint(3203, 3206, 2), new WorldPoint(3217, 3231, 2)); - tunnels = new Zone(new WorldPoint(3221, 9602, 0), new WorldPoint(3308, 9661, 0)); - mines = new Zone(new WorldPoint(3309, 9600, 0), new WorldPoint(3327, 9655, 0)); - hamBase = new Zone(new WorldPoint(3140, 9600, 0), new WorldPoint(3190, 9655, 0)); - } - - public void setupConditions() - { inBasement = new ZoneRequirement(basement); inLumbridgeF0 = new ZoneRequirement(lumbridgeF0); inLumbridgeF1 = new ZoneRequirement(lumbridgeF1); @@ -176,46 +210,82 @@ public void setupSteps() goDownFromF1 = new ObjectStep(this, ObjectID.SPIRALSTAIRSMIDDLE, new WorldPoint(3205, 3208, 1), "Go down the staircase."); goDownFromF1.addDialogStep("Climb down the stairs."); goUpToF1 = new ObjectStep(this, ObjectID.SPIRALSTAIRSBOTTOM_3, new WorldPoint(3205, 3208, 0), "Go up to the first floor of Lumbridge Castle."); + goUpToF1.addDialogStep("Can you show me the way out of the mines?"); goUpFromBasement = new ObjectStep(this, ObjectID.LADDER_FROM_CELLAR, new WorldPoint(3209, 9616, 0), "Go up to the surface."); goDownFromF2 = new ObjectStep(this, ObjectID.SPIRALSTAIRSTOP_3, new WorldPoint(3205, 3208, 2), "Go downstairs."); + climbOutThroughHole = new ObjectStep(this, ObjectID.LOST_TRIBE_CAVEWALL_HOLE_WALLDECOR, new WorldPoint(3221, 9618, 0), ""); + climbOutThroughHole.setForceClickboxHighlight(true); + + goToF1Steps = new ConditionalStep(this, goUpToF1); + goToF1Steps.addStep(inLumbridgeF2, goDownFromF2); + goToF1Steps.addStep(inBasement, goUpFromBasement); + goToF1Steps.addStep(inTunnels, climbOutThroughHole); + talkToSigmund = new NpcStep(this, NpcID.LOST_TRIBE_SIGMUND_THERE, new WorldPoint(3210, 3222, 1), ""); talkToSigmund.addDialogSteps("Do you have any quests for me?", "Yes."); + goTalkToSigmundToStart = new ConditionalStep(this, goToF1Steps, "Talk to Sigmund in Lumbridge Castle."); + goTalkToSigmundToStart.addStep(inLumbridgeF1, talkToSigmund); + // This isn't just talk to Hans, it's a random one of the NPCs to chat to talkToHans = new NpcStep(this, NpcID.HANS, new WorldPoint(3222, 3218, 0), "Talk to Hans who is roaming around the castle."); talkToHans.addDialogStep("Do you know what happened in the cellar?"); - talkToBob = new NpcStep(this, NpcID.TWOCATS_BOB_CUTSCENE, new WorldPoint(3231, 3203, 0), "Talk to Bob in the south of Lumbridge."); + talkToBob = new NpcStep(this, NpcID.BOB, new WorldPoint(3231, 3203, 0), "Talk to Bob in the south of Lumbridge."); talkToBob.addDialogStep("Do you know what happened in the castle cellar?"); - talkToAllAboutCellar = new NpcStep(this, NpcID.COOK, "Talk to the Cook, Hans, Father Aereck, and Bob in Lumbridge until one tells you about seeing a goblin."); - ((NpcStep)(talkToAllAboutCellar)).addAlternateNpcs(NpcID.FATHER_AERECK); + talkToAllAboutCellar = new NpcStep(this, NpcID.COOK, ""); + talkToAllAboutCellar.addAlternateNpcs(NpcID.FATHER_AERECK); talkToAllAboutCellar.addDialogSteps("Do you know what happened in the castle cellar?"); talkToAllAboutCellar.addSubSteps(talkToHans, talkToBob); + findGoblinWitnessSteps = new ConditionalStep(this, talkToAllAboutCellar, "Talk to the Cook, Hans, Father Aereck, and Bob in Lumbridge until one tells you about seeing a goblin."); + findGoblinWitnessSteps.addStep(inLumbridgeF2, goDownFromF2); + findGoblinWitnessSteps.addStep(inLumbridgeF1, goDownFromF1); + findGoblinWitnessSteps.addStep(inBasement, goUpFromBasement); + findGoblinWitnessSteps.addStep(hansKnows, talkToHans); + findGoblinWitnessSteps.addStep(bobKnows, talkToBob); + talkToDuke = new NpcStep(this, NpcID.DUKE_OF_LUMBRIDGE, new WorldPoint(3210, 3222, 1), ""); + + goTalkToDukeAfterHans = new ConditionalStep(this, goToF1Steps, "Talk to Duke Horacio in Lumbridge Castle."); + goTalkToDukeAfterHans.addDialogSteps("Hans says he saw something in the cellar", "Bob says he saw something in the cellar", "Father Aereck says he saw something in the cellar", "The cook says he saw something in the cellar"); + goTalkToDukeAfterHans.addStep(inLumbridgeF1, talkToDuke); + + goDownToBasement = new ConditionalStep(this, goDownIntoBasement); + goDownToBasement.addStep(inLumbridgeF2, goDownFromF2); + goDownToBasement.addStep(inLumbridgeF1, goDownFromF1); + // Name of person who said they saw something changes usePickaxeOnRubble = new ObjectStep(this, ObjectID.LOST_TRIBE_CELLAR_WALL, new WorldPoint(3219, 9618, 0), ""); usePickaxeOnRubble.addIcon(ItemID.BRONZE_PICKAXE); + goMineRubble = new ConditionalStep(this, goDownToBasement, "Use a pickaxe on the rubble in the Lumbridge Castle basement.", pickaxe.highlighted(), lightSource); + goMineRubble.addStep(inBasement, usePickaxeOnRubble); + climbThroughHole = new ObjectStep(this, ObjectID.LOST_TRIBE_CELLAR_WALL, new WorldPoint(3219, 9618, 0), ""); + climbThroughHole.setForceClickboxHighlight(true); - grabBrooch = new DetailedQuestStep(this, new WorldPoint(3230, 9610, 0), "Pick up the brooch on the floor.", brooch); + enterTunnels = new ConditionalStep(this, goDownToBasement, "Enter the hole in Lumbridge Castle's basement.", lightSource); + enterTunnels.addStep(inBasement, climbThroughHole); - climbOutThroughHole = new ObjectStep(this, ObjectID.LOST_TRIBE_CAVEWALL_HOLE_WALLDECOR, new WorldPoint(3221, 9618, 0), ""); + grabBrooch = new DetailedQuestStep(this, new WorldPoint(3230, 9610, 0), "Pick up the brooch on the floor.", brooch); showBroochToDuke = new NpcStep(this, NpcID.DUKE_OF_LUMBRIDGE, new WorldPoint(3210, 3222, 1), ""); showBroochToDuke.addDialogStep("I dug through the rubble..."); + goShowBroochToDuke = new ConditionalStep(this, goToF1Steps, "Show the brooch to Duke Horacio in Lumbridge Castle.", brooch); + goShowBroochToDuke.addStep(inLumbridgeF1, showBroochToDuke); + searchBookcase = new ObjectStep(this, ObjectID.LOST_TRIBE_BOOKCASE, new WorldPoint(3207, 3496, 0), "Search the north west bookcase in the Varrock Castle Library."); searchBookcase.addTeleport(varrockTeleport); + readBook = new DetailedQuestStep(this, "Read the entire goblin symbol book.", book); - readBook.addWidgetHighlight(183, 16); + readBook.addWidgetHighlight(InterfaceID.LostTribeSymbolBook.LOST_TRIBE_RIGHT_ARROW); talkToGenerals = new NpcStep(this, NpcID.GENERAL_WARTFACE_GREEN, new WorldPoint(2957, 3512, 0), "Talk to the Goblin Generals in the Goblin Village."); talkToGenerals.addTeleport(faladorTeleport); - talkToGenerals.addDialogSteps("Have you ever heard of the Dorgeshuun?", "It doesn't really matter", - "Well either way they refused to fight", "Well I found a brooch underground...", "Well why not show me both greetings?"); + talkToGenerals.addDialogSteps("Have you ever heard of the Dorgeshuun?", "It doesn't really matter", "Well either way they refused to fight", "Well I found a brooch underground...", "Well why not show me both greetings?"); List travelLine = Arrays.asList( new WorldPoint(3222, 9618, 0), @@ -261,52 +331,6 @@ public void setupSteps() emoteAtMistag = new NpcEmoteStep(this, NpcID.LOST_TRIBE_MISTAG_1OP, QuestEmote.GOBLIN_BOW, new WorldPoint(3319, 9615, 0), "Perform the Goblin Bow emote next to Mistag and talk to him.", lightSource); - pickpocketSigmund = new NpcStep(this, NpcID.LOST_TRIBE_SIGMUND_THERE, new WorldPoint(3210, 3222, 1), ""); - unlockChest = new ObjectStep(this, ObjectID.LOST_TRIBE_CHEST, new WorldPoint(3209, 3217, 1), ""); - - enterHamLair = new ObjectStep(this, ObjectID.HAM_MULTI_TRAPDOOR, new WorldPoint(3166, 3252, 0), ""); - - searchHamCrates = new ObjectStep(this, ObjectID.LOST_TRIBE_CRATE, new WorldPoint(3152, 9645, 0), ""); - - talkToKazgar = new NpcStep(this, NpcID.LOST_TRIBE_GUIDE_2OPS, new WorldPoint(3230, 9610, 0), "Travel with Kazgar to shortcut to Mistag."); - talkToMistagForEnd = new NpcStep(this, NpcID.LOST_TRIBE_MISTAG_2OPS, new WorldPoint(3319, 9615, 0), ""); - } - - private void setupConditionalSteps() - { - goToF1Steps = new ConditionalStep(this, goUpToF1); - goToF1Steps.addStep(inLumbridgeF2, goDownFromF2); - goToF1Steps.addStep(inBasement, goUpFromBasement); - goToF1Steps.addStep(inTunnels, climbOutThroughHole); - - goDownToBasement = new ConditionalStep(this, goDownIntoBasement); - goDownToBasement.addStep(inLumbridgeF2, goDownFromF2); - goDownToBasement.addStep(inLumbridgeF1, goDownFromF1); - - goTalkToSigmundToStart = new ConditionalStep(this, goToF1Steps, "Talk to Sigmund in Lumbridge Castle."); - goTalkToSigmundToStart.addStep(inLumbridgeF1, talkToSigmund); - - findGoblinWitnessSteps = new ConditionalStep(this, talkToAllAboutCellar); - findGoblinWitnessSteps.addStep(inLumbridgeF2, goDownFromF2); - findGoblinWitnessSteps.addStep(inLumbridgeF1, goDownFromF1); - findGoblinWitnessSteps.addStep(inBasement, goUpFromBasement); - findGoblinWitnessSteps.addStep(hansKnows, talkToHans); - findGoblinWitnessSteps.addStep(bobKnows, talkToBob); - - goTalkToDukeAfterHans = new ConditionalStep(this, goToF1Steps, "Talk to Duke Horacio in Lumbridge Castle."); - goTalkToDukeAfterHans.addDialogSteps("Hans says he saw something in the cellar", "Bob says he saw something in the cellar", - "Father Aereck says he saw something in the cellar", "The cook says he saw something in the cellar"); - goTalkToDukeAfterHans.addStep(inLumbridgeF1, talkToDuke); - - goMineRubble = new ConditionalStep(this, goDownToBasement, "Go use a pickaxe on the rubble in the Lumbridge Castle basement.", pickaxe.highlighted(), lightSource); - goMineRubble.addStep(inBasement, usePickaxeOnRubble); - - enterTunnels = new ConditionalStep(this, goDownToBasement, "Enter the hole in Lumbridge Castle's basement.", lightSource); - enterTunnels.addStep(inBasement, climbThroughHole); - - goShowBroochToDuke = new ConditionalStep(this, goToF1Steps, "Show the brooch to Duke Horacio in Lumbridge Castle.", brooch); - goShowBroochToDuke.addStep(inLumbridgeF1, showBroochToDuke); - goTravelToMistag = new ConditionalStep(this, goDownToBasement, "Travel through the tunnels under Lumbridge until you reach Mistag.", lightSource); goTravelToMistag.addStep(inBasement, climbThroughHole); goTravelToMistag.addSubSteps(walkToMistag); @@ -315,12 +339,20 @@ private void setupConditionalSteps() goTalkToDukeAfterEmote.addDialogSteps("I've made contact with the cave goblins..."); goTalkToDukeAfterEmote.addStep(inLumbridgeF1, talkToDuke); + pickpocketSigmund = new NpcStep(this, NpcID.LOST_TRIBE_SIGMUND_THERE, new WorldPoint(3210, 3222, 1), ""); + goGetKey = new ConditionalStep(this, goToF1Steps, "Pickpocket Sigmund for a key."); goGetKey.addStep(inLumbridgeF1, pickpocketSigmund); + unlockChest = new ObjectStep(this, ObjectID.LOST_TRIBE_CHEST, new WorldPoint(3209, 3217, 1), ""); + goOpenRobeChest = new ConditionalStep(this, goToF1Steps, "Open the chest in the room next to the Duke's room.", key); goOpenRobeChest.addStep(inLumbridgeF1, unlockChest); + enterHamLair = new ObjectStep(this, ObjectID.HAM_MULTI_TRAPDOOR, new WorldPoint(3166, 3252, 0), ""); + + searchHamCrates = new ObjectStep(this, ObjectID.LOST_TRIBE_CRATE, new WorldPoint(3152, 9645, 0), ""); + goIntoHamLair = new ConditionalStep(this, enterHamLair, "Enter the H.A.M lair west of Lumbridge and search a crate in its entrance for the silverware."); goIntoHamLair.addStep(inHamBase, searchHamCrates); goIntoHamLair.addStep(inLumbridgeF2, goDownFromF2); @@ -331,34 +363,91 @@ private void setupConditionalSteps() goToDukeWithSilverware.addDialogStep("I found the missing silverware in the HAM cave!"); goToDukeWithSilverware.addStep(inLumbridgeF1, talkToDuke); + talkToKazgar = new NpcStep(this, NpcID.LOST_TRIBE_GUIDE_2OPS, new WorldPoint(3230, 9610, 0), "Travel with Kazgar to shortcut to Mistag."); + talkToKazgar.addDialogStep("Can you show me the way to the mines?"); + talkToMistagForEnd = new NpcStep(this, NpcID.LOST_TRIBE_MISTAG_2OPS, new WorldPoint(3319, 9615, 0), ""); + travelToMakePeace = new ConditionalStep(this, goDownToBasement, "Travel through the tunnels until you reach Mistag, and give him the treaty.", lightSource, treaty); + travelToMakePeace.addDialogStep("What was I doing again?"); travelToMakePeace.addStep(inMines, talkToMistagForEnd); travelToMakePeace.addStep(inTunnels, talkToKazgar); travelToMakePeace.addStep(inBasement, climbThroughHole); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, goTalkToSigmundToStart); + + steps.put(1, findGoblinWitnessSteps); + + steps.put(2, goTalkToDukeAfterHans); + + steps.put(3, goMineRubble); + + var goGrabBrooch = new ConditionalStep(this, enterTunnels); + goGrabBrooch.addStep(brooch, goShowBroochToDuke); + goGrabBrooch.addStep(inTunnels, grabBrooch); + steps.put(4, goGrabBrooch); + + var getBook = new ConditionalStep(this, searchBookcase); + getBook.addStep(book, readBook); + steps.put(5, getBook); + + steps.put(6, talkToGenerals); + + var makeContactSteps = new ConditionalStep(this, goTravelToMistag); + makeContactSteps.addStep(inMines, emoteAtMistag); + makeContactSteps.addStep(inTunnels, walkToMistag); + steps.put(7, makeContactSteps); + + steps.put(8, goTalkToDukeAfterEmote); + + var revealSigmund = new ConditionalStep(this, goGetKey); + revealSigmund.addStep(silverware.alsoCheckBank(), goToDukeWithSilverware); + revealSigmund.addStep(foundRobes, goIntoHamLair); + revealSigmund.addStep(key, goOpenRobeChest); + steps.put(9, revealSigmund); + + steps.put(10, travelToMakePeace); + + return steps; + } + @Override public List getItemRequirements() { - return Arrays.asList(pickaxe, lightSource); + return List.of( + pickaxe, + lightSource + ); } @Override public List getItemRecommended() { - return Arrays.asList(lumbridgeTeleports, varrockTeleport, faladorTeleport); + return List.of( + lumbridgeTeleports, + varrockTeleport, + faladorTeleport + ); } @Override public List getGeneralRequirements() { - ArrayList req = new ArrayList<>(); - req.add(new QuestRequirement(QuestHelperQuest.GOBLIN_DIPLOMACY, QuestState.FINISHED)); - req.add(new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED)); - req.add(new SkillRequirement(Skill.AGILITY, 13, true)); - req.add(new SkillRequirement(Skill.THIEVING, 13, true)); - req.add(new SkillRequirement(Skill.MINING, 17, true)); - return req; + return List.of( + new QuestRequirement(QuestHelperQuest.GOBLIN_DIPLOMACY, QuestState.FINISHED), + new QuestRequirement(QuestHelperQuest.RUNE_MYSTERIES, QuestState.FINISHED), + new SkillRequirement(Skill.AGILITY, 13, true), + new SkillRequirement(Skill.THIEVING, 13, true), + new SkillRequirement(Skill.MINING, 17, true) + ); } @Override @@ -370,34 +459,74 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.MINING, 3000)); + return List.of( + new ExperienceReward(Skill.MINING, 3000) + ); } @Override public List getItemRewards() { - return Collections.singletonList(new ItemReward("Ring of Life", ItemID.RING_OF_LIFE, 1)); + return List.of( + new ItemReward("Ring of Life", ItemID.RING_OF_LIFE, 1) + ); } @Override public List getUnlockRewards() { - return Arrays.asList( - new UnlockReward("Access to the Dorgesh-Kann mine."), - new UnlockReward("Access to Nardok's Bone Weapon Store"), - new UnlockReward("2 new goblin emotes.")); + return List.of( + new UnlockReward("Access to the Dorgesh-Kaan mine."), + new UnlockReward("Access to Nardok's Bone Weapon Store"), + new UnlockReward("2 new goblin emotes.") + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(goTalkToSigmundToStart, talkToAllAboutCellar, goTalkToDukeAfterHans))); - allSteps.add(new PanelDetails("Investigating", Arrays.asList(goMineRubble, enterTunnels, grabBrooch, goShowBroochToDuke), pickaxe, lightSource)); - allSteps.add(new PanelDetails("Learning about goblins", Arrays.asList(searchBookcase, readBook, talkToGenerals))); - allSteps.add(new PanelDetails("Making contact", Arrays.asList(goTravelToMistag, emoteAtMistag, goTalkToDukeAfterEmote), lightSource)); - allSteps.add(new PanelDetails("Resolving tensions", Arrays.asList(goGetKey, goOpenRobeChest, goIntoHamLair, goToDukeWithSilverware, travelToMakePeace), lightSource)); - - return allSteps; + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + goTalkToSigmundToStart, + findGoblinWitnessSteps, + goTalkToDukeAfterHans + ))); + + sections.add(new PanelDetails("Investigating", List.of( + goMineRubble, + enterTunnels, + grabBrooch, + goShowBroochToDuke + ), List.of( + pickaxe, + lightSource + ))); + + sections.add(new PanelDetails("Learning about goblins", List.of( + searchBookcase, + readBook, + talkToGenerals + ))); + + sections.add(new PanelDetails("Making contact", List.of( + goTravelToMistag, + emoteAtMistag, + goTalkToDukeAfterEmote + ), List.of( + lightSource + ))); + + sections.add(new PanelDetails("Resolving tensions", List.of( + goGetKey, + goOpenRobeChest, + goIntoHamLair, + goToDukeWithSilverware, + travelToMakePeace + ), List.of( + lightSource + ))); + + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java index 5ba87899d0..f277847582 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/ThePathOfGlouphrie.java @@ -53,6 +53,7 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; @@ -232,7 +233,6 @@ private void setupConditions() learnedAboutChapter1 = new VarbitRequirement(VarbitID.POG_BOLRIE_DIARY_1, 1); learnedAboutChapter2 = new VarbitRequirement(VarbitID.POG_BOLRIE_DIARY_2, 1); - // learnedAboutChapter3 = new VarbitRequirement(VarbitID.POG_BOLRIE_DIARY_3, 1); inSewer1 = new ZoneRequirement(sewer1); inSewer2 = new ZoneRequirement(sewer2); @@ -242,7 +242,7 @@ private void setupConditions() inSewer6 = new Conditions(LogicType.OR, new ZoneRequirement(sewer6Section1), new ZoneRequirement(sewer6Section2)); inBossRoom = new ZoneRequirement(bossRoom); - lecternWidgetActive = new WidgetTextRequirement(854, 5, "Chapter 1. Bad advice"); + lecternWidgetActive = new WidgetTextRequirement(InterfaceID.PogBolriesDiary.CHAPTER1, "Chapter 1. Bad advice"); protectMissiles = new PrayerRequirement("Protect from Missiles to reduce damage taken by the Terrorbirds", Prayer.PROTECT_FROM_MISSILES); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java index 3d2db996f8..8094f802a2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/YewnocksPuzzle.java @@ -35,6 +35,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.InventoryID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.ObjectID; @@ -374,11 +375,11 @@ protected void setupSteps() getMoreDiscs = new ObjectStep(getQuestHelper(), ObjectID.POG_CHEST_CLOSED, regionPoint(34, 31), "Get more discs from the chests outside. You can drop discs before you get more. You can also use the exchanger next to Yewnock's machine.", true); useExchanger = new ObjectStep(getQuestHelper(), ObjectID.POG_GNOME_MACHINE_03, regionPoint(22, 33), "A solution has been calculated, exit the machine interface & click Yewnock's exchanger."); - useExchanger.addWidgetHighlight(848, 27); // TODO: Verify that this is the "exit" button in the Machine widget + useExchanger.addWidgetHighlight(InterfaceID.PogCoinMachine.CLOSE); clickMachine = new ObjectStep(getQuestHelper(), ObjectID.POG_GNOME_MACHINE_02, regionPoint(22, 32), "A solution has been found, click Yewnock's machine and insert the discs as prompted."); - clickMachine.addWidgetHighlight(849, 41); + clickMachine.addWidgetHighlight(InterfaceID.PogCoinExchanger.CLOSE); clickMachineOnce = new ObjectStep(getQuestHelper(), ObjectID.POG_GNOME_MACHINE_02, regionPoint(22, 32), "Operate Yewnock's machine to calculate a solution."); @@ -391,14 +392,14 @@ protected void setupSteps() 848, 26); exchangerInsertDisc = new DiscInsertionStep(getQuestHelper(), "Insert the highlighted disc into the highlighted slot."); - exchangerExchange = new WidgetStep(getQuestHelper(), "", 849, 40); + exchangerExchange = new WidgetStep(getQuestHelper(), "", InterfaceID.PogCoinExchanger.EXCHANGE); exchangerConfirm = new DetailedQuestStep(getQuestHelper(), "Click the confirm button."); - exchangerConfirm.addWidgetHighlight(849, 36); + exchangerConfirm.addWidgetHighlight(InterfaceID.PogCoinExchanger.SUBMIT); exchangerReset = new WidgetStep(getQuestHelper(), "Found unexpected disc(s) in the exchange input, reset & follow the instructions."); - exchangerReset.addWidgetHighlight(849, 34); + exchangerReset.addWidgetHighlight(InterfaceID.PogCoinExchanger.RESET); - machineOpen = new WidgetPresenceRequirement(848, 0); - exchangerOpen = new WidgetPresenceRequirement(849, 0); + machineOpen = new WidgetPresenceRequirement(InterfaceID.PogCoinMachine.UNIVERSE); + exchangerOpen = new WidgetPresenceRequirement(InterfaceID.PogCoinExchanger.UNIVERSE); } @Override @@ -453,9 +454,9 @@ public void shutDown() solution.reset(); } - private int getWidgetItemId(int groupId, int childId) + private int getWidgetItemId(int widgetId) { - var widget = client.getWidget(groupId, childId); + var widget = client.getWidget(widgetId); if (widget == null) { return -1; @@ -467,32 +468,32 @@ private int getWidgetItemId(int groupId, int childId) /** * This function will add a widget highlight to the slot where it finds a good exchange, if any * - * @return a pair of widget group + child IDs if there is an exchange we're looking for in one of the slots + * @return a widget ID if there is an exchange we're looking for in one of the slots */ - private Optional> findGoodExchange() + private Optional findGoodExchange() { - var exchangeResultTL = getWidgetItemId(849, 21); - var exchangeResultTR = getWidgetItemId(849, 24); - var exchangeResultBL = getWidgetItemId(849, 27); - var exchangeResultBR = getWidgetItemId(849, 30); + var exchangeResultTL = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_1_MODEL); + var exchangeResultTR = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_2_MODEL); + var exchangeResultBL = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_3_MODEL); + var exchangeResultBR = getWidgetItemId(InterfaceID.PogCoinExchanger.OUTPUT_4_MODEL); for (var puzzleNeed : solution.puzzleNeeds) { if (puzzleNeed.getAllIds().contains(exchangeResultTL)) { - return Optional.of(Pair.of(849, 21)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_1_MODEL); } if (puzzleNeed.getAllIds().contains(exchangeResultTR)) { - return Optional.of(Pair.of(849, 24)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_2_MODEL); } if (puzzleNeed.getAllIds().contains(exchangeResultBL)) { - return Optional.of(Pair.of(849, 27)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_3_MODEL); } if (puzzleNeed.getAllIds().contains(exchangeResultBR)) { - return Optional.of(Pair.of(849, 30)); + return Optional.of(InterfaceID.PogCoinExchanger.OUTPUT_4_MODEL); } } @@ -689,9 +690,9 @@ protected void updateSteps() exchangerConfirm.clearWidgetHighlights(); // Highlight the confirm button - exchangerConfirm.addWidgetHighlight(849, 36); + exchangerConfirm.addWidgetHighlight(InterfaceID.PogCoinExchanger.SUBMIT); // Highlight the widget with the good exchange - exchangerConfirm.addWidgetHighlight(goodExchangeWidget.getLeft(), goodExchangeWidget.getRight()); + exchangerConfirm.addWidgetHighlight(goodExchangeWidget); startUpStep(exchangerConfirm); return; } @@ -699,9 +700,9 @@ protected void updateSteps() exchangerInsertDisc.setRequirements(solution.toExchange); // Exchanger widget is open - var exchangeInput1 = getWidgetItemId(849, 8); - var exchangeInput2 = getWidgetItemId(849, 13); - var exchangeInput3 = getWidgetItemId(849, 18); + var exchangeInput1 = getWidgetItemId(InterfaceID.PogCoinExchanger.INPUT_1_MODEL); + var exchangeInput2 = getWidgetItemId(InterfaceID.PogCoinExchanger.INPUT_2_MODEL); + var exchangeInput3 = getWidgetItemId(InterfaceID.PogCoinExchanger.INPUT_3_MODEL); List exchangeInputs = Stream.of(exchangeInput1, exchangeInput2, exchangeInput3).filter(itemId -> itemId > 0).collect(Collectors.toUnmodifiableList()); // TODO: Validate that the correct disc is in one of the 3 exchange slots (need their widget IDs or varbits) @@ -713,7 +714,7 @@ protected void updateSteps() // Highlight the first exchanger input exchangerInsertDisc.clearWidgetHighlights(); - exchangerInsertDisc.addWidgetHighlight(849, 8); + exchangerInsertDisc.addWidgetHighlight(InterfaceID.PogCoinExchanger.INPUT_1_MODEL); startUpStep(exchangerInsertDisc); return; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java index 1c9e04dbf0..97cbbe87f1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thepathofglouphrie/sections/TheWarpedDepths.java @@ -59,6 +59,7 @@ public void setup(ThePathOfGlouphrie quest) sewer1Ladder.addRecommended(quest.earmuffsOrSlayerHelmet); sewer2Ladder = new ObjectStep(quest, ObjectID.POG_SEWER_LADDER_TOP, new WorldPoint(1529, 4236, 1), "Climb down the ladder to the east."); + sewer2Ladder.setForceClickboxHighlight(true); sewer2Ladder.addRecommended(quest.protectMissiles); sewer2Ladder.addRecommended(quest.earmuffsOrSlayerHelmetEquipped); sewer3Ladder = new ObjectStep(quest, ObjectID.POG_SEWER_PIPE_SIDE_LADDER, new WorldPoint(1529, 4253, 0), @@ -67,6 +68,7 @@ public void setup(ThePathOfGlouphrie quest) sewer3Ladder.addRecommended(quest.earmuffsOrSlayerHelmetEquipped); sewer4Ladder = new ObjectStep(quest, ObjectID.POG_SEWER_LADDER_TOP, new WorldPoint(1486, 4282, 1), "Climb down the ladder to the north-west. Re-activate your run if you step in any puddles."); + sewer4Ladder.setForceClickboxHighlight(true); sewer4Ladder.addRecommended(quest.protectMissiles); sewer4Ladder.addRecommended(quest.earmuffsOrSlayerHelmetEquipped); sewer4Ladder.setLinePoints(List.of( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theredreef/TheRedReef.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theredreef/TheRedReef.java new file mode 100644 index 0000000000..3dac4184e5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theredreef/TheRedReef.java @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2026, pajlada + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.helpers.quests.theredreef; + +import net.runelite.client.plugins.microbot.questhelper.bank.banktab.BankSlotIcons; +import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; +import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; +import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NoFollowerRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.CombatLevelRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.PolyZone; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; +import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; +import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.runelite.client.plugins.microbot.questhelper.steps.WorldEntityStep; +import net.runelite.api.QuestState; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; + +public class TheRedReef extends BasicQuestHelper +{ + // Required items + ItemRequirement rangedCombatGearOrShipWithCannons; + ItemRequirement combatGear; + ItemRequirement combatGearBethel; + ItemRequirement combatGearLobster; + + // Recommended items + ItemRequirement food; + ItemRequirement prayerPotions; + ItemRequirement repairKits; + + // Mid-quest item requirements + ItemRequirement divingHelmet; + ItemRequirement divingHelmetEquipped; + ItemRequirement divingApparatus; + ItemRequirement divingApparatusEquipped; + + // Zones + Zone redRock; + Zone lastLightF0; + + // Miscellaneous requirements + ZoneRequirement onRedRock; + ZoneRequirement onLastLightF0; + ZoneRequirement onLastLightF1; + ZoneRequirement onLastLightF2; + NpcRequirement onZenith; + VarbitRequirement diving; + NpcRequirement giantLobsterAround; + VarbitRequirement onBoat; + FreeInventorySlotRequirement freeInv2; + NoFollowerRequirement noFollower; + + // Steps + // 0 + 2 + NpcStep talkToRaleyToStartQuest; + + // 4 + NpcStep talkToFinn; + + // 6 + NpcStep talkToElderKatt; + + // 8 + NpcStep talkToFloopa; + + // 10 + DetailedQuestStep sailToRedRock; + + // 12 + NpcStep talkToRedRockReceptionist; + + // 14 + ConditionalStep cInspectCases; + + // 16 + NpcStep talkToTheodorePaxton; + + // 18 + NpcStep sinkBlackEyeBethelBoats; + + // 20 + ObjectStep disembarkAtLastLight; + + // 22 + NpcStep killPiratesAtLastLight; + + // 24 + ObjectStep climbUpToF1; + ObjectStep climbUpToF2; + NpcStep killBlackEyeBethel; + + // 26 + ObjectStep climbDownToF1; + ObjectStep climbDownToF0; + ObjectStep sailToRedRock2; + ObjectStep boardYourShip; + NpcStep talkToTheodorePaxtonAgain; + ConditionalStep cReturnToTheodorePaxton; + + // 28 + WorldEntityStep sailToZenith; + + // 30 + NpcStep talkToSpencerBrentwood; + DetailedQuestStep equipDivingGearAndDive; + NpcStep dive; + DetailedQuestStep listenToSpencer; + + // 32 + ObjectStep repairCoralDredger; + NpcStep fightTheGiantLobster; + + // 34 + ObjectStep repairCoralDredger2; + + // 36 + NpcStep talkToSpencerNearEastCoralDredger; + + // 38 + NpcStep talkToSpencerAboutFuturePlans; + + // 40 + ConditionalStep cReturnToFloopa; + + @Override + protected void setupZones() + { + redRock = new PolyZone(List.of( + new WorldPoint(2809, 2508, 0), + new WorldPoint(2804, 2511, 0) + )); + + lastLightF0 = new Zone( + new WorldPoint(2867, 2319, 0), + new WorldPoint(2849, 2335, 0) + ); + } + + @Override + protected void setupRequirements() + { + rangedCombatGearOrShipWithCannons = new ItemRequirement("Ranged/Mage combat gear to skip boat combat, or a boat with cannons to deal with pirates", -1, -1).isNotConsumed(); + rangedCombatGearOrShipWithCannons.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + combatGear = new ItemRequirement("Combat gear", -1, -1).isNotConsumed(); + combatGear.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + combatGearBethel = new ItemRequirement("Combat gear to fight Black Eye Bethel", -1, -1).isNotConsumed(); + combatGearBethel.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + combatGearLobster = new ItemRequirement("Any combat gear to fight a giant lobster", -1, -1).isNotConsumed(); + combatGearLobster.setDisplayItemId(BankSlotIcons.getRangedCombatGear()); + + food = new ItemRequirement("Food", ItemCollections.GOOD_EATING_FOOD, -1); + prayerPotions = new ItemRequirement("Prayer potions", ItemCollections.PRAYER_POTIONS, -1); + repairKits = new ItemRequirement("Boat repair kits", ItemCollections.BOAT_REPAIR_KITS, 5); + + divingHelmet = new ItemRequirement("Deep sea helmet", ItemID.TRR_DIVING_HELMET); + divingHelmetEquipped = divingHelmet.equipped(); + divingHelmetEquipped.setHighlightInInventory(true); + divingApparatus = new ItemRequirement("Deep sea apparatus", ItemID.TRR_DIVING_BACKPACK); + divingApparatusEquipped = divingApparatus.equipped(); + divingApparatusEquipped.setHighlightInInventory(true); + + var rr1 = new Zone( + new WorldPoint(2805, 2500, 0), + new WorldPoint(2790, 2527, 0) + ); + var rr2 = new Zone( + new WorldPoint(2808, 2521, 0), + new WorldPoint(2806, 2522, 0) + ); + var rr3 = new Zone( + new WorldPoint(2806, 2510, 0), + new WorldPoint(2808, 2509, 0) + ); + var rr4 = new Zone( + new WorldPoint(2789, 2515, 0), + new WorldPoint(2785, 2529, 0) + ); + onRedRock = new ZoneRequirement(rr1, rr2, rr3, rr4); + + onLastLightF0 = new ZoneRequirement(lastLightF0); + onLastLightF1 = new ZoneRequirement(new Zone(11300, 1)); + onLastLightF2 = new ZoneRequirement(new Zone(11300, 2)); + + onZenith = new NpcRequirement(NpcID.TRR_SPENCER_BRENTWOOD_VIS); + + diving = new VarbitRequirement(VarbitID.PLAYER_DIVING, 1); + giantLobsterAround = new NpcRequirement(NpcID.TRR_GIANT_LOBSTER); + onBoat = new VarbitRequirement(VarbitID.SAILING_BOARDED_BOAT, 1); + freeInv2 = new FreeInventorySlotRequirement(2); + noFollower = new NoFollowerRequirement("No pet following you"); + } + + void setupSteps() + { + talkToRaleyToStartQuest = new NpcStep(this, NpcID.TT_RALEY_CONCH, new WorldPoint(3186, 2405, 0), "Talk to Elder Raley at his home in The Great Conch to start the quest."); + talkToRaleyToStartQuest.addDialogStep("Yes."); + + talkToFinn = new NpcStep(this, NpcID.TORTUGAN_FINN, new WorldPoint(3197, 2401, 0), "Talk to Finn, south-east of Elder Raley's house, about Floopa's whereabouts."); + + talkToElderKatt = new NpcStep(this, NpcID.TORTUGAN_GROVE_GUARDIAN, new WorldPoint(3196, 2466, 0), "Head to The Sacred Grove and talk to Elder Katt."); + + talkToFloopa = new NpcStep(this, NpcID.TRR_FLOOPA_VIS, new WorldPoint(3194, 2490, 0), "Enter The Sacred Grove and talk to Floopa."); + + sailToRedRock = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(2809, 2509, 0), "Sail to Red Rock, north-west of The Great Conch."); + + talkToRedRockReceptionist = new NpcStep(this, NpcID.TRR_RED_ROCK_RECEPTIONIST, new WorldPoint(2792, 2522, 0), "Talk to the receptionist on Red Rock."); + + var needToInspectCase1 = new VarbitRequirement(VarbitID.TRR_DISPLAY_CASE_1, 0); + var inspectCase1 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_1, new WorldPoint(2796, 2522, 0), ""); + + var needToInspectCase2 = new VarbitRequirement(VarbitID.TRR_DISPLAY_CASE_2, 0); + var inspectCase2 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_2, new WorldPoint(2794, 2524, 0), ""); + + var needToInspectCase3 = new VarbitRequirement(VarbitID.TRR_DISPLAY_CASE_3, 0); + var inspectCase3 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_3, new WorldPoint(2789, 2523, 0), ""); + + var inspectCase4 = new ObjectStep(this, ObjectID.TRR_DISPLAY_CASE_4, new WorldPoint(2789, 2519, 0), ""); + + cInspectCases = new ConditionalStep(this, inspectCase4, "Familiarize yourself with the history of the Red Reef Trading Company by inspecting the display cases around the building."); + cInspectCases.addStep(needToInspectCase1, inspectCase1); + cInspectCases.addStep(needToInspectCase2, inspectCase2); + cInspectCases.addStep(needToInspectCase3, inspectCase3); + + talkToTheodorePaxton = new NpcStep(this, NpcID.TRR_THEODORE_PAXTON, new WorldPoint(2795, 2517, 0), "Talk to Theodore Paxton."); + + // TODO: add all pirate npc ids + sinkBlackEyeBethelBoats = new NpcStep(this, new int[]{NpcID.TRR_PIRATE_1, NpcID.TRR_PIRATE_2, NpcID.TRR_PIRATE_3, NpcID.TRR_PIRATE_4}, new WorldPoint(2834, 2357, 0), + "Get ready for boat combat, then sail south towards Last Light and deal with Black Eye Bethel. Protect from Missiles to avoid most damage. Repair your ship. " + + "Combat is over when all boats are sunk or all pirates are killed.", rangedCombatGearOrShipWithCannons, combatGearBethel); + sinkBlackEyeBethelBoats.setRecommended(List.of(food, prayerPotions, repairKits)); + + disembarkAtLastLight = new ObjectStep(this, ObjectID.SAILING_MOORING_DISEMBARK, new WorldPoint(2849, 2327, 0), "Disembark at Last Light."); + + killPiratesAtLastLight = new NpcStep(this, new int[]{NpcID.TRR_PIRATE_1, NpcID.TRR_PIRATE_2, NpcID.TRR_PIRATE_3, NpcID.TRR_PIRATE_4}, new WorldPoint(2855, 2325, 0), "Kill all six pirates at Last Light.", true); + + var blackEyeBethelText = "Kill Black Eye Bethel. Use Protect from Melee to avoid some damage. Avoid her charge attack. Re-enable your prayers if she disables them."; + climbUpToF1 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_BASE, new WorldPoint(2863, 2326, 0), blackEyeBethelText, combatGearBethel); + climbUpToF2 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_MIDDLE, new WorldPoint(2863, 2326, 1), blackEyeBethelText, combatGearBethel); + climbUpToF2.addDialogStep("Climb up."); + killBlackEyeBethel = new NpcStep(this, NpcID.TRR_PIRATE_CAPTAIN, new WorldPoint(2862, 2323, 2), blackEyeBethelText, combatGearBethel); + killBlackEyeBethel.addSubSteps(climbUpToF1, climbUpToF2); + + sailToRedRock2 = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(2809, 2509, 0), "Sail to Red Rock, north of Last Light."); + climbDownToF1 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_TOP, new WorldPoint(2863, 2326, 2), "Climb down the tower."); + climbDownToF0 = new ObjectStep(this, ObjectID.LAST_LIGHT_SPIRALSTAIRS_MIDDLE, new WorldPoint(2862, 2326, 1), "Climb down the tower."); + climbDownToF0.addDialogStep("Climb down."); + boardYourShip = new ObjectStep(this, ObjectID.SAILING_MOORING_EMBARK, new WorldPoint(2849, 2327, 0), "Board your boat."); + talkToTheodorePaxtonAgain = new NpcStep(this, NpcID.TRR_THEODORE_PAXTON, new WorldPoint(2795, 2517, 0), "Talk to Theodore Paxton."); + cReturnToTheodorePaxton = new ConditionalStep(this, sailToRedRock2, "Return to Theodore Paxton on Red Rock with the good news."); + cReturnToTheodorePaxton.addStep(onRedRock, talkToTheodorePaxtonAgain); + cReturnToTheodorePaxton.addStep(onLastLightF2, climbDownToF1); + cReturnToTheodorePaxton.addStep(onLastLightF1, climbDownToF0); + cReturnToTheodorePaxton.addStep(onLastLightF0, boardYourShip); + + sailToZenith = new WorldEntityStep(this, 9, new WorldPoint(2874, 2506, 0), + "Sail to and board the Zenith, east of Red Rock. If you don't see the Zenith there, try hopping to a different world.", combatGearLobster); + talkToSpencerBrentwood = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, new WorldPoint(2878, 2505, 0), "Talk to Spencer Brentwood aboard the Zenith.", combatGearLobster); + equipDivingGearAndDive = new DetailedQuestStep(this, "Equip the deep sea diving gear and dive down to the bottom of the sea.", combatGearLobster, divingHelmetEquipped, divingApparatusEquipped); + dive = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, "Talk to Spencer Brentwood again with the deep sea diving gear equipped to dive down to the bottom of the sea.", combatGearLobster, divingHelmetEquipped, divingApparatusEquipped, noFollower); + dive.addDialogStep("Let's go."); + dive.addSubSteps(equipDivingGearAndDive); + listenToSpencer = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_DIVING_A, new WorldPoint(2836, 8922, 1), "Listen to Spencer Brentwood's instructions."); + + repairCoralDredger = new ObjectStep(this, ObjectID.TRR_CORAL_DREDGER_BROKEN_OP, new WorldPoint(2844, 8942, 1), "Head north and repair the Coral dredger, ready to fight a Giant lobster.", combatGearLobster); + fightTheGiantLobster = new NpcStep(this, NpcID.TRR_GIANT_LOBSTER, "Kill the Giant lobster. Avoid the blue particles on the floor."); + + repairCoralDredger2 = new ObjectStep(this, ObjectID.TRR_CORAL_DREDGER_BROKEN_OP, new WorldPoint(2844, 8942, 1), "Repair the Coral dredger."); + + talkToSpencerNearEastCoralDredger = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_DIVING_VIS, new WorldPoint(2857, 8915, 1), "Talk to Spencer Brentwood near the eastern coral dredger."); + + talkToSpencerAboutFuturePlans = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, new WorldPoint(2878, 2505, 0), "Talk to Spencer Brentwood aboard the Zenith after repairing the coral dredgers."); + + var talkToSpencerBrentwoodAgain = new NpcStep(this, NpcID.TRR_SPENCER_BRENTWOOD_VIS, new WorldPoint(2878, 2505, 0), "Return to Spencer Brentwood to disembark onto your boat."); + talkToSpencerBrentwoodAgain.addDialogStep("Actually, I'd like to disembark."); + + var sailToGreatConch = new ObjectStep(this, ObjectID.SAILING_GANGPLANK_DISEMBARK, new WorldPoint(3174, 2367, 0), "Sail to The Great Conch."); + var talkToFloopaAtElderRaleysHouse = new NpcStep(this, NpcID.TT_FLOOPA_VIS, new WorldPoint(3185, 2405, 0), ""); + + cReturnToFloopa = new ConditionalStep(this, talkToFloopaAtElderRaleysHouse, "Return to Floopa at Elder Raley's house at The Great Conch."); + cReturnToFloopa.addStep(onZenith, talkToSpencerBrentwoodAgain); + cReturnToFloopa.addStep(onBoat, sailToGreatConch); + } + + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToRaleyToStartQuest); + steps.put(2, talkToRaleyToStartQuest); + + steps.put(4, talkToFinn); + + steps.put(6, talkToElderKatt); + + steps.put(8, talkToFloopa); + + steps.put(10, sailToRedRock); + + var cTalkToReceptionist = new ConditionalStep(this, sailToRedRock); + cTalkToReceptionist.addStep(onRedRock, talkToRedRockReceptionist); + steps.put(12, cTalkToReceptionist); + + var cInspectCases = new ConditionalStep(this, sailToRedRock); + cInspectCases.addStep(onRedRock, this.cInspectCases); + steps.put(14, cInspectCases); + + var cTalkToMrPaxton = new ConditionalStep(this, sailToRedRock); + cTalkToMrPaxton.addStep(onRedRock, talkToTheodorePaxton); + steps.put(16, cTalkToMrPaxton); + + steps.put(18, sinkBlackEyeBethelBoats); + + steps.put(20, disembarkAtLastLight); + + var cKillPiratesAtLastLight = new ConditionalStep(this, disembarkAtLastLight); + cKillPiratesAtLastLight.addStep(onLastLightF0, killPiratesAtLastLight); + steps.put(22, cKillPiratesAtLastLight); + + var cKillBlackEyeBethel = new ConditionalStep(this, disembarkAtLastLight); + cKillBlackEyeBethel.addStep(onLastLightF0, climbUpToF1); + cKillBlackEyeBethel.addStep(onLastLightF1, climbUpToF2); + cKillBlackEyeBethel.addStep(onLastLightF2, killBlackEyeBethel); + steps.put(24, cKillBlackEyeBethel); + + steps.put(26, cReturnToTheodorePaxton); + + var cInitialDive = new ConditionalStep(this, sailToZenith); + cInitialDive.addStep(diving, listenToSpencer); + cInitialDive.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cInitialDive.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cInitialDive.addStep(onZenith, talkToSpencerBrentwood); + steps.put(28, cInitialDive); + steps.put(30, cInitialDive); + + var cFightLobster = new ConditionalStep(this, sailToZenith); + cFightLobster.addStep(and(diving, giantLobsterAround), fightTheGiantLobster); + cFightLobster.addStep(diving, repairCoralDredger); + cFightLobster.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cFightLobster.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cFightLobster.addStep(onZenith, talkToSpencerBrentwood); + + steps.put(32, cFightLobster); + + var cRepairNorthernCoralDredger = new ConditionalStep(this, sailToZenith); + cRepairNorthernCoralDredger.addStep(diving, repairCoralDredger2); + cRepairNorthernCoralDredger.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cRepairNorthernCoralDredger.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cRepairNorthernCoralDredger.addStep(onZenith, talkToSpencerBrentwood); + steps.put(34, cRepairNorthernCoralDredger); + + var cRepairEasternCoralDredgerWithSpencer = new ConditionalStep(this, sailToZenith); + cRepairEasternCoralDredgerWithSpencer.addStep(diving, talkToSpencerNearEastCoralDredger); + cRepairEasternCoralDredgerWithSpencer.addStep(and(onZenith, divingApparatusEquipped, divingHelmetEquipped), dive); + cRepairEasternCoralDredgerWithSpencer.addStep(and(onZenith, divingApparatus, divingHelmet), equipDivingGearAndDive); + cRepairEasternCoralDredgerWithSpencer.addStep(onZenith, talkToSpencerBrentwood); + + steps.put(36, cRepairEasternCoralDredgerWithSpencer); + + var cTalkToSpencerAboutFuturePlans = new ConditionalStep(this, sailToZenith); + cTalkToSpencerAboutFuturePlans.addStep(onZenith, talkToSpencerAboutFuturePlans); + + steps.put(38, cTalkToSpencerAboutFuturePlans); + + steps.put(40, cReturnToFloopa); + + return steps; + } + + @Override + public List getGeneralRequirements() + { + return List.of( + new QuestRequirement(QuestHelperQuest.TROUBLED_TORTUGANS, QuestState.FINISHED), + new SkillRequirement(Skill.SAILING, 52, false), + new SkillRequirement(Skill.SMITHING, 48, false) + ); + } + + @Override + public List getGeneralRecommended() + { + return List.of( + new SkillRequirement(Skill.PRAYER, 40, false, "43 prayer for Protect from Missiles & Melee"), + new CombatLevelRequirement(65) + ); + } + + @Override + public List getItemRequirements() + { + return List.of( + rangedCombatGearOrShipWithCannons, + combatGear + ); + } + + @Override + public List getItemRecommended() + { + return List.of( + food, + prayerPotions, + repairKits + ); + } + + @Override + public List getCombatRequirements() + { + return List.of( + "2 pirate ships, or the crew on the ship with ranged combat gear", + "6 pirates (lvl 52)", + "Black Eye Bethel (lvl 191)", + "Giant lobster (lvl 112)" + ); + } + + @Override + public QuestPointReward getQuestPointReward() + { + return new QuestPointReward(2); + } + + @Override + public List getExperienceRewards() + { + return List.of( + new ExperienceReward(Skill.SAILING, 15000), + new ExperienceReward(Skill.SMITHING, 5000) + ); + } + + @Override + public List getItemRewards() + { + return List.of( + new ItemReward("Bosun's Workbench Schematic", /*ItemID.LOST_SCHEMATIC_BOSUNS_WORKBENCH*/ -1) // NOTE: The gameval for this item is not in the latest RuneLite release + ); + } + + @Override + public List getUnlockRewards() + { + return List.of( + new UnlockReward("Access to the Great Conch sacred grove") + ); + } + + @Override + public List getPanels() + { + var sections = new ArrayList(); + + sections.add(new PanelDetails("Finding Floopa", List.of( + talkToRaleyToStartQuest, + talkToFinn, + talkToElderKatt, + talkToFloopa + ))); + + sections.add(new PanelDetails("Infiltrating the Red Reef", List.of( + sailToRedRock, + talkToRedRockReceptionist, + cInspectCases, + talkToTheodorePaxton + ))); + + sections.add(new PanelDetails("Dealing with Black Eye Bethel", List.of( + sinkBlackEyeBethelBoats, + disembarkAtLastLight, + killPiratesAtLastLight, + killBlackEyeBethel, + cReturnToTheodorePaxton + ), List.of( + rangedCombatGearOrShipWithCannons, + combatGearBethel + ), List.of( + food, + prayerPotions, + repairKits + ))); + + sections.add(new PanelDetails("Helping the Zenith", List.of( + sailToZenith, + talkToSpencerBrentwood, + dive, + listenToSpencer, + repairCoralDredger, + fightTheGiantLobster, + repairCoralDredger2, + talkToSpencerNearEastCoralDredger, + talkToSpencerAboutFuturePlans + ), List.of( + combatGearLobster, + freeInv2 + ), List.of( + food + ))); + + sections.add(new PanelDetails("Return to Floopa", List.of( + cReturnToFloopa + ))); + + return sections; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java index aa5fa847ba..534620bed0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/therestlessghost/TheRestlessGhost.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,6 +41,10 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -47,13 +52,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class TheRestlessGhost extends BasicQuestHelper { // Recommended items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java index 02a15095ca..f692f5bf4e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/theslugmenace/PuzzleStep.java @@ -5,8 +5,8 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.events.VarbitChanged; import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.VarPlayerID; import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java index ee1bfac569..64b0ec34b7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/thetouristtrap/TheTouristTrap.java @@ -191,7 +191,7 @@ protected void setupRequirements() bronzeBar3 = new ItemRequirement("Bronze bars", ItemID.BRONZE_BAR, 3); hammer = new ItemRequirement("Hammer", ItemCollections.HAMMER).isNotConsumed(); - metalKey = new KeyringRequirement("Metal key", configManager, KeyringCollection.METAL_KEY); + metalKey = new KeyringRequirement("Metal key", KeyringCollection.METAL_KEY); metalKey.setTooltip("You can get another by killing the Mercenary Guard outside the Desert Mining Camp"); slaveTop = new ItemRequirement("Slave shirt", ItemID.SLAVE_SHIRT); slaveTop.setTooltip("You can trade in a desert robe set for slave clothes with the Male Slave"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java index 100a526c8f..25371badb2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/throneofmiscellania/ThroneOfMiscellania.java @@ -45,7 +45,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; @@ -476,15 +480,6 @@ public List getItemRequirements() return reqs; } - @Override - public List getNotes() - { - ArrayList reqs = new ArrayList<>(); - reqs.add("Currently this helper only shows you how to marry Astrid. If you'd like to be friends with her or choose to be with Brand, " + - "you can either follow an external guide for now, or simply talk to King Vargas after the quest to change."); - return reqs; - } - @Override public List getItemRecommended() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java index 0a50496100..98e697d07b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/toweroflife/PuzzleSolver.java @@ -246,7 +246,6 @@ private class PipeSolverSolution { private final WidgetDetails pieceInfo; - private final Widget piece; private final int correctOrientation, selectedVBit, targetX, targetY; public PipeSolverSolution(WidgetDetails piece, int targetX, int targetY, int correctOrientation, int selectedVBit) @@ -257,15 +256,20 @@ public PipeSolverSolution(WidgetDetails piece, int targetX, int targetY, int cor public PipeSolverSolution(WidgetDetails pieceDetails, int targetX, int targetY, int correctOrientation, int selectedVBit, Function getPieceX, Function getPieceY) { this.pieceInfo = pieceDetails; - this.piece = PuzzleSolver.this.getWidget(pieceInfo); - if (this.piece == null) - throw new WidgetNotFoundException(); this.targetX = targetX; this.targetY = targetY; this.correctOrientation = correctOrientation; this.selectedVBit = selectedVBit; } + private Widget getPiece() + { + Widget widget = PuzzleSolver.this.getWidget(pieceInfo); + if (widget == null) + throw new WidgetNotFoundException(); + return widget; + } + public boolean isSolved() { return !isSelected(); @@ -278,27 +282,27 @@ public boolean isSelected() public boolean isLeft() { - return piece.getOriginalX() < targetX - 4; + return getPiece().getOriginalX() < targetX - 4; } public boolean isRight() { - return piece.getOriginalX() > targetX + 4; + return getPiece().getOriginalX() > targetX + 4; } public boolean isAbove() { - return piece.getOriginalY() < targetY - 4; + return getPiece().getOriginalY() < targetY - 4; } public boolean isBelow() { - return piece.getOriginalY() > targetY + 4; + return getPiece().getOriginalY() > targetY + 4; } public boolean isOriented() { - return piece.getModelId() == correctOrientation; + return getPiece().getModelId() == correctOrientation; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java index a195487284..9beea13352 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/treegnomevillage/TreeGnomeVillage.java @@ -33,6 +33,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.NpcHintArrowRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; @@ -42,7 +43,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -50,13 +60,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class TreeGnomeVillage extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java index cf26b3e11f..d40f4b6171 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/PuzzleStep.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.events.GameTick; import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; @@ -40,26 +41,21 @@ public class PuzzleStep extends QuestStep { - private final Character ENTRY_ONE = 'K'; - private final Character ENTRY_TWO = 'U'; - private final Character ENTRY_THREE = 'R'; - private final Character ENTRY_FOUR = 'T'; - - private final int SLOT_ONE = 42; - private final int SLOT_TWO = 43; - private final int SLOT_THREE = 44; - private final int SLOT_FOUR = 45; - - private final int ARROW_ONE_LEFT = 46; - private final int ARROW_ONE_RIGHT = 47; - private final int ARROW_TWO_LEFT = 48; - private final int ARROW_TWO_RIGHT = 49; - private final int ARROW_THREE_LEFT = 50; - private final int ARROW_THREE_RIGHT = 51; - private final int ARROW_FOUR_LEFT = 52; - private final int ARROW_FOUR_RIGHT = 53; - - private final int COMPLETE = 55; + private final int ENTRY_ONE = 11; // K + private final int ENTRY_TWO = 21; // U + private final int ENTRY_THREE = 18; // R + private final int ENTRY_FOUR = 20; // T + + private final int ARROW_ONE_LEFT = InterfaceID.TribalDoor.TRIBALA_LEFT; + private final int ARROW_ONE_RIGHT = InterfaceID.TribalDoor.TRIBALA_RIGHT; + private final int ARROW_TWO_LEFT = InterfaceID.TribalDoor.TRIBALB_LEFT; + private final int ARROW_TWO_RIGHT = InterfaceID.TribalDoor.TRIBALB_RIGHT; + private final int ARROW_THREE_LEFT = InterfaceID.TribalDoor.TRIBALC_LEFT; + private final int ARROW_THREE_RIGHT = InterfaceID.TribalDoor.TRIBALC_RIGHT; + private final int ARROW_FOUR_LEFT = InterfaceID.TribalDoor.TRIBALD_LEFT; + private final int ARROW_FOUR_RIGHT = InterfaceID.TribalDoor.TRIBALD_RIGHT; + + private final int COMPLETE = InterfaceID.TribalDoor.TRIBALENTER; private final HashMap highlightButtons = new HashMap<>(); private final HashMap distance = new HashMap<>(); @@ -86,15 +82,15 @@ public void onGameTick(GameTick gameTick) private void updateSolvedPositionState() { - highlightButtons.replace(1, matchStateToSolution(SLOT_ONE, ENTRY_ONE, ARROW_ONE_RIGHT, ARROW_ONE_LEFT)); - highlightButtons.replace(2, matchStateToSolution(SLOT_TWO, ENTRY_TWO, ARROW_TWO_RIGHT, ARROW_TWO_LEFT)); - highlightButtons.replace(3, matchStateToSolution(SLOT_THREE, ENTRY_THREE, ARROW_THREE_RIGHT, ARROW_THREE_LEFT)); - highlightButtons.replace(4, matchStateToSolution(SLOT_FOUR, ENTRY_FOUR, ARROW_FOUR_RIGHT, ARROW_FOUR_LEFT)); + highlightButtons.replace(1, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE1, ENTRY_ONE, ARROW_ONE_RIGHT, ARROW_ONE_LEFT)); + highlightButtons.replace(2, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE2, ENTRY_TWO, ARROW_TWO_RIGHT, ARROW_TWO_LEFT)); + highlightButtons.replace(3, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE3, ENTRY_THREE, ARROW_THREE_RIGHT, ARROW_THREE_LEFT)); + highlightButtons.replace(4, matchStateToSolution(VarbitID.TOTEMQUEST_COMBODOOR_CODE4, ENTRY_FOUR, ARROW_FOUR_RIGHT, ARROW_FOUR_LEFT)); - distance.replace(1, matchStateToDistance(SLOT_ONE, ENTRY_ONE)); - distance.replace(2, matchStateToDistance(SLOT_TWO, ENTRY_TWO)); - distance.replace(3, matchStateToDistance(SLOT_THREE, ENTRY_THREE)); - distance.replace(4, matchStateToDistance(SLOT_FOUR, ENTRY_FOUR)); + distance.replace(1, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE1, ENTRY_ONE)); + distance.replace(2, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE2, ENTRY_TWO)); + distance.replace(3, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE3, ENTRY_THREE)); + distance.replace(4, matchStateToDistance(VarbitID.TOTEMQUEST_COMBODOOR_CODE4, ENTRY_FOUR)); if (highlightButtons.get(1) + highlightButtons.get(2) + highlightButtons.get(3) + highlightButtons.get(4) == 0) @@ -107,22 +103,17 @@ private void updateSolvedPositionState() } } - private int matchStateToSolution(int slot, Character target, int arrowRightId, int arrowLeftId) + private int matchStateToSolution(int varbitID, int target, int arrowRightId, int arrowLeftId) { - Widget widget = client.getWidget(InterfaceID.TRIBAL_DOOR, slot); - if (widget == null) return 0; - char current = widget.getText().charAt(0); - int currentPos = (int) current - (int) 'A'; - int id = Math.floorMod(currentPos - target, 26) < Math.floorMod(target - currentPos, 26) ? arrowRightId : arrowLeftId; - if (current != target) return id; + int currentPos = client.getVarbitValue(varbitID); + int id = Math.floorMod(currentPos - target, 26) < Math.floorMod(target - currentPos, 26) ? arrowLeftId : arrowRightId; + if (currentPos != target) return id; return 0; } - private int matchStateToDistance(int slot, Character target) + private int matchStateToDistance(int varbitID, int target) { - Widget widget = client.getWidget(InterfaceID.TRIBAL_DOOR, slot); - if (widget == null) return 0; - char current = widget.getText().charAt(0); + int current = client.getVarbitValue(varbitID); return Math.min(Math.floorMod(current - target, 26), Math.floorMod(target - current, 26)); } @@ -137,7 +128,7 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) continue; } - Widget widget = client.getWidget(InterfaceID.TRIBAL_DOOR, entry.getValue()); + Widget widget = client.getWidget(entry.getValue()); if (widget != null) { graphics.setColor(new Color(questHelper.getConfig().targetOverlayColor().getRed(), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java index c0d3ea0310..187a5a8396 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/tribaltotem/TribalTotem.java @@ -43,6 +43,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; @@ -127,7 +128,7 @@ public void setupConditions() { inEntrance = new ZoneRequirement(houseGroundFloorEntrance); inMiddleRoom = new ZoneRequirement(houseGroundFloorMiddleRoom); - openedLockWidget = new WidgetTextRequirement(369, 54,"Combination Lock Door"); + openedLockWidget = new WidgetTextRequirement(InterfaceID.TribalDoor.TITLE_TEXT, "Combination Lock Door"); inStairway = new ZoneRequirement(houseGroundFloor); investigatedStairs = new WidgetTextRequirement(229, 1, "Your trained senses as a thief enable you to see that there is a trap
in these stairs. You make a note of its location for future reference
when using these stairs."); isUpstairs = new ZoneRequirement(houseFirstFloor); @@ -137,7 +138,7 @@ public void setupConditions() public void setupSteps() { talkToKangaiMau = new NpcStep(this, NpcID.KANGAI_MAU, new WorldPoint(2794, 3182, 0), "Talk to Kangai Mau in the Brimhaven food store."); - talkToKangaiMau.addDialogSteps("I'm in search of adventure!", "Ok, I will get it back."); + talkToKangaiMau.addDialogSteps("I'm in search of adventure!", "Ok, I will get it back.", "Yes."); investigateCrate = new ObjectStep(this, ObjectID.HORNCRATE, new WorldPoint(2650, 3273, 0), "Travel to the GPDT depot in Ardougne and investigate the most northeastern crate for a label."); useLabel = new ObjectStep(this, ObjectID.TELEPORTCRATE, new WorldPoint(2650, 3271, 0), "Use the label on the highlighted crate.", addressLabel); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java index 234599667f..c1c125ca56 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/trollstronghold/TrollStronghold.java @@ -49,7 +49,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java index 6fa67c894e..91cb6ce6b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/RepairTown.java @@ -33,6 +33,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.List; import net.runelite.api.ItemContainer; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; @@ -42,8 +43,6 @@ import net.runelite.api.gameval.VarbitID; import net.runelite.client.eventbus.Subscribe; -import java.util.List; - public class RepairTown extends DetailedOwnerStep { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java index c7f7035eaf..cbaf94cd40 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/troubledtortugans/TroubledTortugans.java @@ -33,6 +33,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemOnTileRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.nor; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; @@ -40,7 +43,16 @@ import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -48,13 +60,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class TroubledTortugans extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java index 186f7c2675..119ef3a54b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/vampyreslayer/VampyreSlayer.java @@ -29,62 +29,83 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.*; - public class VampyreSlayer extends BasicQuestHelper { - //Items Required - ItemRequirement hammer, beer, garlic, garlicObtainable, stake, combatGear; - - //Items Recommended - ItemRequirement varrockTeleport, draynorManorTeleport; - - Requirement inManor, inBasement, isUpstairsInMorgans, draynorNearby; - - QuestStep talkToMorgan, goUpstairsMorgan, getGarlic, ifNeedGarlic, talkToHarlow, talkToHarlowAgain, enterDraynorManor, goDownToBasement, openCoffin, killDraynor; + // Required items + ItemRequirement hammer; + ItemRequirement beer; + ItemRequirement twoCoins; + ItemRequirements beerOrTwoCoins; + ItemRequirement combatGear; - //Zones - Zone manor, basement, upstairsInMorgans; - - @Override - public Map loadSteps() - { - initializeRequirements(); - setupConditions(); - setupSteps(); - Map steps = new HashMap<>(); + // Recommended items + ItemRequirement varrockTeleport; + ItemRequirement draynorManorTeleport; + ItemRequirement garlic; + ItemRequirement garlicObtainable; - steps.put(0, talkToMorgan); + // Mid-quest item requirements + ItemRequirement stake; - ConditionalStep getGarlicAndStake = new ConditionalStep(this, goUpstairsMorgan); - getGarlicAndStake.addStep(garlic, talkToHarlow); - getGarlicAndStake.addStep(isUpstairsInMorgans, getGarlic); + // Zones + Zone manor; + Zone basement; + Zone upstairsInMorgans; - steps.put(1, getGarlicAndStake); + // Miscellaneous requirements + ZoneRequirement inManor; + ZoneRequirement inBasement; + ZoneRequirement isUpstairsInMorgans; + NpcCondition draynorNearby; + Conditions givenBeerToHarlow; - ConditionalStep prepareAndKillDraynor = new ConditionalStep(this, getGarlicAndStake); - prepareAndKillDraynor.addStep(draynorNearby, killDraynor); - prepareAndKillDraynor.addStep(inBasement, openCoffin); - prepareAndKillDraynor.addStep(inManor, goDownToBasement); - prepareAndKillDraynor.addStep(stake, enterDraynorManor); + // Steps + NpcStep talkToMorgan; - steps.put(2, prepareAndKillDraynor); + ObjectStep goUpstairsMorgan; + ObjectStep getGarlic; + ConditionalStep cGetGarlic; + NpcStep talkToHarlow; + NpcStep buyBeer; + NpcStep talkToHarlowAgain; + ObjectStep enterDraynorManor; + ObjectStep goDownToBasement; + ObjectStep openCoffin; + NpcStep killDraynor; - return steps; + @Override + protected void setupZones() + { + basement = new Zone(new WorldPoint(3074, 9767, 0), new WorldPoint(3081, 9779, 0)); + manor = new Zone(new WorldPoint(3097, 3354, 0), new WorldPoint(3119, 3373, 0)); + upstairsInMorgans = new Zone(new WorldPoint(3096, 3266, 1), new WorldPoint(3102, 3270, 1)); } @Override @@ -96,77 +117,109 @@ protected void setupRequirements() stake.setTooltip("You can get another from Dr. Harlow in the Blue Moon Inn in Varrock."); hammer = new ItemRequirement("Hammer", ItemCollections.HAMMER).isNotConsumed(); garlic = new ItemRequirement("Garlic", ItemID.GARLIC); - garlic.setTooltip("Optional, makes Count Draynor weaker"); - beer = new ItemRequirement("A beer, or 2 coins to buy one", ItemID.BEER); + garlic.setTooltip("Weakens Count Draynor"); + beer = new ItemRequirement("Beer", ItemID.BEER); + twoCoins = new ItemRequirement("Coins", ItemID.COINS, 2); + beerOrTwoCoins = new ItemRequirements(LogicType.OR, "A beer, or 2 coins to buy one", beer, twoCoins); combatGear = new ItemRequirement("Combat gear + food to defeat Count Draynor", -1, -1).isNotConsumed(); combatGear.setDisplayItemId(BankSlotIcons.getCombatGear()); - garlicObtainable = new ItemRequirement("Garlic", ItemID.GARLIC); + garlicObtainable = garlic.copy(); garlicObtainable.canBeObtainedDuringQuest(); - } - public void setupConditions() - { inBasement = new ZoneRequirement(basement); inManor = new ZoneRequirement(manor); isUpstairsInMorgans = new ZoneRequirement(upstairsInMorgans); draynorNearby = new NpcCondition(NpcID.COUNT_DRAYNOR); - } - @Override - protected void setupZones() - { - basement = new Zone(new WorldPoint(3074, 9767, 0), new WorldPoint(3081, 9779, 0)); - manor = new Zone(new WorldPoint(3097, 3354, 0), new WorldPoint(3119, 3373, 0)); - upstairsInMorgans = new Zone(new WorldPoint(3096, 3266, 1), new WorldPoint(3102, 3270, 1)); + var givenBeerToHarlow1 = new DialogRequirement("You give a beer to Dr Harlow."); + givenBeerToHarlow1.setMustBeActive(true); + givenBeerToHarlow1.setAllowMesbox(true); + var givenBeerToHarlow2 = new DialogRequirement("Cheersh matey...", "So tell me how to kill vampyres then.", "Yesh, yesh vampyres, I was very good at killing em once", "Well, you're going to need a stake"); + givenBeerToHarlow2.setMustBeActive(true); + givenBeerToHarlow = or(givenBeerToHarlow1, givenBeerToHarlow2); } public void setupSteps() { talkToMorgan = new NpcStep(this, NpcID.MORGAN, new WorldPoint(3098, 3268, 0), "Talk to Morgan in the north of Draynor Village."); - talkToMorgan.addDialogStep("Ok, I'm up for an adventure."); - talkToMorgan.addDialogStep("Accept quest"); - goUpstairsMorgan = new ObjectStep(this, ObjectID.STAIRS, new WorldPoint(3100, 3267, 0), "Go upstairs in Morgan's house and search the cupboard for some garlic."); - getGarlic = new ObjectStep(this, ObjectID.GARLICCUPBOARDOPEN, new WorldPoint(3096, 3270, 1), "Search the cupboard upstairs in Morgan's house."); - ((ObjectStep) getGarlic).addAlternateObjects(ObjectID.GARLICCUPBOARDSHUT); - ifNeedGarlic = new DetailedQuestStep(this, "If you need garlic, you can get some from the cupboard upstairs in Morgan's house."); - ifNeedGarlic.addSubSteps(goUpstairsMorgan, getGarlic); - - talkToHarlow = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow in the Blue Moon Inn in Varrock.", beer); + talkToMorgan.addDialogStep("Yes."); + + goUpstairsMorgan = new ObjectStep(this, ObjectID.STAIRS, new WorldPoint(3100, 3267, 0), "Climb the stairs."); + getGarlic = new ObjectStep(this, ObjectID.GARLICCUPBOARDOPEN, new WorldPoint(3096, 3270, 1), "Search the cupboard."); + getGarlic.addAlternateObjects(ObjectID.GARLICCUPBOARDSHUT); + cGetGarlic = new ConditionalStep(this, goUpstairsMorgan, "Get garlic from the cupboard upstairs in Morgan's house.\n\nYou can tick off this section in the sidebar to skip the garlic acquisition."); + cGetGarlic.addStep(isUpstairsInMorgans, getGarlic); + + talkToHarlow = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow in the Blue Moon Inn in Varrock.", beerOrTwoCoins); talkToHarlow.addDialogStep("Morgan needs your help!"); - talkToHarlowAgain = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow again with a beer. You can buy one for 2gp in the Blue Moon Inn.", beer); - enterDraynorManor = new ObjectStep(this, ObjectID.HAUNTEDDOORL, new WorldPoint(3108, 3353, 0), "Prepare to fight Count Draynor (level 34), and enter Draynor Manor.", combatGear, stake, hammer, garlic); - goDownToBasement = new ObjectStep(this, ObjectID.CRYPTSTAIRSDOWN, new WorldPoint(3116, 3358, 0), "Enter Draynor Manor's basement.", combatGear, stake, hammer, garlic); - openCoffin = new ObjectStep(this, ObjectID.VAMPCOFFIN, new WorldPoint(3078, 9776, 0), "Open the coffin and kill Count Draynor.", combatGear, stake, hammer, garlic); - killDraynor = new NpcStep(this, NpcID.COUNT_DRAYNOR, new WorldPoint(3077, 9769, 0), "Kill Count Draynor.", combatGear, stake, hammer, garlic); + buyBeer = new NpcStep(this, NpcID.BLUEMOON_BARTENDER, "Buy a beer from the bartender in the Blue Moon Inn in Varrock.", twoCoins); + buyBeer.addDialogStep("A glass of your finest ale please."); + talkToHarlowAgain = new NpcStep(this, NpcID.DR_HARLOW, new WorldPoint(3222, 3399, 0), "Talk to Dr. Harlow again with a beer.", beer); + talkToHarlowAgain.addDialogStep("Yes. Here you go."); + + List countDraynorReqs = List.of(hammer, stake, combatGear); + List countDraynorRecommended = List.of(garlic); + enterDraynorManor = new ObjectStep(this, ObjectID.HAUNTEDDOORL, new WorldPoint(3108, 3353, 0), "Prepare to fight Count Draynor (level 34), and enter Draynor Manor.", countDraynorReqs, countDraynorRecommended); + goDownToBasement = new ObjectStep(this, ObjectID.CRYPTSTAIRSDOWN, new WorldPoint(3116, 3358, 0), "Enter Draynor Manor's basement.", countDraynorReqs, countDraynorRecommended); + openCoffin = new ObjectStep(this, ObjectID.VAMPCOFFIN, new WorldPoint(3078, 9776, 0), "Open the coffin and kill Count Draynor.", countDraynorReqs, countDraynorRecommended); + killDraynor = new NpcStep(this, NpcID.COUNT_DRAYNOR, new WorldPoint(3077, 9769, 0), "Kill Count Draynor.", countDraynorReqs, countDraynorRecommended); openCoffin.addSubSteps(killDraynor); } + @Override + public Map loadSteps() + { + initializeRequirements(); + setupSteps(); + + var steps = new HashMap(); + + steps.put(0, talkToMorgan); + + var getGarlicAndStake = new ConditionalStep(this, cGetGarlic); + getGarlicAndStake.addStep(garlic, talkToHarlow); + steps.put(1, getGarlicAndStake); + + var getStake = new ConditionalStep(this, talkToHarlowAgain); + getStake.addStep(givenBeerToHarlow, talkToHarlowAgain); + getStake.addStep(not(beer), buyBeer); + var prepareAndKillDraynor = new ConditionalStep(this, getStake); + prepareAndKillDraynor.addStep(draynorNearby, killDraynor); + prepareAndKillDraynor.addStep(inBasement, openCoffin); + prepareAndKillDraynor.addStep(inManor, goDownToBasement); + prepareAndKillDraynor.addStep(stake, enterDraynorManor); + + steps.put(2, prepareAndKillDraynor); + + return steps; + } + @Override public List getItemRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add(hammer); - reqs.add(beer); - reqs.add(combatGear); - return reqs; + return List.of( + hammer, + beerOrTwoCoins, + combatGear + ); } @Override public List getItemRecommended() { - ArrayList reqs = new ArrayList<>(); - reqs.add(varrockTeleport); - reqs.add(draynorManorTeleport); - reqs.add(garlicObtainable); - return reqs; + return List.of( + varrockTeleport, + draynorManorTeleport, + garlicObtainable + ); } @Override public List getCombatRequirements() { - ArrayList reqs = new ArrayList<>(); - reqs.add("Count Draynor (level 34)"); - return reqs; + return List.of( + "Count Draynor (level 34)" + ); } @Override @@ -178,17 +231,46 @@ public QuestPointReward getQuestPointReward() @Override public List getExperienceRewards() { - return Collections.singletonList(new ExperienceReward(Skill.ATTACK, 4825)); + return List.of( + new ExperienceReward(Skill.ATTACK, 4825) + ); } @Override public List getPanels() { - List allSteps = new ArrayList<>(); + var sections = new ArrayList(); + + sections.add(new PanelDetails("Starting off", List.of( + talkToMorgan + ))); + + var garlicSection = new PanelDetails("Get garlic", List.of( + cGetGarlic + )); + garlicSection.setLockingStep(cGetGarlic); + sections.add(garlicSection); + + sections.add(new PanelDetails("Get a stake", List.of( + talkToHarlow, + buyBeer, + talkToHarlowAgain + ), List.of( + beerOrTwoCoins + ))); + + sections.add(new PanelDetails("Kill Count Draynor", List.of( + enterDraynorManor, + goDownToBasement, + openCoffin + ), List.of( + hammer, + stake, + combatGear + ), List.of( + garlic + ))); - allSteps.add(new PanelDetails("Starting off", Arrays.asList(talkToMorgan, ifNeedGarlic))); - allSteps.add(new PanelDetails("Get a stake", Arrays.asList(talkToHarlow, talkToHarlowAgain), beer)); - allSteps.add(new PanelDetails("Kill Count Draynor", Arrays.asList(enterDraynorManor, goDownToBasement, openCoffin), hammer, stake, garlic, combatGear)); - return allSteps; + return sections; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java index 6d70f71b89..c24aa9b27e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/wanted/Wanted.java @@ -52,7 +52,11 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; +import net.runelite.api.gameval.VarPlayerID; import java.util.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java index 7e2e1bcda4..a815e6d73c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/watchtower/Watchtower.java @@ -45,7 +45,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.*; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; +import net.runelite.api.gameval.VarbitID; import java.util.*; @@ -467,7 +471,7 @@ public void setupSteps() stealRockCake = new ObjectStep(this, ObjectID.ROCKCOUNTER_WITHCAKES, new WorldPoint(2514, 3036, 0), "Steal a rock cake from Gu'Tanoth's market."); - talkToGuardBattlement = new NpcStep(this, NpcID.OGRE_GUARD3, new WorldPoint(2503, 3012, 0), "Talk to an Ogre Guard next to the battelement."); + talkToGuardBattlement = new NpcStep(this, NpcID.OGRE_GUARD3, new WorldPoint(2503, 3012, 0), "Talk to an Ogre Guard next to the battlement."); talkToGuardBattlement.addDialogStep("But I am a friend to ogres..."); talkToGuardWithRockCake = new ObjectStep(this, NpcID.OGRE_GUARD3, new WorldPoint(2507, 3012, 0), "Attempt to cross the battlement again with a rock cake.", rockCake); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java index 53a9e9909e..dbc6f03668 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/waterfallquest/WaterfallQuest.java @@ -29,13 +29,23 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarbitRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -43,10 +53,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; -import java.util.*; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; - public class WaterfallQuest extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java index cd5151d3ea..755a965577 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whatliesbelow/WhatLiesBelow.java @@ -185,6 +185,7 @@ public void setupSteps() talkToSurok = new NpcStep(this, NpcID.SUROK_SUROK, new WorldPoint(3211, 3493, 0), "Talk to Surok Magis in the Varrock Library.", letterToSurok); talkToSurokNoLetter = new NpcStep(this, NpcID.WGS_SUROK_TRANSITION, new WorldPoint(3211, 3493, 0), "Talk to Surok Magis in the Varrock Library."); + ((NpcStep) talkToSurokNoLetter).addAlternateNpcs(NpcID.SUROK_SUROK_TYPE1); talkToSurokNoLetter.addDialogSteps("Go on, then!", "Go on then!"); talkToSurok.addSubSteps(talkToSurokNoLetter); @@ -278,7 +279,7 @@ public List getPanels() List allSteps = new ArrayList<>(); allSteps.add(new PanelDetails("Starting off", Collections.singletonList(talkToRat))); allSteps.add(new PanelDetails("Help Rat", Arrays.asList(killOutlaws, bringFolderToRat))); - allSteps.add(new PanelDetails("Help Surok", Arrays.asList(talkToSurok, enterChaosAltar, useWandOnAltar, bringWandToSurok), chaosRunes15, chaosTalismanOrAbyss, bowl)); + allSteps.add(new PanelDetails("Help Surok", Arrays.asList(talkToSurok, enterChaosAltar, useWandOnAltar, bringWandToSurok), chaosRunes15, chaosTalismanOrAbyss, bowl, wand)); allSteps.add(new PanelDetails("Defeat Surok", Arrays.asList(talkToRatAfterSurok, talkToZaff, talkToSurokToFight, fightRoald, talkToRatToFinish))); return allSteps; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java index 777c1b452d..f72bf89f64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/whileguthixsleeps/WhileGuthixSleeps.java @@ -984,7 +984,7 @@ protected void setupRequirements() placedEarthBlock = new VarbitRequirement(VarbitID.WGS_EARTH_KEY_USED, 1); notPlacedFireBlock = new VarbitRequirement(VarbitID.WGS_FIRE_KEY_USED, 0); - noWeaponOrShieldEquipped = new ComplexRequirement("No weapon or shield equipped", new NoItemRequirement("", ItemSlots.WEAPON), new NoItemRequirement("", ItemSlots.SHIELD)); + noWeaponOrShieldEquipped = new NoItemRequirement("Nothing equipped in your hands", ItemSlots.EMPTY_HANDS); airCavity = new Zone(new WorldPoint(4107, 5095, 0), new WorldPoint(4119, 5116, 0)); inAirCavity = new ZoneRequirement(airCavity); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java index e88fb2908a..44fd46da66 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchshouse/WitchsHouse.java @@ -32,13 +32,25 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ObjectCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.FreeInventorySlotRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; import net.runelite.client.plugins.microbot.questhelper.requirements.var.VarplayerRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.rewards.ExperienceReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; -import net.runelite.client.plugins.microbot.questhelper.steps.*; +import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; +import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ItemStep; +import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; +import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; +import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; @@ -46,13 +58,6 @@ import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarPlayerID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.*; - public class WitchsHouse extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java index e33a50f6de..6dff4d5a39 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/witchspotion/WitchsPotion.java @@ -33,17 +33,16 @@ import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.ObjectStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.NpcID; import net.runelite.api.gameval.ObjectID; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class WitchsPotion extends BasicQuestHelper { // Required items diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java index cc33e64f75..5768cf0b31 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/helpers/quests/xmarksthespot/XMarksTheSpot.java @@ -29,22 +29,20 @@ import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; import net.runelite.client.plugins.microbot.questhelper.rewards.ItemReward; import net.runelite.client.plugins.microbot.questhelper.rewards.QuestPointReward; import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; import net.runelite.client.plugins.microbot.questhelper.steps.DigStep; import net.runelite.client.plugins.microbot.questhelper.steps.NpcStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.not; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; public class XMarksTheSpot extends BasicQuestHelper { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java index c1a357b171..d84dffe7cc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/ItemAndLastUpdated.java @@ -31,6 +31,9 @@ import net.runelite.api.Item; import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.Callable; @Slf4j @@ -52,12 +55,36 @@ public ItemAndLastUpdated(TrackedContainers containerType) this.containerType = containerType; } + /// Updates the full list of items in this container public void update(int updateTick, Item[] items) { this.lastUpdated = updateTick; this.items = items; } + /// Helper function to add a single item into the container. + /// + /// Prefer using the update method if possible. + public void add(int updateTick, int itemID, int itemQuantity) + { + this.lastUpdated = updateTick; + + var newItems = new ArrayList<>(List.of(this.items)); + newItems.add(new Item(itemID, itemQuantity)); + + this.items = newItems.toArray(new Item[0]); + } + + /// Helper function to remove items with a given item ID from the container. + /// + /// Prefer using the update method if possible. + public void removeByItemID(int updateTick, int itemID) + { + this.lastUpdated = updateTick; + + this.items = Arrays.stream(this.items).filter((item) -> item.getId() != itemID).toArray(Item[]::new); + } + /** * Get the Items contained within the Tracked Container. * If this instance of ItemAndLastUpdated has a method in specialMethodToObtainItems to obtain the current state of the Container other than diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java index 7b42362739..625ea5f6a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/NewVersionManager.java @@ -44,7 +44,7 @@ public class NewVersionManager private final String LAST_VERSION_SEEN_CONFIG_KEY = "lastversionchecked"; - private final String UPDATE_CHAT_TEXT = "Quest Helper has been updated to 4.12.1! This improves the default order for Sea Charting, and adds a proximity mode you can toggle at the top of it!"; + private final String UPDATE_CHAT_TEXT = "Quest Helper has been updated to 4.15.1! You can now filter by leagues regions, and the League's Helper is improved."; public void updateChatWithNotificationIfNewVersion() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java index 03a1bac8dc..9ad173886d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestContainerManager.java @@ -56,8 +56,11 @@ public class QuestContainerManager @Getter private final static ItemAndLastUpdated runePouchData = new ItemAndLastUpdated(TrackedContainers.RUNE_POUCH); + @Getter + private final static ItemAndLastUpdated keyRingData = new ItemAndLastUpdated(TrackedContainers.KEY_RING); + @Getter - private final static List orderedListOfContainers = List.of(equippedData, inventoryData, bankData, runePouchData, potionData, groupStorageData); + private final static List orderedListOfContainers = List.of(equippedData, inventoryData, bankData, runePouchData, potionData, groupStorageData, keyRingData); static Set RUNE_POUCHES = Set.of(ItemID.BH_RUNE_POUCH, ItemID.BH_RUNE_POUCH_TROUVER, ItemID.DIVINE_RUNE_POUCH, ItemID.DIVINE_RUNE_POUCH_TROUVER); private static final int NUM_SLOTS = 6; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java index 85864b9f0f..a94bbb3682 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestManager.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.config.LeagueFiltering; import net.runelite.client.plugins.microbot.questhelper.config.SkillFiltering; import net.runelite.client.plugins.microbot.questhelper.panel.QuestHelperPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestDetails; @@ -229,6 +230,7 @@ public void updateQuestList() .filter(config.difficulty()) .filter(QuestDetails::showCompletedQuests) .filter(SkillFiltering::passesSkillFilter) + .filter(LeagueFiltering::passesLeagueFilter) .sorted(config.orderListBy()) .collect(Collectors.toList()); Map completedQuests = QuestHelperQuest.getQuestHelpers(isDeveloperMode()) @@ -476,6 +478,7 @@ private void getAllItemRequirements() .stream() .filter(pred) .filter(QuestDetails::isNotCompleted) + .filter(LeagueFiltering::passesLeagueFilter) .sorted(config.orderListBy()) .collect(Collectors.toList()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java index d05de52e61..4a411b70fb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/managers/QuestMenuHandler.java @@ -33,7 +33,6 @@ import net.runelite.api.*; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; import net.runelite.client.util.Text; import javax.inject.Inject; @@ -131,7 +130,7 @@ private void handleShieldOfArrav() return; } - WorldPoint location = Rs2Player.getWorldLocation(); + WorldPoint location = player.getWorldLocation(); QuestHelperQuest questToStart = PHOENIX_START_ZONE.contains(location) ? QuestHelperQuest.SHIELD_OF_ARRAV_PHOENIX_GANG : QuestHelperQuest.SHIELD_OF_ARRAV_BLACK_ARM_GANG; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java index 6d16420abf..c4d05be991 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperMinimapOverlay.java @@ -26,6 +26,11 @@ public QuestHelperMinimapOverlay(QuestHelperPlugin plugin) @Override public Dimension render(Graphics2D graphics) { + if (plugin.isInCutscene()) + { + return null; + } + QuestHelper quest = plugin.getSelectedQuest(); if (quest != null && quest.getCurrentStep() != null && quest.getCurrentStep().getActiveStep() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java index 9be7416147..c37ee6b597 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperOverlay.java @@ -31,6 +31,7 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPanel; +import net.runelite.client.ui.overlay.OverlayPriority; import javax.inject.Inject; import java.awt.*; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java index 7960babaf2..1f3ee50951 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldArrowOverlay.java @@ -49,6 +49,11 @@ public QuestHelperWorldArrowOverlay(QuestHelperPlugin plugin) @Override public Dimension render(Graphics2D graphics) { + if (plugin.isInCutscene()) + { + return null; + } + QuestHelper quest = plugin.getSelectedQuest(); if (quest != null && quest.getCurrentStep() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java index feac0cba6f..51988c55b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldLineOverlay.java @@ -54,6 +54,11 @@ public Dimension render(Graphics2D graphics) return null; } + if (plugin.isInCutscene()) + { + return null; + } + QuestHelper quest = plugin.getSelectedQuest(); if (quest != null && quest.getCurrentStep() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java index 002db5eb04..911c32400f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/overlays/QuestHelperWorldOverlay.java @@ -63,15 +63,24 @@ public Dimension render(Graphics2D graphics) QuestHelper quest = plugin.getSelectedQuest(); - if (quest != null && quest.getCurrentStep() != null) + if (quest != null) { - quest.makeWorldOverlayHint(graphics, plugin); - quest.getCurrentStep().makeWorldOverlayHint(graphics, plugin); + var currentStep = quest.getCurrentStep(); + if (currentStep != null) + { + if (!plugin.isInCutscene() || currentStep.getActiveStep().isAllowInCutscene()) + { + currentStep.makeWorldOverlayHint(graphics, plugin); + } + } } - plugin.getBackgroundHelpers().forEach((name, questHelper) -> questHelper.getCurrentStep().makeWorldOverlayHint(graphics, plugin)); + if (!plugin.isInCutscene()) + { + plugin.getBackgroundHelpers().forEach((name, questHelper) -> questHelper.getCurrentStep().makeWorldOverlayHint(graphics, plugin)); - plugin.getRuneliteObjectManager().makeWorldOverlayHint(graphics); + plugin.getRuneliteObjectManager().makeWorldOverlayHint(graphics); + } return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java index f79c75fb30..53a0f7f66a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/JGenerator.java @@ -72,7 +72,7 @@ public static JTextArea makeJTextArea() jTextArea.setOpaque(false); jTextArea.setEditable(false); jTextArea.setFocusable(false); - jTextArea.setBackground(UIManager.getColor("Label.background")); + jTextArea.setBackground(javax.swing.UIManager.getColor("Label.background")); jTextArea.setBorder(new EmptyBorder(0, 0, 0, 0)); return jTextArea; @@ -86,7 +86,7 @@ public static JTextArea makeJTextArea(String text) jTextArea.setOpaque(false); jTextArea.setEditable(false); jTextArea.setFocusable(false); - jTextArea.setBackground(UIManager.getColor("Label.background")); + jTextArea.setBackground(javax.swing.UIManager.getColor("Label.background")); jTextArea.setBorder(new EmptyBorder(0, 0, 0, 0)); return jTextArea; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/ManualStepSkipStore.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/ManualStepSkipStore.java new file mode 100644 index 0000000000..528815a9d8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/ManualStepSkipStore.java @@ -0,0 +1,112 @@ +package net.runelite.client.plugins.microbot.questhelper.panel; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.config.ConfigManager; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * Persists per-RuneScape-profile manual step skips under {@link QuestHelperConfig#QUEST_HELPER_GROUP}, + * one JSON map key per displayed helper name (same grouping as sidebar order). + */ +public final class ManualStepSkipStore +{ + private static final Type MAP_TYPE = new TypeToken>() + { + }.getType(); + + private ManualStepSkipStore() + { + } + + public static String configKeyForQuest(String displayedQuestName) + { + return QuestHelperConfig.QUEST_HELPER_MANUAL_SKIPS_KEY_PREFIX + slug(displayedQuestName); + } + + private static String slug(String name) + { + if (name == null) + { + return "helper"; + } + String s = name.trim().replaceAll("[^a-zA-Z0-9_-]+", "_"); + if (s.length() > 96) + { + s = s.substring(0, 96); + } + return s.isEmpty() ? "helper" : s; + } + + public static Map load(ConfigManager cm, Gson gson, String displayedQuestName) + { + if (cm == null || cm.getRSProfileKey() == null) + { + return new HashMap<>(); + } + String ck = configKeyForQuest(displayedQuestName); + String raw = cm.getRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + if ((raw == null || raw.isBlank()) && cm.getRSProfileKey() != null) + { + String legacy = cm.getConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + if (legacy != null && !legacy.isBlank()) + { + cm.setRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck, legacy); + cm.unsetConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + raw = legacy; + } + } + if (raw == null || raw.isBlank()) + { + return new HashMap<>(); + } + try + { + Map m = gson.fromJson(raw, MAP_TYPE); + return m != null ? new HashMap<>(m) : new HashMap<>(); + } + catch (RuntimeException e) + { + return new HashMap<>(); + } + } + + public static void put(ConfigManager cm, Gson gson, String displayedQuestName, String slotKey, boolean skipped) + { + if (cm == null || cm.getRSProfileKey() == null || slotKey == null || slotKey.isBlank()) + { + return; + } + String ck = configKeyForQuest(displayedQuestName); + Map map = load(cm, gson, displayedQuestName); + if (skipped) + { + map.put(slotKey, true); + } + else + { + map.remove(slotKey); + } + if (map.isEmpty()) + { + cm.unsetRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck); + } + else + { + cm.setRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, ck, gson.toJson(map)); + } + } + + public static void clearAll(ConfigManager cm, String displayedQuestName) + { + if (cm == null || cm.getRSProfileKey() == null) + { + return; + } + cm.unsetRSProfileConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, configKeyForQuest(displayedQuestName)); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java index b1bfcc9590..5830295f1b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/PanelDetails.java @@ -37,7 +37,7 @@ public class PanelDetails { @Getter - int id = -1; + int id = Integer.MIN_VALUE; @Getter String header; @@ -139,6 +139,11 @@ public void addSteps(QuestStep... steps) this.steps.addAll(Arrays.asList(steps)); } + public void addSteps(Collection steps) + { + this.steps.addAll(steps); + } + public boolean contains(QuestStep currentStep) { if (getSteps().contains(currentStep)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java index 2c840fa1f7..a8893857ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestHelperPanel.java @@ -27,6 +27,7 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.managers.QuestManager; +import net.runelite.client.plugins.microbot.questhelper.panel.regionfiltering.RegionFilterPanel; import net.runelite.client.plugins.microbot.questhelper.panel.skillfiltering.SkillFilterPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestDetails; @@ -39,6 +40,9 @@ import net.runelite.api.GameState; import net.runelite.api.QuestState; import net.runelite.api.Skill; +import net.runelite.api.WorldType; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.config.ConfigManager; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; @@ -54,12 +58,13 @@ import javax.swing.event.DocumentListener; import javax.swing.plaf.basic.BasicButtonUI; import java.awt.*; +import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; @Slf4j @@ -74,17 +79,37 @@ public class QuestHelperPanel extends PluginPanel private final JPanel searchQuestsPanel; private final JPanel allDropdownSections = new JPanel(); + private final JPanel filterStackPanel = new JPanel(); private final JComboBox filterDropdown, difficultyDropdown, orderDropdown; private final JComboBox stateDropdown = new JComboBox<>(); private JPanel statePanel; private final JButton skillExpandButton = new JButton(); + private JPanel regionsFilterSection; + private RegionFilterPanel regionFilterPanel; private final IconTextField searchBar = new IconTextField(); private final FixedWidthPanel questListPanel = new FixedWidthPanel(); private final FixedWidthPanel questListWrapper = new FixedWidthPanel(); private final JScrollPane scrollableContainer; + private final CardLayout viewportLayout = new CardLayout(); + private final JPanel viewportContent = new JPanel(viewportLayout) + { + @Override + public Dimension getPreferredSize() + { + for (Component component : getComponents()) + { + if (component.isVisible()) + { + return component.getPreferredSize(); + } + } + return super.getPreferredSize(); + } + }; public static final int DROPDOWN_HEIGHT = 26; public boolean questActive = false; + private String activeView = VIEW_QUEST_LIST; private final ArrayList questSelectPanels = new ArrayList<>(); @@ -98,6 +123,9 @@ public class QuestHelperPanel extends PluginPanel private static final ImageIcon SETTINGS_ICON; private static final ImageIcon COLLAPSED_ICON; private static final ImageIcon EXPANDED_ICON; + private static final String VIEW_QUEST_LIST = "quest_list"; + private static final String VIEW_QUEST_OVERVIEW = "quest_overview"; + private static final String VIEW_SETTINGS = "settings"; private int nextDesiredScrollValue = 0; @@ -160,14 +188,14 @@ public QuestHelperPanel(QuestHelperPlugin questHelperPlugin, QuestManager questM onSearchBarChanged(); }); - settingsBtn.addMouseListener(new MouseAdapter() + settingsBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { settingsBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { if (settingsPanelActive()) { @@ -189,14 +217,14 @@ public void mouseExited(MouseEvent evt) discordBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); discordBtn.setUI(new BasicButtonUI()); discordBtn.addActionListener((ev) -> LinkBrowser.browse("https://discord.gg/XCfwNnz6RB")); - discordBtn.addMouseListener(new MouseAdapter() + discordBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { discordBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { discordBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); } @@ -211,14 +239,14 @@ public void mouseExited(MouseEvent evt) githubBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); githubBtn.setUI(new BasicButtonUI()); githubBtn.addActionListener((ev) -> LinkBrowser.browse("https://github.com/Zoinkwiz/quest-helper")); - githubBtn.addMouseListener(new MouseAdapter() + githubBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { githubBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { githubBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); } @@ -233,14 +261,14 @@ public void mouseExited(MouseEvent evt) patreonBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); patreonBtn.setUI(new BasicButtonUI()); patreonBtn.addActionListener((ev) -> LinkBrowser.browse("https://www.patreon.com/zoinkwiz")); - patreonBtn.addMouseListener(new MouseAdapter() + patreonBtn.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseEntered(MouseEvent evt) + public void mouseEntered(java.awt.event.MouseEvent evt) { patreonBtn.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR); } - public void mouseExited(MouseEvent evt) + public void mouseExited(java.awt.event.MouseEvent evt) { patreonBtn.setBackground(ColorScheme.DARK_GRAY_COLOR); } @@ -318,21 +346,21 @@ public void changedUpdate(DocumentEvent e) skillExpandButton.setHorizontalTextPosition(SwingConstants.LEFT); skillExpandButton.setIconTextGap(10); skillExpandButton.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent mouseEvent) { - skillFilterPanel.setVisible(!skillFilterPanel.isVisible()); - if (skillFilterPanel.isVisible()) - { - skillExpandButton.setIcon(EXPANDED_ICON); - } - else + @Override + public void mousePressed(MouseEvent mouseEvent) { - skillExpandButton.setIcon(COLLAPSED_ICON); + skillFilterPanel.setVisible(!skillFilterPanel.isVisible()); + if (skillFilterPanel.isVisible()) + { + skillExpandButton.setIcon(EXPANDED_ICON); + } + else + { + skillExpandButton.setIcon(COLLAPSED_ICON); + } } - } - }); + }); JPanel skillExpandBar = new JPanel(); skillExpandBar.setLayout(new BorderLayout()); @@ -362,6 +390,53 @@ public void mousePressed(MouseEvent mouseEvent) } }); + // Region filtering + JButton regionExpandButton = new JButton(); + regionExpandButton.setForeground(Color.GRAY); + regionExpandButton.setIcon(COLLAPSED_ICON); + regionExpandButton.setHorizontalTextPosition(SwingConstants.LEFT); + regionExpandButton.setIconTextGap(10); + + regionFilterPanel = new RegionFilterPanel(questHelperPlugin.spriteManager, () -> { + questHelperPlugin.getClientThread().invokeLater(questManager::updateQuestList); + int count = regionFilterPanel.getSelectedCount(); + regionExpandButton.setText(count > 0 ? String.format("%d active", count) : ""); + }); + regionFilterPanel.setVisible(false); + + JLabel regionFilterName = JGenerator.makeJLabel("Region filtering"); + regionFilterName.setForeground(Color.WHITE); + questHelperPlugin.spriteManager.getSpriteAsync(2214, 0, sprite -> { + if (sprite != null) + { + SwingUtilities.invokeLater(() -> regionFilterName.setIcon(new ImageIcon(sprite))); + } + }); + + JPanel regionExpandBar = new JPanel(); + regionExpandBar.setLayout(new BorderLayout()); + regionExpandBar.setToolTipText("Choose league regions to filter quests by"); + regionExpandBar.add(regionFilterName, BorderLayout.CENTER); + regionExpandBar.add(regionExpandButton, BorderLayout.EAST); + + MouseAdapter regionExpandListener = new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + regionFilterPanel.setVisible(!regionFilterPanel.isVisible()); + regionExpandButton.setIcon(regionFilterPanel.isVisible() ? EXPANDED_ICON : COLLAPSED_ICON); + } + }; + regionExpandButton.addMouseListener(regionExpandListener); + regionExpandBar.addMouseListener(regionExpandListener); + + regionsFilterSection = new JPanel(); + regionsFilterSection.setLayout(new BorderLayout()); + regionsFilterSection.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + regionsFilterSection.add(regionExpandBar, BorderLayout.CENTER); + regionsFilterSection.add(regionFilterPanel, BorderLayout.SOUTH); + // Filter dropdown + search allDropdownSections.setLayout(new BoxLayout(allDropdownSections, BoxLayout.Y_AXIS)); allDropdownSections.setBorder(new EmptyBorder(0, 0, 10, 0)); @@ -369,14 +444,23 @@ public void mousePressed(MouseEvent mouseEvent) allDropdownSections.add(difficultyPanel); allDropdownSections.add(orderPanel); allDropdownSections.add(skillsFilterPanel); + allDropdownSections.add(regionsFilterSection); - searchQuestsPanel.add(allDropdownSections, BorderLayout.NORTH); + // Set initial visibility based on config and current world type + updateRegionFilterVisibility(questHelperPlugin.getClient().getWorldType().contains(WorldType.SEASONAL)); + + filterStackPanel.setLayout(new BoxLayout(filterStackPanel, BoxLayout.Y_AXIS)); + filterStackPanel.setOpaque(false); + filterStackPanel.add(Box.createVerticalStrut(8)); + filterStackPanel.add(allDropdownSections); + + searchQuestsPanel.add(filterStackPanel, BorderLayout.NORTH); // Wrapper questListWrapper.setLayout(new BorderLayout()); questListWrapper.add(questListPanel, BorderLayout.NORTH); - scrollableContainer = new JScrollPane(questListWrapper); + scrollableContainer = new JScrollPane(viewportContent); scrollableContainer.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); @@ -394,6 +478,9 @@ public void mousePressed(MouseEvent mouseEvent) questOverviewWrapper.setLayout(new BorderLayout()); questOverviewWrapper.add(questOverviewPanel, BorderLayout.NORTH); + viewportContent.add(questListWrapper, VIEW_QUEST_LIST); + viewportContent.add(questOverviewWrapper, VIEW_QUEST_OVERVIEW); + viewportContent.add(assistLevelPanel, VIEW_SETTINGS); if (questHelperPlugin.isDeveloperMode()) { @@ -404,8 +491,56 @@ public void mousePressed(MouseEvent mouseEvent) var devModePanel = new JPanel(); devModePanel.setLayout(new BorderLayout()); + var togglePuzzleHelper = new JMenuItem(new AbstractAction("toggle puzzle helper") + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + var v = questHelperPlugin.getConfig().solvePuzzles(); + configManager.setConfiguration(QuestHelperConfig.QUEST_HELPER_GROUP, "solvePuzzles", !v); + } + }); + + var toggleCutsceneStatus = new JMenuItem(new AbstractAction("toggle cutscene status") + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + questHelperPlugin.getClientThread().invoke(() -> { + // from RuneLite core's devtools ::setvarb + var varbit = VarbitID.CUTSCENE_STATUS; + var client = questHelperPlugin.getClient(); + + var currentStatus = client.getVarbitValue(VarbitID.CUTSCENE_STATUS); + var varbitComposition = client.getVarbit(varbit); + var value = currentStatus == 0 ? 1 : 0; + + client.setVarbitValue(client.getVarps(), varbit, value); + client.queueChangedVarp(varbitComposition.getIndex()); + var varbitChanged = new VarbitChanged(); + varbitChanged.setVarbitId(varbit); + varbitChanged.setValue(value); + questHelperPlugin.getEventBus().post(varbitChanged); // fake event + }); + } + }); + + var menu = new JPopupMenu("Menu"); + menu.add(togglePuzzleHelper); + menu.add(toggleCutsceneStatus); var reloadQuest = new JButton("reload quest"); + reloadQuest.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + if (SwingUtilities.isRightMouseButton(e) && e.getClickCount() == 1) + { + menu.show(reloadQuest, e.getX(), e.getY()); + } + } + }); reloadQuest.addActionListener((ev) -> { nextDesiredScrollValue = scrollableContainer.getVerticalScrollBar().getValue(); var currentQuest = questHelperPlugin.getSelectedQuest(); @@ -417,6 +552,10 @@ public void mousePressed(MouseEvent mouseEvent) }); devModePanel.add(reloadQuest, BorderLayout.SOUTH); + JPanel previewNavPanel = new JPanel(new GridLayout(2, 1, 0, 4)); + previewNavPanel.setBackground(ColorScheme.DARK_GRAY_COLOR); + devModePanel.add(previewNavPanel, BorderLayout.CENTER); + // State dropdown for BasicQuestHelper stateDropdown.setFocusable(false); stateDropdown.addItemListener((ev) -> { @@ -443,7 +582,7 @@ else if (selectedItem != null) } } }); - + // Create a panel with label for the state dropdown statePanel = makeDropdownPanel(stateDropdown, "Quest State"); statePanel.setPreferredSize(new Dimension(PANEL_WIDTH, DROPDOWN_HEIGHT)); @@ -468,12 +607,11 @@ private void onSearchBarChanged() if ((questOverviewPanel.currentQuest == null || !text.isEmpty())) { activateQuestList(); - questSelectPanels.forEach(questListPanel::remove); showMatchingQuests(text); } else { - scrollableContainer.setViewportView(questOverviewWrapper); + showView(VIEW_QUEST_OVERVIEW); } revalidate(); } @@ -515,21 +653,25 @@ private JPanel makeDropdownPanel(JComboBox dropdown, String name) private void showMatchingQuests(String text) { - if (text.isEmpty()) + questSelectPanels.forEach(questListPanel::remove); + + if (text == null || text.isEmpty()) { questSelectPanels.forEach(questListPanel::add); - return; } - - final String[] searchTerms = text.toLowerCase().split(" "); - - questSelectPanels.forEach(listItem -> + else { - if (Text.matchesSearchTerms(Arrays.asList(searchTerms), listItem.getKeywords())) + final String[] searchTerms = text.toLowerCase().split(" "); + questSelectPanels.forEach(listItem -> { - questListPanel.add(listItem); - } - }); + if (Text.matchesSearchTerms(Arrays.asList(searchTerms), listItem.getKeywords())) + { + questListPanel.add(listItem); + } + }); + } + revalidate(); + repaint(); } public void refresh(List questHelpers, boolean loggedOut, @@ -590,10 +732,11 @@ public void refresh(List questHelpers, boolean loggedOut, showMatchingQuests(searchBar.getText() != null ? searchBar.getText() : ""); } + public void addQuest(QuestHelper quest, boolean isActive) { allDropdownSections.setVisible(false); - scrollableContainer.setViewportView(questOverviewWrapper); + showView(VIEW_QUEST_OVERVIEW); questOverviewPanel.addQuest(quest, isActive); updateStateDropdown(quest); @@ -631,7 +774,9 @@ public void removeQuest() questActive = false; questOverviewPanel.removeQuest(); activateQuestList(); + showMatchingQuests(searchBar.getText() != null ? searchBar.getText() : ""); updateStateDropdown(null); + scrollableContainer.getVerticalScrollBar().setValue(0); repaint(); revalidate(); @@ -639,12 +784,12 @@ public void removeQuest() private boolean settingsPanelActive() { - return scrollableContainer.getViewport().getView() == assistLevelPanel; + return VIEW_SETTINGS.equals(activeView); } private void activateSettings() { - scrollableContainer.setViewportView(assistLevelPanel); + showView(VIEW_SETTINGS); searchQuestsPanel.setVisible(false); repaint(); @@ -655,7 +800,7 @@ private void deactivateSettings() { if (questActive && searchBar.getText().isEmpty()) { - scrollableContainer.setViewportView(questOverviewWrapper); + showView(VIEW_QUEST_OVERVIEW); } else { @@ -669,7 +814,7 @@ private void deactivateSettings() private void activateQuestList() { - scrollableContainer.setViewportView(questListWrapper); + showView(VIEW_QUEST_LIST); searchQuestsPanel.setVisible(true); allDropdownSections.setVisible(true); @@ -677,6 +822,17 @@ private void activateQuestList() revalidate(); } + private void showView(String viewName) + { + if (viewName.equals(activeView)) + { + return; + } + + viewportLayout.show(viewportContent, viewName); + activeView = viewName; + } + private void updateStateDropdown(QuestHelper questHelper) { if (!questHelperPlugin.isDeveloperMode()) return; @@ -746,7 +902,7 @@ public void setSelectedQuest(QuestHelper questHelper) else { assistLevelPanel.rebuild(questHelper, configManager, this); - scrollableContainer.setViewportView(assistLevelPanel); + showView(VIEW_SETTINGS); searchQuestsPanel.setVisible(false); } } @@ -785,4 +941,31 @@ public void refreshSkillFiltering() skillExpandButton.setText(String.format("%d active", numFilteredSkills)); } } + + /** + * Updates visibility of the region filter section based on config and world type. + */ + public void updateRegionFilterVisibility(boolean isLeagueWorld) + { + QuestHelperConfig.RegionFilterVisibility visibility = questHelperPlugin.getConfig().regionFilterVisibility(); + boolean shouldShow; + switch (visibility) + { + case SHOW: + shouldShow = true; + break; + case HIDE: + shouldShow = false; + break; + case AUTO: + default: + shouldShow = isLeagueWorld; + break; + } + regionsFilterSection.setVisible(shouldShow); + if (!shouldShow) + { + regionFilterPanel.clearSelection(); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java index d2d63233d3..ba751a8ea0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestOverviewPanel.java @@ -56,8 +56,8 @@ import java.awt.event.ItemEvent; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.*; import java.util.List; +import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; @@ -81,7 +81,10 @@ public class QuestOverviewPanel extends JPanel private final QuestRewardsPanel questRewardsPanel; private final JPanel questExternalResourcesList; - private final JPanel questStepsContainer = new JPanel(); + private JPanel questStepsContainer; + private final CardLayout questStepsLayout = new CardLayout(); + private final JPanel questStepsHost = new JPanel(questStepsLayout); + private final JPanel activeStepsCard = new JPanel(new BorderLayout()); private final JPanel actionsContainer = new JPanel(); private final JPanel configContainer = new JPanel(); @@ -90,6 +93,8 @@ public class QuestOverviewPanel extends JPanel private final JLabel questNameLabel = JGenerator.makeJLabel(); private static final ImageIcon CLOSE_ICON = Icon.CLOSE.getIcon(); + private static final String ACTIVE_STEPS_CARD = "active"; + private static final String EMPTY_STEPS_CARD = "empty"; private final List allQuestStepPanelList = new CopyOnWriteArrayList<>(); public QuestOverviewPanel(QuestHelperPlugin questHelperPlugin, QuestManager questManager) @@ -109,7 +114,7 @@ public QuestOverviewPanel(QuestHelperPlugin questHelperPlugin, QuestManager ques actionsContainer.setBorder(new EmptyBorder(5, 5, 5, 10)); actionsContainer.setVisible(false); - final JPanel viewControls = new JPanel(new GridLayout(1, 3, 10, 0)); + final JPanel viewControls = new JPanel(new GridLayout(1, 1, 6, 0)); viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR); JButton closeBtn = new JButton(); @@ -197,11 +202,15 @@ public QuestOverviewPanel(QuestHelperPlugin questHelperPlugin, QuestManager ques introPanel.add(overviewPanel, BorderLayout.NORTH); /* Container for quest steps */ - questStepsContainer.setLayout(new BoxLayout(questStepsContainer, BoxLayout.Y_AXIS)); + questStepsContainer = createQuestStepsContainer(); + activeStepsCard.add(questStepsContainer, BorderLayout.CENTER); + questStepsHost.add(new JPanel(), EMPTY_STEPS_CARD); + questStepsHost.add(activeStepsCard, ACTIVE_STEPS_CARD); + questStepsLayout.show(questStepsHost, EMPTY_STEPS_CARD); add(actionsContainer); add(configContainer); add(introPanel); - add(questStepsContainer); + add(questStepsHost); } private JComboBox makeNewDropdown(Enum[] values, String key) @@ -251,6 +260,10 @@ public void addQuest(QuestHelper quest, boolean isActive) { currentQuest = quest; allQuestStepPanelList.clear(); + questStepsContainer = createQuestStepsContainer(); + activeStepsCard.removeAll(); + activeStepsCard.add(questStepsContainer, BorderLayout.CENTER); + questStepsLayout.show(questStepsHost, ACTIVE_STEPS_CARD); List steps = quest.getPanels(); QuestStep currentStep; @@ -324,7 +337,8 @@ public void removeQuest() introPanel.setVisible(false); configContainer.setVisible(false); configContainer.removeAll(); - questStepsContainer.removeAll(); + questStepsLayout.show(questStepsHost, EMPTY_STEPS_CARD); + allQuestStepPanelList.clear(); questGeneralRequirementsPanel.setRequirements(null); questGeneralRecommendedPanel.setRequirements(null); questItemRequirementsPanel.setRequirements(null); @@ -337,6 +351,13 @@ public void removeQuest() revalidate(); } + private JPanel createQuestStepsContainer() + { + JPanel container = new JPanel(); + container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); + return container; + } + /// The quest helper's X is clicked private void closeHelper() { @@ -415,6 +436,10 @@ public void setupQuestRequirements(QuestHelper quest) private static void collectRequirements(QuestHelper quest, List allRequirements, Set processedQuestIds) { + if (quest.getQuest() == null) + { + return; + } if (quest.getQuest().getQuestHelper().getGeneralRequirements() == null) return; List generalRequirements = quest.getQuest().getQuestHelper().getGeneralRequirements(); @@ -524,6 +549,11 @@ private void updateCombatRequirementsPanels(List combatRequirementList) private void updateExternalResourcesPanel(QuestHelper quest) { List externalResourcesList; + if (quest.getQuest() == null) + { + questExternalResourcesList.removeAll(); + return; + } try { externalResourcesList = Collections.singletonList(ExternalQuestResources.valueOf(quest.getQuest().name().toUpperCase()).getWikiURL()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java index 27e547a170..1782997e9d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRequirementsPanel.java @@ -50,8 +50,11 @@ import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class QuestRequirementsPanel extends JPanel { @@ -92,7 +95,7 @@ public static JPanel createHeader(@NonNull String header) var headerPanel = new JPanel(); headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); headerPanel.setLayout(new BorderLayout()); - headerPanel.setBorder(new EmptyBorder(5, 5, 5, 10)); + headerPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); var headerLabel = JGenerator.makeJTextArea(header); headerLabel.setForeground(Color.WHITE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java index 42f5beab26..dbef8c712a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestRewardsPanel.java @@ -58,7 +58,7 @@ public QuestRewardsPanel() rewardsText.setOpaque(false); rewardsText.setEditable(false); rewardsText.setFocusable(false); - rewardsText.setBackground(UIManager.getColor("Label.background")); + rewardsText.setBackground(javax.swing.UIManager.getColor("Label.background")); rewardsText.setFont(Fonts.getOriginalFont()); rewardsText.setBorder(new EmptyBorder(0, 0, 0, 0)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestStepPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestStepPanel.java deleted file mode 100644 index 290e67db96..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/QuestStepPanel.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2020, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.panel; - -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; -import net.runelite.client.plugins.microbot.questhelper.managers.QuestManager; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.client.ui.ColorScheme; -import net.runelite.client.ui.FontManager; -import net.runelite.client.util.SwingUtil; - -import javax.annotation.Nullable; -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - -public class QuestStepPanel extends JPanel implements MouseListener -{ - private static final int TITLE_PADDING = 5; - - @Getter - private final PanelDetails panelDetails; - private final QuestHelperPlugin questHelperPlugin; - - private final JPanel headerPanel = new JPanel(); - private final JTextPane headerLabel = JGenerator.makeJTextPane(); - private final JPanel bodyPanel = new JPanel(); - private final JCheckBox lockStep = new JCheckBox(); - @Getter - private final JPanel leftTitleContainer; - private final JPanel viewControls; - private final HashMap steps = new HashMap<>(); - private final @Nullable QuestRequirementsPanel requiredItemsPanel; - private final @Nullable QuestRequirementsPanel recommendedItemsPanel; - private boolean stepAutoLocked; - private final QuestHelper questHelper; - private QuestStep lastHighlightedStep = null; - - public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestManager questManager, QuestHelperPlugin questHelperPlugin) - { - this.panelDetails = panelDetails; - this.questHelperPlugin = questHelperPlugin; - this.questHelper = questManager.getSelectedQuest(); - - setLayout(new BorderLayout(0, 1)); - setBorder(new EmptyBorder(5, 0, 0, 0)); - - leftTitleContainer = new JPanel(new BorderLayout(5, 0)); - - headerLabel.addMouseListener(this); - addMouseListener(this); - - headerLabel.setText(panelDetails.getHeader()); - headerLabel.setFont(FontManager.getRunescapeBoldFont()); - - headerLabel.setMinimumSize(new Dimension(1, headerLabel.getPreferredSize().height)); - - headerPanel.setLayout(new BoxLayout(headerPanel, BoxLayout.X_AXIS)); - headerPanel.setBorder(new EmptyBorder(7, 7, 3, 7)); - - headerPanel.add(Box.createRigidArea(new Dimension(TITLE_PADDING, 0))); - leftTitleContainer.add(headerLabel, BorderLayout.CENTER); - headerPanel.add(leftTitleContainer, BorderLayout.WEST); - - viewControls = new JPanel(new GridLayout(1, 3, 10, 0)); - - SwingUtil.addModalTooltip(lockStep, "Mark section as incomplete", "Mark section as complete"); - lockStep.setBackground(ColorScheme.DARKER_GRAY_COLOR); - lockStep.addActionListener(ev -> lockSection(lockStep.isSelected())); - lockStep.setVisible(false); - headerPanel.add(lockStep, BorderLayout.EAST); - - viewControls.add(lockStep); - - headerPanel.add(viewControls, BorderLayout.EAST); - - if (panelDetails.contains(currentStep)) - { - headerLabel.setForeground(Color.BLACK); - headerPanel.setBackground(ColorScheme.BRAND_ORANGE); - viewControls.setBackground(ColorScheme.BRAND_ORANGE); - leftTitleContainer.setBackground(ColorScheme.BRAND_ORANGE); - } - else - { - headerLabel.setForeground(Color.WHITE); - headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - leftTitleContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - } - - /* Body */ - bodyPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - bodyPanel.setLayout(new BorderLayout()); - bodyPanel.setBorder(new EmptyBorder(10, 5, 10, 5)); - - if (panelDetails.getRequirements() != null) - { - requiredItemsPanel = new QuestRequirementsPanel("Bring the following items:", panelDetails.getRequirements(), questManager, false); - bodyPanel.add(requiredItemsPanel, BorderLayout.NORTH); - } - else - { - requiredItemsPanel = null; - } - - if (panelDetails.getRecommended() != null) - { - recommendedItemsPanel = new QuestRequirementsPanel("Optionally bring the following items:", panelDetails.getRecommended(), questManager, - false); - bodyPanel.add(recommendedItemsPanel, BorderLayout.CENTER); - } - else - { - recommendedItemsPanel = null; - } - - JPanel questStepsPanel = new JPanel(); - questStepsPanel.setLayout(new BoxLayout(questStepsPanel, BoxLayout.Y_AXIS)); - questStepsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - - for (QuestStep step : panelDetails.getSteps()) - { - JTextPane questStepLabel = JGenerator.makeJTextPane(); - questStepLabel.setLayout(new BorderLayout()); - questStepLabel.setAlignmentX(SwingConstants.LEFT); - questStepLabel.setAlignmentY(SwingConstants.TOP); - questStepLabel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - questStepLabel.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createMatteBorder(1, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR.brighter()), - BorderFactory.createEmptyBorder(5, 5, 10, 0) - )); - questStepLabel.setText(generateText(step)); - questStepLabel.setOpaque(true); - questStepLabel.setVisible(step.isShowInSidebar()); - - steps.put(step, questStepLabel); - questStepsPanel.add(questStepLabel); - - } - - bodyPanel.add(questStepsPanel, BorderLayout.SOUTH); - - add(headerPanel, BorderLayout.NORTH); - add(bodyPanel, BorderLayout.CENTER); - - if (!panelDetails.getSteps().contains(currentStep)) - { - collapse(); - } - } - - public String generateText(QuestStep step) - { - StringBuilder text = new StringBuilder(); - - if (step.getText() != null) - { - var first = true; - for (var line : step.getText()) - { - if (!first) - { - text.append("\n\n"); - } - text.append(line); - first = false; - } - } - - return text.toString(); - } - - public List getSteps() - { - return new ArrayList<>(steps.keySet()); - } - - public HashMap getStepsLabels() - { - return steps; - } - - public void setLockable(boolean canLock) - { - lockStep.setVisible(canLock); - } - - public void updateHighlightCheck(Client client, QuestStep newStep, QuestHelper currentQuest) - { - if (panelDetails.getHideCondition() == null || !panelDetails.getHideCondition().check(client)) - { - setVisible(true); - boolean highlighted = false; - setLockable(panelDetails.getLockingQuestSteps() != null && - (panelDetails.getVars() == null || panelDetails.getVars().contains(currentQuest.getVar()))); - - for (QuestStep sidebarStep : getSteps()) - { - if (sidebarStep.getConditionToHide() != null && sidebarStep.getConditionToHide().check(client)) continue; - if (sidebarStep.containsSteps(newStep, new HashSet<>())) - { - highlighted = true; - updateHighlight(sidebarStep); - break; - } - } - - if (!highlighted) - { - removeHighlight(); - } - } - else - { - setVisible(false); - } - } - - - public void updateHighlight(QuestStep currentStep) - { - expand(); - - if (steps.get(lastHighlightedStep) != null) - { - steps.get(lastHighlightedStep).setForeground(Color.LIGHT_GRAY); - } - else - { - headerLabel.setForeground(Color.BLACK); - headerPanel.setBackground(ColorScheme.BRAND_ORANGE); - viewControls.setBackground(ColorScheme.BRAND_ORANGE); - leftTitleContainer.setBackground(ColorScheme.BRAND_ORANGE); - } - - if (steps.get(currentStep) != null) - { - steps.get(currentStep).setForeground(ColorScheme.BRAND_ORANGE); - } - - lastHighlightedStep = currentStep; - } - - public void removeHighlight() - { - headerLabel.setForeground(Color.WHITE); - if (isCollapsed()) - { - applyDimmer(false, headerPanel); - } - headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - leftTitleContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - if (steps.get(currentlyActiveQuestSidebarStep()) != null) - { - steps.get(currentlyActiveQuestSidebarStep()).setForeground(Color.LIGHT_GRAY); - } - - collapse(); - } - - public void updateLock() - { - if (panelDetails.getLockingQuestSteps() == null) - { - return; - } - - if (panelDetails.getLockingQuestSteps().isUnlockable()) - { - stepAutoLocked = false; - lockStep.setEnabled(true); - } - else - { - if (!stepAutoLocked) - { - collapse(); - } - stepAutoLocked = true; - lockStep.setEnabled(false); - } - - if (panelDetails.getLockingQuestSteps().isLocked()) - { - lockStep.setSelected(true); - } - } - - private void lockSection(boolean locked) - { - if (locked) - { - panelDetails.getLockingQuestSteps().setLockedManually(true); - if (!isCollapsed()) - { - collapse(); - } - } - else - { - panelDetails.getLockingQuestSteps().setLockedManually(false); - if (isCollapsed()) - { - expand(); - } - } - } - - private void collapse() - { - if (!isCollapsed()) - { - bodyPanel.setVisible(false); - applyDimmer(false, headerPanel); - } - } - - private void expand() - { - if (isCollapsed()) - { - bodyPanel.setVisible(true); - applyDimmer(true, headerPanel); - } - } - - boolean isCollapsed() - { - return !bodyPanel.isVisible(); - } - - private void applyDimmer(boolean brighten, JPanel panel) - { - for (Component component : panel.getComponents()) - { - Color color = component.getForeground(); - component.setForeground(brighten ? color.brighter() : color.darker()); - } - } - - public void updateRequirements(Client client) - { - if (requiredItemsPanel != null) - { - requiredItemsPanel.update(client, questHelperPlugin); - } - - if (recommendedItemsPanel != null) - { - recommendedItemsPanel.update(client, questHelperPlugin); - } - - updateStepVisibility(client); - } - - public void updateStepVisibility(Client client) - { - boolean stepVisibilityChanged = false; - for (QuestStep step : steps.keySet()) - { - boolean oldVisibility = step.isShowInSidebar(); - boolean newVisibility = step.getConditionToHide() == null || !step.getConditionToHide().check(client); - stepVisibilityChanged = stepVisibilityChanged || (oldVisibility != newVisibility); - - step.setShowInSidebar(newVisibility); - steps.get(step).setVisible(newVisibility); - } - - if (stepVisibilityChanged) - { - updateHighlightCheck(client, currentlyActiveQuestSidebarStep(), questHelper); - } - } - - private QuestStep currentlyActiveQuestSidebarStep() - { - return questHelperPlugin.getSelectedQuest().getCurrentStep().getActiveStep(); - } - - @Override - public void mouseClicked(MouseEvent e) - { - if (e.getButton() == MouseEvent.BUTTON1) - { - if (isCollapsed()) - { - expand(); - } - else - { - collapse(); - } - } - } - - @Override - public void mousePressed(MouseEvent mouseEvent) - { - } - - @Override - public void mouseReleased(MouseEvent mouseEvent) - { - } - - @Override - public void mouseEntered(MouseEvent mouseEvent) - { - } - - @Override - public void mouseExited(MouseEvent mouseEvent) - { - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java index 6945285280..1522e462e1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/TopLevelPanelDetails.java @@ -26,7 +26,6 @@ import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import lombok.Getter; - import java.util.ArrayList; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java index b24beed088..dfd06d9c33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/IronmanOptimalQuestGuide.java @@ -27,9 +27,8 @@ import com.google.common.collect.ImmutableList; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import lombok.Getter; - import java.util.List; +import lombok.Getter; /** * The order of these quests are parsed using data from the OSRS Wiki @@ -261,6 +260,8 @@ public class IronmanOptimalQuestGuide QuestHelperQuest.THE_CORSAIR_CURSE, QuestHelperQuest.IN_SEARCH_OF_KNOWLEDGE, QuestHelperQuest.HOPESPEARS_WILL, + QuestHelperQuest.THE_IDES_OF_MILK, + QuestHelperQuest.THE_RED_REEF, // Quests & mini quests that are not part of the OSRS Wiki's Optimal Ironman Quest Guide QuestHelperQuest.VALE_TOTEMS, QuestHelperQuest.BALLOON_TRANSPORT_GRAND_TREE, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java index 1e2a0ce647..84d9ed1ece 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/OptimalQuestGuide.java @@ -27,9 +27,8 @@ import com.google.common.collect.ImmutableList; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import lombok.Getter; - import java.util.List; +import lombok.Getter; /** * The order of these quests are parsed using data from the OSRS Wiki @@ -266,6 +265,8 @@ public class OptimalQuestGuide QuestHelperQuest.SONG_OF_THE_ELVES, QuestHelperQuest.CLOCK_TOWER, QuestHelperQuest.THE_CORSAIR_CURSE, + QuestHelperQuest.THE_IDES_OF_MILK, + QuestHelperQuest.THE_RED_REEF, // Quests & mini quests that are not part of the OSRS Wiki's Optimal Quest Guide QuestHelperQuest.VALE_TOTEMS, QuestHelperQuest.BARBARIAN_TRAINING, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java index 45dac69e04..221ef4d55f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/questorders/ReleaseDate.java @@ -27,9 +27,8 @@ import com.google.common.collect.ImmutableList; import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import lombok.Getter; - import java.util.List; +import lombok.Getter; /** * The order of these quests are parsed using data from the OSRS Wiki @@ -226,6 +225,8 @@ public class ReleaseDate QuestHelperQuest.PRYING_TIMES, QuestHelperQuest.CURRENT_AFFAIRS, QuestHelperQuest.TROUBLED_TORTUGANS, + QuestHelperQuest.THE_IDES_OF_MILK, + QuestHelperQuest.THE_RED_REEF, // Miniquests QuestHelperQuest.ALFRED_GRIMHANDS_BARCRAWL, QuestHelperQuest.THE_MAGE_ARENA, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java index 85251329c0..c623ec6c75 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/AbstractQuestSection.java @@ -29,8 +29,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Client; - import javax.swing.*; +import java.util.HashMap; import java.util.List; public abstract class AbstractQuestSection extends JPanel diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java index af26014f44..c86c481c79 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestSectionSection.java @@ -36,7 +36,6 @@ import net.runelite.client.ui.FontManager; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.SwingUtil; - import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; @@ -44,15 +43,20 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class QuestSectionSection extends AbstractQuestSection implements MouseListener { // Idea is to contain multiple sections or queststeppanel private static final int TITLE_PADDING = 5; - private static final ImageIcon DRAG_ICON = new ImageIcon(ImageUtil.loadImageResource(QuestHelperPlugin.class, "/hamburger.png")); + private static final ImageIcon DRAG_ICON = new ImageIcon(ImageUtil.loadImageResource(QuestHelperPlugin.class, "hamburger.png")); private final QuestOverviewPanel questOverviewPanel; private final QuestHelperPlugin questHelperPlugin; @@ -125,7 +129,7 @@ public QuestSectionSection(QuestOverviewPanel questOverviewPanel, TopLevelPanelD stepsPanel.setBorder(new EmptyBorder(10, 5, 10, 5)); // Dragging functionality - this.draggable = panelDetails.getPanelDetails().stream().anyMatch((pDetails -> pDetails.getId() != -1)); + this.draggable = panelDetails.getPanelDetails().stream().anyMatch((pDetails -> pDetails.getId() != Integer.MIN_VALUE)); List order = questHelperPlugin.loadSidebarOrder(questManager.getSelectedQuest()); List panelDetailsList = panelDetails.getPanelDetails(); @@ -476,7 +480,7 @@ private void swapPanels(AbstractQuestSection a, AbstractQuestSection b) public List getIds() { List allIds = new ArrayList<>(); - if (panelDetails.getId() != -1) allIds.add(panelDetails.getId()); + if (panelDetails.getId() != Integer.MIN_VALUE) allIds.add(panelDetails.getId()); allIds.addAll(subPanels.stream() .map(AbstractQuestSection::getIds) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java index 5665aca9ee..dcbefe6f8c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/queststepsection/QuestStepPanel.java @@ -27,9 +27,12 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.managers.QuestManager; import net.runelite.client.plugins.microbot.questhelper.panel.JGenerator; +import net.runelite.client.plugins.microbot.questhelper.panel.ManualStepSkipStore; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.panel.QuestRequirementsPanel; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.ManualRequirement; +import net.runelite.client.plugins.microbot.questhelper.steps.BoardShipStep; import net.runelite.client.plugins.microbot.questhelper.steps.PortTaskStep; import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; import net.runelite.api.Client; @@ -41,19 +44,26 @@ import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; +import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; public class QuestStepPanel extends AbstractQuestSection implements MouseListener { private static final int TITLE_PADDING = 5; private final QuestHelperPlugin questHelperPlugin; - private final HashMap steps = new HashMap<>(); + private final Map stepTextPanes = new HashMap<>(); + private final Map stepRowPanels = new HashMap<>(); + private final Map manualSkipBoxes = new HashMap<>(); + private final Map persistedManualSkips; + private final List orderedSidebarSteps = new ArrayList<>(); + private boolean suppressManualSkipEvents; private final @Nullable QuestRequirementsPanel requiredItemsPanel; private final @Nullable QuestRequirementsPanel recommendedItemsPanel; private boolean stepAutoLocked; @@ -65,6 +75,18 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan this.panelDetails = panelDetails; this.questHelperPlugin = questHelperPlugin; this.questHelper = questManager.getSelectedQuest(); + if (this.questHelper != null) + { + this.persistedManualSkips = ManualStepSkipStore.load( + this.questHelper.getConfigManager(), + this.questHelper.gson, + this.questHelper.getDisplayedQuestName() + ); + } + else + { + this.persistedManualSkips = new HashMap<>(); + } setLayout(new BorderLayout(0, 1)); setBorder(new EmptyBorder(5, 0, 0, 0)); @@ -131,7 +153,7 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan if (panelDetails.getRecommended() != null) { recommendedItemsPanel = new QuestRequirementsPanel("Optionally bring the following items:", panelDetails.getRecommended(), questManager, - false); + false); bodyPanel.add(recommendedItemsPanel, BorderLayout.CENTER); } else @@ -145,18 +167,16 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan for (QuestStep step : panelDetails.getSteps()) { - if(step instanceof PortTaskStep) + if (step instanceof PortTaskStep) { for (QuestStep step2 : ((PortTaskStep) step).getStepsList()) { - JTextPane questStepLabel = createQuestStepLabel(step2); - steps.put(step2, questStepLabel); - questStepsPanel.add(questStepLabel); + addStepRow(questStepsPanel, step2); } - }else{ - JTextPane questStepLabel = createQuestStepLabel(step); - steps.put(step, questStepLabel); - questStepsPanel.add(questStepLabel); + } + else + { + addStepRow(questStepsPanel, step); } } @@ -171,7 +191,179 @@ public QuestStepPanel(PanelDetails panelDetails, QuestStep currentStep, QuestMan } } - private JTextPane createQuestStepLabel(QuestStep step){ + private void addStepRow(JPanel questStepsPanel, QuestStep step) + { + orderedSidebarSteps.add(step); + JPanel row = buildStepRow(step); + stepRowPanels.put(step, row); + questStepsPanel.add(row); + } + + private JPanel buildStepRow(QuestStep step) + { + JPanel row = new JPanel(new BorderLayout()); + row.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + JTextPane questStepLabel = createQuestStepTextPane(step); + stepTextPanes.put(step, questStepLabel); + row.add(questStepLabel, BorderLayout.CENTER); + + ManualRequirement m = step.getSidebarManualSkipRequirement(); + String pk = step.getSidebarManualSkipPersistenceKey(); + if (m != null && pk != null && !pk.isBlank()) + { + boolean persistedSkipped = Boolean.TRUE.equals(persistedManualSkips.get(pk)); + if (persistedSkipped) + { + m.setShouldPass(true); + } + + JCheckBox skip = new JCheckBox(); + skip.setToolTipText("Skip step"); + skip.setOpaque(true); + Client c = questHelperPlugin.getClient(); + skip.setSelected(c != null && m.check(c)); + manualSkipBoxes.put(step, skip); + skip.addActionListener(e -> { + if (suppressManualSkipEvents) + { + return; + } + boolean sel = skip.isSelected(); + m.setShouldPass(sel); + if (sel) + { + persistedManualSkips.put(pk, true); + } + else + { + persistedManualSkips.remove(pk); + } + if (questHelper != null) + { + questHelper.notifyManualSidebarSkipChanged(pk, sel); + } + }); + skip.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + maybeShowManualSkipContextMenu(step, skip, e); + } + + @Override + public void mouseReleased(MouseEvent e) + { + maybeShowManualSkipContextMenu(step, skip, e); + } + }); + row.add(skip, BorderLayout.EAST); + } + + row.setVisible(step.isShowInSidebar()); + return row; + } + + private void maybeShowManualSkipContextMenu(QuestStep clickedStep, JCheckBox source, MouseEvent e) + { + if (!e.isPopupTrigger()) + { + return; + } + JPopupMenu menu = new JPopupMenu(); + JMenuItem tickUpTo = new JMenuItem("Tick all up to this step"); + tickUpTo.addActionListener(ev -> tickManualSkipCheckboxesUpTo(clickedStep)); + menu.add(tickUpTo); + JMenuItem resetAll = new JMenuItem("Reset all tick boxes"); + resetAll.addActionListener(ev -> resetAllManualSkipCheckboxes()); + menu.add(resetAll); + menu.show(source, e.getX(), e.getY()); + } + + private void tickManualSkipCheckboxesUpTo(QuestStep clickedStep) + { + if (clickedStep == null || orderedSidebarSteps.isEmpty()) + { + return; + } + int endIndex = orderedSidebarSteps.indexOf(clickedStep); + if (endIndex < 0) + { + return; + } + suppressManualSkipEvents = true; + try + { + for (int i = 0; i <= endIndex; i++) + { + QuestStep step = orderedSidebarSteps.get(i); + ManualRequirement m = step.getSidebarManualSkipRequirement(); + String pk = step.getSidebarManualSkipPersistenceKey(); + if (m == null || pk == null || pk.isBlank()) + { + continue; + } + m.setShouldPass(true); + persistedManualSkips.put(pk, true); + JCheckBox box = manualSkipBoxes.get(step); + if (box != null) + { + box.setSelected(true); + } + if (questHelper != null) + { + questHelper.notifyManualSidebarSkipChanged(pk, true); + } + } + } + finally + { + suppressManualSkipEvents = false; + } + } + + private void resetAllManualSkipCheckboxes() + { + if (questHelper != null) + { + questHelper.resetAllManualSidebarSkips(); + } + if (manualSkipBoxes.isEmpty()) + { + return; + } + suppressManualSkipEvents = true; + try + { + for (Map.Entry e : manualSkipBoxes.entrySet()) + { + QuestStep step = e.getKey(); + JCheckBox box = e.getValue(); + ManualRequirement m = step.getSidebarManualSkipRequirement(); + String pk = step.getSidebarManualSkipPersistenceKey(); + if (m != null) + { + m.setShouldPass(false); + } + if (pk != null && !pk.isBlank()) + { + persistedManualSkips.remove(pk); + } + if (box != null) + { + box.setSelected(false); + } + } + } + finally + { + suppressManualSkipEvents = false; + } + } + + private JTextPane createQuestStepTextPane(QuestStep step) + { JTextPane questStepLabel = JGenerator.makeJTextPane(); questStepLabel.setLayout(new BorderLayout()); questStepLabel.setAlignmentX(SwingConstants.LEFT); @@ -183,13 +375,37 @@ private JTextPane createQuestStepLabel(QuestStep step){ )); questStepLabel.setText(generateText(step)); questStepLabel.setOpaque(true); - questStepLabel.setVisible(step.isShowInSidebar()); + questStepLabel.setVisible(true); return questStepLabel; } + private void syncManualSkipCheckboxesFromRequirements(Client client) + { + if (manualSkipBoxes.isEmpty()) + { + return; + } + suppressManualSkipEvents = true; + try + { + for (Map.Entry e : manualSkipBoxes.entrySet()) + { + ManualRequirement m = e.getKey().getSidebarManualSkipRequirement(); + if (m != null) + { + e.getValue().setSelected(client != null && m.check(client)); + } + } + } + finally + { + suppressManualSkipEvents = false; + } + } + public void updateAllText() { - steps.forEach((questStep, textPane) -> { + stepTextPanes.forEach((questStep, textPane) -> { if (textPane != null) { String newText = generateText(questStep); @@ -226,7 +442,7 @@ public String generateText(QuestStep step) public List getSteps() { - return new ArrayList<>(steps.keySet()); + return new ArrayList<>(stepTextPanes.keySet()); } public void setLockable(boolean canLock) @@ -282,19 +498,19 @@ public boolean updateHighlightCheck(Client client, QuestStep newStep, QuestHelpe public void updateTextToFaded(QuestStep questStep) { - if (steps.get(questStep) != null) + if (stepTextPanes.get(questStep) != null) { - steps.get(questStep).setForeground(Color.DARK_GRAY); - steps.get(questStep).setToolTipText(questStep.getFadeCondition().getDisplayText()); + stepTextPanes.get(questStep).setForeground(Color.DARK_GRAY); + stepTextPanes.get(questStep).setToolTipText(questStep.getFadeCondition().getDisplayText()); } } public void updateTextToUnfaded(QuestStep questStep) { - if (steps.get(questStep) != null) + if (stepTextPanes.get(questStep) != null) { - steps.get(questStep).setForeground(Color.LIGHT_GRAY); - steps.get(questStep).setToolTipText(null); + stepTextPanes.get(questStep).setForeground(Color.LIGHT_GRAY); + stepTextPanes.get(questStep).setToolTipText(null); } } @@ -302,14 +518,14 @@ public void updateHighlight(QuestStep currentStep) { expand(); - if (steps.get(lastHighlightedStep) != null) + if (stepTextPanes.get(lastHighlightedStep) != null) { - steps.get(lastHighlightedStep).setForeground(Color.LIGHT_GRAY); + stepTextPanes.get(lastHighlightedStep).setForeground(Color.LIGHT_GRAY); } - if (steps.get(currentStep) != null) + if (stepTextPanes.get(currentStep) != null) { - steps.get(currentStep).setForeground(ColorScheme.BRAND_ORANGE); + stepTextPanes.get(currentStep).setForeground(ColorScheme.BRAND_ORANGE); headerLabel.setForeground(Color.BLACK); headerPanel.setBackground(ColorScheme.BRAND_ORANGE); viewControls.setBackground(ColorScheme.BRAND_ORANGE); @@ -329,9 +545,9 @@ public void removeHighlight() headerPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); viewControls.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); leftTitleContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); - if (steps.get(currentlyActiveQuestSidebarStep()) != null) + if (stepTextPanes.get(currentlyActiveQuestSidebarStep()) != null) { - steps.get(currentlyActiveQuestSidebarStep()).setForeground(Color.LIGHT_GRAY); + stepTextPanes.get(currentlyActiveQuestSidebarStep()).setForeground(Color.LIGHT_GRAY); } collapse(); @@ -430,19 +646,24 @@ public void updateRequirements(Client client) } updateStepVisibility(client); + syncManualSkipCheckboxesFromRequirements(client); } public boolean updateStepVisibility(Client client) { boolean stepVisibilityChanged = false; - for (QuestStep step : steps.keySet()) + for (QuestStep step : stepTextPanes.keySet()) { boolean oldVisibility = step.isShowInSidebar(); boolean newVisibility = step.getConditionToHide() == null || !step.getConditionToHide().check(client); stepVisibilityChanged = stepVisibilityChanged || (oldVisibility != newVisibility); step.setShowInSidebar(newVisibility); - steps.get(step).setVisible(newVisibility); + JPanel row = stepRowPanels.get(step); + if (row != null) + { + row.setVisible(newVisibility); + } } if (stepVisibilityChanged) @@ -463,7 +684,7 @@ protected QuestStep currentlyActiveQuestSidebarStep() public List getIds() { - if (panelDetails.getId() == -1) return List.of(); + if (panelDetails.getId() == Integer.MIN_VALUE) return List.of(); return List.of(panelDetails.getId()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/regionfiltering/RegionFilterPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/regionfiltering/RegionFilterPanel.java new file mode 100644 index 0000000000..2d3a4a1d57 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/panel/regionfiltering/RegionFilterPanel.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2026, Syrif + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.panel.regionfiltering; + +import net.runelite.client.plugins.microbot.questhelper.config.LeagueFiltering; +import net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueRegion; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.util.ImageUtil; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.EnumSet; + +public class RegionFilterPanel extends JPanel +{ + private final EnumSet selectedRegions = EnumSet.noneOf(LeagueRegion.class); + private final Runnable onChanged; + private final SpriteManager spriteManager; + public RegionFilterPanel(SpriteManager spriteManager, Runnable onChanged) + { + super(); + this.spriteManager = spriteManager; + this.onChanged = onChanged; + + setBorder(new EmptyBorder(10, 10, 10, 10)); + setLayout(new GridLayout(0, 3, 7, 7)); + + for (LeagueRegion region : LeagueRegion.values()) + { + add(createRegionButton(region)); + } + } + + private JButton createRegionButton(LeagueRegion region) + { + JButton button = new JButton(); + button.setOpaque(true); + button.setFocusPainted(false); + button.setBackground(ColorScheme.DARKER_GRAY_COLOR); + button.setToolTipText(region.getDisplayName()); + button.setText(region.getDisplayName()); + button.setFont(button.getFont().deriveFont(Font.PLAIN, 9f)); + button.setForeground(Color.GRAY); + button.setMargin(new Insets(4, 2, 4, 2)); + + // Load sprite async on client thread, replace text with icon when ready + spriteManager.getSpriteAsync(region.getSpriteId(), 0, sprite -> { + if (sprite != null) + { + ImageIcon selectedIcon = new ImageIcon(sprite); + ImageIcon deselectedIcon = new ImageIcon(ImageUtil.alphaOffset(sprite, -180)); + button.putClientProperty("selectedIcon", selectedIcon); + button.putClientProperty("deselectedIcon", deselectedIcon); + SwingUtilities.invokeLater(() -> { + button.setText(null); + if (selectedRegions.contains(region)) + { + button.setIcon(selectedIcon); + } + else + { + button.setIcon(deselectedIcon); + } + button.setPreferredSize(new Dimension(sprite.getWidth() + 10, sprite.getHeight() + 10)); + button.revalidate(); + }); + } + }); + + button.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + if (selectedRegions.contains(region)) + { + selectedRegions.remove(region); + updateButtonState(button, false); + } + else + { + selectedRegions.add(region); + updateButtonState(button, true); + } + LeagueFiltering.setSelectedRegions(selectedRegions.isEmpty() ? null : EnumSet.copyOf(selectedRegions)); + onChanged.run(); + } + + @Override + public void mouseEntered(MouseEvent e) + { + button.setBackground(button.getBackground().brighter()); + } + + @Override + public void mouseExited(MouseEvent e) + { + if (selectedRegions.contains(region)) + { + button.setBackground(ColorScheme.BRAND_ORANGE); + } + else + { + button.setBackground(ColorScheme.DARKER_GRAY_COLOR); + } + } + }); + + return button; + } + + private void updateButtonState(JButton button, boolean selected) + { + if (selected) + { + button.setBackground(ColorScheme.BRAND_ORANGE); + ImageIcon selectedIcon = (ImageIcon) button.getClientProperty("selectedIcon"); + if (selectedIcon != null) + { + button.setIcon(selectedIcon); + } + else + { + button.setForeground(Color.WHITE); + } + } + else + { + button.setBackground(ColorScheme.DARKER_GRAY_COLOR); + ImageIcon deselectedIcon = (ImageIcon) button.getClientProperty("deselectedIcon"); + if (deselectedIcon != null) + { + button.setIcon(deselectedIcon); + } + else + { + button.setForeground(Color.GRAY); + } + } + } + + public int getSelectedCount() + { + return selectedRegions.size(); + } + + /** + * Clears all selected regions and resets button states. + */ + public void clearSelection() + { + if (selectedRegions.isEmpty()) + { + return; + } + selectedRegions.clear(); + LeagueFiltering.setSelectedRegions(null); + for (Component comp : getComponents()) + { + if (comp instanceof JButton) + { + updateButtonState((JButton) comp, false); + } + } + onChanged.run(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java index 552e6bcaad..ecd46990f1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/bikeshedder/BikeShedder.java @@ -25,18 +25,14 @@ package net.runelite.client.plugins.microbot.questhelper.playerquests.bikeshedder; import com.google.common.collect.ImmutableMap; -import net.runelite.api.Skill; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; import net.runelite.client.plugins.microbot.questhelper.collections.ItemCollections; +import net.runelite.client.plugins.microbot.questhelper.collections.KeyringCollection; import net.runelite.client.plugins.microbot.questhelper.collections.TeleportCollections; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questhelpers.BasicQuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirements; +import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SkillRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.player.SpellbookRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; @@ -46,6 +42,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.client.plugins.microbot.questhelper.steps.widget.NormalSpells; +import net.runelite.api.Skill; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.ItemID; +import net.runelite.api.gameval.NpcID; +import net.runelite.api.gameval.ObjectID; import java.util.ArrayList; import java.util.Arrays; @@ -91,13 +93,95 @@ public class BikeShedder extends BasicQuestHelper private ItemRequirement anyCoins; private ItemStep getCoins; + // Sailing + private NpcStep talkToNpcOnBoat; + private NpcStep talkToKlarenceFromShip; + private ObjectStep useSalvagingHook; + private ObjectStep useObjectOffBoat; + private ZoneRequirement onBoat1; + private ZoneRequirement onBoat2; + private ZoneRequirement onBoat3; + private ZoneRequirement onBoat4; + + // Keyring + private ItemRequirement dustyKeyItem; + private KeyringRequirement dustyKeyKeyRing; + private DetailedQuestStep keyringStep; + @Override public Map loadSteps() { + setupRequirements(); + var lumbridge = new Zone(new WorldPoint(3217, 3210, 0), new WorldPoint(3226, 3228, 0)); var outsideLumbridge = new ZoneRequirement(false, lumbridge); moveToLumbridge.setHighlightZone(lumbridge); var steps = new ConditionalStep(this, confuseHans); + + // aldarin bank + var plankNoBank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); + { + // Do not check bank for plank + var plankStep = new DetailedQuestStep(this, "Plank requirement will not check bank", plankNoBank); + var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will not check bank (Requirement used as conditional step passed)", plankNoBank); + var cPlankStep = new ConditionalStep(this, plankStep); + cPlankStep.addStep(plankNoBank, plankStepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2926, 0)), cPlankStep); + } + + { + // Check bank for plank using alsoCheckBank + var plank = plankNoBank.alsoCheckBank(); + plank.setName("Plank (check bank 1)"); + var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 1", plank); + var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 1 (Requirement used as conditional step passed)", plank); + var cPlankStep = new ConditionalStep(this, plankStep); + cPlankStep.addStep(plank, plankStepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2925, 0)), cPlankStep); + } + + { + // Check bank for plank using setShouldCheckBank + var plank = new ItemRequirement("Plank (no bank)", ItemID.WOODPLANK); + plank.setShouldCheckBank(true); + plank.setName("Plank (check bank 2)"); + var plankStep = new DetailedQuestStep(this, "Plank requirement will check bank 2", plank); + var plankStepPassed = new DetailedQuestStep(this, "Plank requirement will check bank 2 (Requirement used as conditional step passed)", plank); + var cPlankStep = new ConditionalStep(this, plankStep); + cPlankStep.addStep(plank, plankStepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1399, 2924, 0)), cPlankStep); + } + + // mistrock bank + { + // does not need to be equipped + var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); + var step = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped", blueWizardHat); + var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, does not have to be equipped (Requirement used as conditional step passed)", blueWizardHat); + var cStep = new ConditionalStep(this, step); + cStep.addStep(blueWizardHat, stepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1383, 2866, 0)), cStep); + } + + { + // must be equipped + var blueWizardHat = new ItemRequirement("Blue wizard hat", ItemID.BLUEWIZHAT); + blueWizardHat.setMustBeEquipped(true); + var step = new DetailedQuestStep(this, "Blue wizard hat, must be equipped", blueWizardHat); + var stepPassed = new DetailedQuestStep(this, "Blue wizard hat, must be equipped (Requirement used as conditional step passed)", blueWizardHat); + var cStep = new ConditionalStep(this, step); + cStep.addStep(blueWizardHat, stepPassed); + steps.addStep(new ZoneRequirement(new WorldPoint(1382, 2866, 0)), cStep); + } + + // Boat + steps.addStep(onBoat1, talkToNpcOnBoat); + steps.addStep(onBoat2, talkToKlarenceFromShip); + steps.addStep(onBoat3, useSalvagingHook); + steps.addStep(onBoat4, useObjectOffBoat); + + steps.addStep(new ZoneRequirement(new WorldPoint(2655, 3286, 0)), keyringStep); + steps.addStep(byStaircaseInSunrisePalace, goDownstairsInSunrisePalace); steps.addStep(outsideLumbridge, moveToLumbridge); steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3218, 0)), haveRunes); @@ -108,6 +192,7 @@ public Map loadSteps() steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3216, 0)), getCoins); steps.addStep(conditionalRequirementZoneRequirement, conditionalRequirementLookAtCoins); steps.addStep(new ZoneRequirement(new WorldPoint(3224, 3221, 0)), lookAtCooksAssistant); + return new ImmutableMap.Builder() .put(-1, steps) .build(); @@ -174,22 +259,86 @@ protected void setupRequirements() var fire30 = new ItemRequirement("Fire runes", ItemID.FIRERUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 63)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 63)); var air30 = new ItemRequirement("Air runes", ItemID.AIRRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 66)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 66)); var water30 = new ItemRequirement("Water runes", ItemID.WATERRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 56)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 56)); var earth30 = new ItemRequirement("Earth runes", ItemID.EARTHRUNE, 30) - .showConditioned(new SkillRequirement(Skill.MAGIC, 60)); + .showConditioned(new SkillRequirement(Skill.MAGIC, 60)); elemental30Unique = new ItemRequirements(LogicType.OR, "Elemental runes as ItemRequirements OR", air30, water30, earth30, fire30); elemental30Unique.addAlternates(ItemID.FIRERUNE, ItemID.EARTHRUNE, ItemID.AIRRUNE); elemental30 = new ItemRequirement("Elemental rune as ItemRequirement", List.of(ItemID.AIRRUNE, ItemID.EARTHRUNE, ItemID.WATERRUNE, - ItemID.FIRERUNE), 30); + ItemID.FIRERUNE), 30); elemental30.setTooltip("You have potato"); haveRunes = new DetailedQuestStep(this, "Compare rune checks for ItemRequirement and ItemRequirements with OR.", elemental30, elemental30Unique); anyCoins = new ItemRequirement("Coins", ItemCollections.COINS); getCoins = new ItemStep(this, new WorldPoint(3224, 3215, 0), "Get coins", anyCoins); + + // Sailing + + var zones1 = new Zone[] { + new Zone(new WorldPoint(3843, 6402, 1), new WorldPoint(3844, 6402, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6389, 1), new WorldPoint(3876, 6389, 1)), + new Zone(new WorldPoint(3842, 6365, 1), new WorldPoint(3860, 6365, 1)), + new Zone(new WorldPoint(3843, 6354, 1), new WorldPoint(3884, 6354, 1)) + }; + onBoat1 = new ZoneRequirement(zones1); + + var zones2 = new Zone[] { + new Zone(new WorldPoint(3843, 6403, 1), new WorldPoint(3844, 6403, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6390, 1), new WorldPoint(3876, 6390, 1)), + new Zone(new WorldPoint(3842, 6366, 1), new WorldPoint(3860, 6366, 1)), + new Zone(new WorldPoint(3843, 6355, 1), new WorldPoint(3884, 6355, 1)) + }; + onBoat2 = new ZoneRequirement(zones2); + + var zones3 = new Zone[] { + new Zone(new WorldPoint(3843, 6404, 1), new WorldPoint(3844, 6404, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6391, 1), new WorldPoint(3876, 6391, 1)), + new Zone(new WorldPoint(3842, 6367, 1), new WorldPoint(3860, 6367, 1)), + new Zone(new WorldPoint(3843, 6356, 1), new WorldPoint(3884, 6356, 1)) + }; + onBoat3 = new ZoneRequirement(zones3); + + var zones4 = new Zone[] { + new Zone(new WorldPoint(3843, 6405, 1), new WorldPoint(3844, 6405, 1)), // Tutorial + new Zone(new WorldPoint(3842, 6312, 1), new WorldPoint(3876, 6392, 1)), + new Zone(new WorldPoint(3842, 6368, 1), new WorldPoint(3860, 6368, 1)), + new Zone(new WorldPoint(3843, 6357, 1), new WorldPoint(3884, 6357, 1)) + }; + onBoat4 = new ZoneRequirement(zones4); + + talkToNpcOnBoat = new NpcStep(this, NpcID.SAILING_INTRO_ANNE_BOAT, "Talk to a ship NPC."); + List shipNpcs = new ArrayList<>(); + for (int i = NpcID.SAILING_CREW_GENERIC_1_WORLD; i <= NpcID.SAILING_CREW_GHOST_JENKINS_CARGO_3; i++) + { + shipNpcs.add(i); + } + talkToNpcOnBoat.addHighlightZones(zones1); + talkToNpcOnBoat.addAlternateNpcs(shipNpcs.toArray(new Integer[0])); + + talkToKlarenceFromShip = new NpcStep(this, NpcID.KLARENSE, new WorldPoint(3046, 3205, 0), "Klarence off the ship."); + talkToKlarenceFromShip.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); + talkToKlarenceFromShip.addHighlightZones(zones2); + List salvagingHookIds = new ArrayList<>(); + for (int i = ObjectID.SAILING_INTRO_SALVAGING_HOOK; i <= ObjectID.SALVAGING_HOOK_LARGE_DRAGON_B; i++) + { + salvagingHookIds.add(i); + } + + useSalvagingHook = new ObjectStep(this, ObjectID.SAILING_INTRO_SALVAGING_HOOK, "Use the salvaging hook."); + useSalvagingHook.addAlternateObjects(salvagingHookIds.toArray(new Integer[0])); + useSalvagingHook.addHighlightZones(zones3); + + useObjectOffBoat = new ObjectStep(this, ObjectID.DRAGONSHIPGANGPLANK_ON, new WorldPoint(3047, 3205, 0), "Click Klarense's gangplank."); + useObjectOffBoat.setHighlightZone(new Zone(new WorldPoint(3044, 3202, 0), new WorldPoint(3050, 3205, 0))); + useObjectOffBoat.addHighlightZones(zones4); + + dustyKeyItem = new ItemRequirement("Dusty key (ItemReq)", ItemID.DUSTY_KEY); + dustyKeyKeyRing = new KeyringRequirement("Dusty key (KeyRingReq)", KeyringCollection.DUSTY_KEY); + keyringStep = new DetailedQuestStep(this, "We need the dusty key", dustyKeyItem, dustyKeyKeyRing); } @Override @@ -211,6 +360,8 @@ public List getPanels() panels.add(new PanelDetails("Item step", List.of(getCoins), List.of(anyCoins))); panels.add(new PanelDetails("Quest state", List.of(lookAtCooksAssistant), List.of(lookAtCooksAssistantRequirement, lookAtCooksAssistantTextRequirement))); panels.add(new PanelDetails("Ensure staircase upstairs in Sunrise Palace is highlighted", List.of(goDownstairsInSunrisePalace), List.of())); + panels.add(new PanelDetails("Sailing", List.of(talkToNpcOnBoat, talkToKlarenceFromShip, useSalvagingHook, useObjectOffBoat), List.of())); + panels.add(new PanelDetails("Key ring", List.of(keyringStep), List.of(dustyKeyItem, dustyKeyKeyRing))); return panels; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/cookshelper/CooksHelper.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/cookshelper/CooksHelper.java deleted file mode 100644 index 50bc5a9b56..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/playerquests/cookshelper/CooksHelper.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2023, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.playerquests.cookshelper; - -import net.runelite.api.QuestState; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.gameval.ItemID; -import net.runelite.api.gameval.NpcID; -import net.runelite.api.gameval.ObjectID; -import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; -import net.runelite.client.plugins.microbot.questhelper.questhelpers.PlayerMadeQuestHelper; -import net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest; -import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; -import net.runelite.client.plugins.microbot.questhelper.requirements.quest.QuestRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.PlayerQuestStateRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.ZoneRequirement; -import net.runelite.client.plugins.microbot.questhelper.rewards.UnlockReward; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.RuneliteConfigSetter; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.dialog.RuneliteDialogStep; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.dialog.RuneliteObjectDialogStep; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.dialog.RunelitePlayerDialogStep; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.FaceAnimationIDs; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.FakeItem; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.FakeNpc; -import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.ReplacedObject; -import net.runelite.client.plugins.microbot.questhelper.steps.ConditionalStep; -import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; -import net.runelite.client.plugins.microbot.questhelper.steps.QuestStep; -import net.runelite.client.plugins.microbot.questhelper.steps.TileStep; -import net.runelite.client.plugins.microbot.questhelper.steps.playermadesteps.RuneliteObjectStep; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class CooksHelper extends PlayerMadeQuestHelper -{ - private RuneliteObjectStep talkToCook, talkToHopleez, grabCabbage, returnToHopleez; - - private DetailedQuestStep standNextToCook, standNextToHopleez, standNextToHopleez2; - - private Requirement nearCook, nearHopleez; - - private FakeNpc cooksCousin, hopleez; - - private FakeItem cabbage; - - private PlayerQuestStateRequirement talkedToCooksCousin, talkedToHopleez, displayCabbage, pickedCabbage; - - @Override - public QuestStep loadStep() - { - itemWidget = ItemID.TOP_HAT; - rotationX = 100; - zoom = 200; - - setupRequirements(); - createRuneliteObjects(); - setupSteps(); - - PlayerQuestStateRequirement req = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 0); - - ConditionalStep questSteps = new ConditionalStep(this, standNextToCook); - questSteps.addStep(req.getNewState(4), new DetailedQuestStep(this, "Quest completed!")); - questSteps.addStep(new Conditions(req.getNewState(3), nearHopleez), returnToHopleez); - questSteps.addStep(req.getNewState(3), standNextToHopleez2); - questSteps.addStep(req.getNewState(2), grabCabbage); - questSteps.addStep(new Conditions(req.getNewState(1), nearHopleez), talkToHopleez); - questSteps.addStep(req.getNewState(1), standNextToHopleez); - questSteps.addStep(nearCook, talkToCook); - - // We want something which can be added to a requirement, which - - // Don't save to config until helper closes/client closing? - - return questSteps; - } - - @Override - protected void setupRequirements() - { - // NPCs should persist through quest steps unless actively removed? Dialog should be conditional on step (sometimes) - // Hide/show NPCs/the runelite character when NPCs go on it/you go over it - // Handle cancelling dialog boxes (even just moving a tile away should remove for example) - // Properly handle removing NPC from screen when changing floors and such - // Work out how to do proper priority on the npcs being clicked - // Wandering NPCs? - // Objects + items (basically same as NPCs) - talkedToCooksCousin = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 1, Operation.GREATER_EQUAL); - talkedToHopleez = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 2, Operation.GREATER_EQUAL); - pickedCabbage = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 3, Operation.GREATER_EQUAL); - displayCabbage = new PlayerQuestStateRequirement(configManager, getQuest().getPlayerQuests(), 2); - nearCook = new ZoneRequirement(new Zone(new WorldPoint(3206, 3212, 0), new WorldPoint(3212, 3218, 0))); - nearHopleez = new ZoneRequirement(new Zone(new WorldPoint(3232, 3212, 0), new WorldPoint(3238, 3218, 0))); - } - - public void setupSteps() - { - // TODO: Need a way to define the groupID of a runelite object to be a quest step without it being stuck - // Add each step's groupID as a sub-group - - talkToCook = new RuneliteObjectStep(this, cooksCousin, "Talk to the Lumbridge Cook's Cousin."); - standNextToCook = new TileStep(this, new WorldPoint(3210, 3215, 0), "Talk to the Lumbridge Cook's Cousin."); - talkToCook.addSubSteps(standNextToCook); - - talkToHopleez = new RuneliteObjectStep(this, hopleez, "Talk to Hopleez east of Lumbridge Castle."); - standNextToHopleez = new TileStep(this, new WorldPoint(3236, 3215, 0), "Talk to Hopleez east of Lumbridge Castle."); - talkToHopleez.addSubSteps(standNextToHopleez); - - grabCabbage = new RuneliteObjectStep(this, cabbage, "Get the cabbage to the north of Hopleez, outside the Sheared Ram."); - - returnToHopleez = new RuneliteObjectStep(this, hopleez, "Return to Hopleez east of Lumbridge Castle."); - standNextToHopleez2 = new DetailedQuestStep(this, new WorldPoint(3235, 3216, 0), "Return to Hopleez east of Lumbridge Castle."); - returnToHopleez.addSubSteps(standNextToHopleez2); - } - - private void setupCooksCousin() - { - // Cook's Cousin - cooksCousin = runeliteObjectManager.createFakeNpc(this.toString(), client.getNpcDefinition(NpcID.POH_SERVANT_COOK_WOMAN).getModels(), new WorldPoint(3209, 3215, 0), 808); - cooksCousin.setName("Cook's Cousin"); - cooksCousin.setFace(4626); - cooksCousin.setExamine("The Cook's cousin."); - cooksCousin.addTalkAction(runeliteObjectManager); - cooksCousin.addExamineAction(runeliteObjectManager); - - QuestRequirement hasDoneCooksAssistant = new QuestRequirement(QuestHelperQuest.COOKS_ASSISTANT, QuestState.FINISHED); - - RuneliteObjectDialogStep dontMeetReqDialog = cooksCousin.createDialogStepForNpc("Come talk to me once you've helped my cousin out."); - cooksCousin.addDialogTree(null, dontMeetReqDialog); - - RuneliteDialogStep dialog = cooksCousin.createDialogStepForNpc("Hey, you there! You helped out my cousin before right?"); - dialog.addContinueDialog(new RunelitePlayerDialogStep(client, "I have yeah, what's wrong? Does he need some more eggs? Maybe I can just get him a chicken instead?")) - .addContinueDialog(cooksCousin.createDialogStepForNpc("No no, nothing like that. Have you seen that terribly dressed person outside the courtyard?", FaceAnimationIDs.FRIENDLY_QUESTIONING)) - .addContinueDialog(cooksCousin.createDialogStepForNpc("I don't know who they are, but can you please get them to move along please?", FaceAnimationIDs.FRIENDLY_QUESTIONING)) - .addContinueDialog(cooksCousin.createDialogStepForNpc("They seem to be attracting more troublemakers....")) - .addContinueDialog(new RunelitePlayerDialogStep(client, "You mean Hatius? If so it'd be my pleasure.").setStateProgression(talkedToCooksCousin.getSetter())); - cooksCousin.addDialogTree(hasDoneCooksAssistant, dialog); - - RuneliteObjectDialogStep dialogV2 = cooksCousin.createDialogStepForNpc("That terribly dressed person is still outside the castle, go talk to them!"); - cooksCousin.addDialogTree(talkedToCooksCousin, dialogV2); - } - - private void setupHopleez() - { - // Hopleez - hopleez = runeliteObjectManager.createFakeNpc(this.toString(), client.getNpcDefinition(NpcID.ZEAH_DEFENCE_PURE).getModels(), new WorldPoint(3235, 3215, 0), 808); - hopleez.setName("Hopleez"); - hopleez.setFace(7481); - hopleez.setExamine("He was here first."); - hopleez.addTalkAction(runeliteObjectManager); - hopleez.addExamineAction(runeliteObjectManager); - - // Dialog - RuneliteDialogStep hopleezDialogPreQuest = hopleez.createDialogStepForNpc("Hop noob."); - hopleezDialogPreQuest.addContinueDialog(new RunelitePlayerDialogStep(client, "What? Also, what are you wearing?")) - .addContinueDialog(hopleez.createDialogStepForNpc("Hop NOOB.")); - hopleez.addDialogTree(null, hopleezDialogPreQuest); - - RuneliteDialogStep hopleezDialog1 = hopleez.createDialogStepForNpc("Hop noob.", FaceAnimationIDs.ANNOYED); - hopleezDialog1.addContinueDialog(new RunelitePlayerDialogStep(client, "What? The Cook's Cousin sent me to see what you were doing here.", FaceAnimationIDs.QUIZZICAL)) - .addContinueDialog(hopleez.createDialogStepForNpc("One moment I was relaxing in Zeah killing some crabs. I closed my eyes for a second, and suddenly I'm here.")) - .addContinueDialog(hopleez.createDialogStepForNpc("People would always try to steal my spot in Zeah, and it seems it's no different here!", FaceAnimationIDs.ANNOYED)) - .addContinueDialog(hopleez.createDialogStepForNpc("Not only is this guy crashing me, but he's trying to outdress me too!", FaceAnimationIDs.ANNOYED_2)) - .addContinueDialog(new RunelitePlayerDialogStep(client, "Hatius? I'm pretty sure he's been here much longer than you....", FaceAnimationIDs.QUESTIONING)) - .addContinueDialog(hopleez.createDialogStepForNpc("I swear he wasn't here when I first arrived, I went away for a second and suddenly he's here!", FaceAnimationIDs.ANNOYED_2)) - .addContinueDialog(hopleez.createDialogStepForNpc("Help me teach him a lesson, get me that old cabbage from outside the The Sheared Ram.")) - .addContinueDialog(new RunelitePlayerDialogStep(client, "Umm, sure....", talkedToHopleez.getSetter())); - hopleez.addDialogTree(talkedToCooksCousin, hopleezDialog1); - - - RuneliteDialogStep hopleezWaitingForCabbageDialog = hopleez.createDialogStepForNpc("Get me that cabbage!"); - hopleez.addDialogTree(talkedToHopleez, hopleezWaitingForCabbageDialog); - - RuneliteConfigSetter endQuest = new RuneliteConfigSetter(configManager, getQuest().getPlayerQuests().getConfigValue(), "4"); - RuneliteDialogStep hopleezGiveCabbageDialog = hopleez.createDialogStepForNpc("Have you got the cabbage?"); - hopleezGiveCabbageDialog - .addContinueDialog(new RunelitePlayerDialogStep(client, "I have! Here you go, why do you need it?")) - .addContinueDialog(hopleez.createDialogStepForNpc("Nice! Now let's sort out this crasher...")) - .addContinueDialog(hopleez.createDialogStepForNpc("Oi noob, take this!")) - .addContinueDialog(new RuneliteObjectDialogStep("Hatius Cosaintus", "What on earth?", NpcID.HATIUS_LUMBRIDGE_DIARY).setStateProgression(endQuest)); - hopleez.addDialogTree(pickedCabbage, hopleezGiveCabbageDialog); - } - - private void setupCabbage() - { - // Old cabbage - cabbage = runeliteObjectManager.createFakeItem(this.toString(), new int[]{ 8196 }, new WorldPoint(3231, 3235, 0), -1); - cabbage.setName("Old cabbage"); - cabbage.setExamine("A mouldy looking cabbage."); - cabbage.addExamineAction(runeliteObjectManager); - cabbage.setDisplayRequirement(displayCabbage); - cabbage.addTakeAction(runeliteObjectManager, new RuneliteConfigSetter(configManager, getQuest().getPlayerQuests().getConfigValue(), "3"), - "You pick up the old cabbage."); - - cabbage.setObjectToRemove(new ReplacedObject(ObjectID.AP_INDICATOR, new WorldPoint(3231, 3235, 0))); - } - - private void createRuneliteObjects() - { - setupCooksCousin(); - setupHopleez(); - setupCabbage(); - } - - @Override - public List getGeneralRequirements() - { - return Collections.singletonList(new QuestRequirement(QuestHelperQuest.COOKS_ASSISTANT, QuestState.FINISHED)); - } - - @Override - public List getUnlockRewards() - { - return Collections.singletonList( - new UnlockReward("A replacement for Hatius Cosaintus") - ); - } - - @Override - public List getPanels() - { - List allSteps = new ArrayList<>(); - PanelDetails helpingTheCousinSteps = new PanelDetails("Helping the Cook's Cousin", Arrays.asList(talkToCook, talkToHopleez, grabCabbage, returnToHopleez)); - allSteps.add(helpingTheCousinSteps); - - return allSteps; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java index 18a590d939..37e5a9a687 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questhelpers/QuestHelper.java @@ -24,12 +24,14 @@ */ package net.runelite.client.plugins.microbot.questhelper.questhelpers; +import com.google.gson.Gson; import com.google.inject.Binder; import com.google.inject.CreationException; import com.google.inject.Injector; import com.google.inject.Module; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.panel.ManualStepSkipStore; import net.runelite.client.plugins.microbot.questhelper.panel.PanelDetails; import net.runelite.client.plugins.microbot.questhelper.questinfo.ExternalQuestResources; import net.runelite.client.plugins.microbot.questhelper.questinfo.HelperConfig; @@ -77,6 +79,9 @@ public abstract class QuestHelper implements Module, QuestDebugRenderer @Inject private EventBus eventBus; + @Inject + public Gson gson; + @Getter private QuestStep currentStep; @@ -84,6 +89,14 @@ public abstract class QuestHelper implements Module, QuestDebugRenderer @Setter private QuestHelperQuest quest; + /** + * When set (e.g. construct preview / imported player guides), used for sidebar and step overlays + * instead of {@link QuestHelperQuest#getName()} from {@link #quest}. + */ + @Getter + @Setter + private String playerFacingQuestName; + @Setter private Injector injector; @@ -118,6 +131,49 @@ public void removeRuneliteObjects() runeliteObjectManager.removeGroupAndSubgroups(toString()); } + /** + * Human-readable quest title for UI (sidebar, overlays). Uses {@link #playerFacingQuestName} when set, + * otherwise the linked {@link QuestHelperQuest} name, otherwise a generic label. + */ + public String getDisplayedQuestName() + { + if (playerFacingQuestName != null && !playerFacingQuestName.isBlank()) + { + return playerFacingQuestName.trim(); + } + if (quest != null) + { + return quest.getName(); + } + return "Quest Helper"; + } + + /** + * Persists a manual skip flag for one step (sidebar checkbox) and notifies the helper to refresh branch logic. + */ + public void notifyManualSidebarSkipChanged(String persistenceKey, boolean skipped) + { + if (persistenceKey == null || persistenceKey.isBlank()) + { + return; + } + ManualStepSkipStore.put(configManager, gson, getDisplayedQuestName(), persistenceKey, skipped); + onManualSidebarSkipsPersistedChanged(); + } + + public void resetAllManualSidebarSkips() + { + ManualStepSkipStore.clearAll(configManager, getDisplayedQuestName()); + onManualSidebarSkipsPersistedChanged(); + } + + /** + * Hook for helpers that merge persisted skips with runtime state (e.g. maker preview). + */ + protected void onManualSidebarSkipsPersistedChanged() + { + } + public abstract boolean updateQuest(); public void debugStartup(QuestHelperConfig config) @@ -218,9 +274,9 @@ public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, Pane .build() ); panelComponent.getChildren().add(LineComponent.builder() - .left(getQuest().getName()) + .left(getDisplayedQuestName()) .leftColor(getConfig().debugColor()) - .right(getVar() + "") + .right(getQuest() != null ? String.valueOf(getVar()) : "—") .rightColor(getConfig().debugColor()) .build() ); @@ -228,6 +284,10 @@ public void renderDebugOverlay(Graphics graphics, QuestHelperPlugin plugin, Pane public int getVar() { + if (quest == null) + { + return 0; + } return quest.getVar(client); } @@ -240,11 +300,6 @@ public boolean hasQuestStateBecomeFinished() return questStateEnteredFinished; } - public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) - { - - } - protected void setupZones() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java index 17b6e15564..e20412742e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/ExternalQuestResources.java @@ -28,6 +28,7 @@ public enum ExternalQuestResources SHEEP_SHEARER("https://oldschool.runescape.wiki/w/Sheep_Shearer"), SHIELD_OF_ARRAV_PHOENIX_GANG("https://oldschool.runescape.wiki/w/Shield_of_Arrav"), SHIELD_OF_ARRAV_BLACK_ARM_GANG("https://oldschool.runescape.wiki/w/Shield_of_Arrav"), + THE_IDES_OF_MILK("https://oldschool.runescape.wiki/w/The_Ides_of_Milk"), VAMPYRE_SLAYER("https://oldschool.runescape.wiki/w/Vampyre_Slayer"), WITCHS_POTION("https://oldschool.runescape.wiki/w/Witch%27s_Potion"), X_MARKS_THE_SPOT("https://oldschool.runescape.wiki/w/X_Marks_the_Spot"), @@ -192,6 +193,7 @@ public enum ExternalQuestResources PRYING_TIMES("https://oldschool.runescape.wiki/w/Prying_Times"), CURRENT_AFFAIRS("https://oldschool.runescape.wiki/w/Current_Affairs"), TROUBLED_TORTUGANS("https://oldschool.runescape.wiki/w/Troubled_Tortugans"), + THE_RED_REEF("https://oldschool.runescape.wiki/w/The_Red_Reef"), //Miniquests ENTER_THE_ABYSS("https://oldschool.runescape.wiki/w/Enter_the_Abyss"), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueQuestRegions.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueQuestRegions.java new file mode 100644 index 0000000000..44243f9b90 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueQuestRegions.java @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2026, Syrif + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.questinfo; + +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.Map; + +import static net.runelite.client.plugins.microbot.questhelper.questinfo.LeagueRegion.*; +import static net.runelite.client.plugins.microbot.questhelper.questinfo.QuestHelperQuest.*; + +/** + * Maps quests to the league regions required to complete them. + * TODO: Quests with no mapping require manual curation. + * Unmapped quests always pass the league filter. + * Update this class per league season. + */ +public class LeagueQuestRegions +{ + private static final Map> QUEST_REGIONS = new EnumMap<>(QuestHelperQuest.class); + + static + { + // F2P quests + put(X_MARKS_THE_SPOT, ASGARNIA); + put(THE_CORSAIR_CURSE, ASGARNIA, KANDARIN); + put(MISTHALIN_MYSTERY, MISTHALIN); + put(PIRATES_TREASURE, ASGARNIA); + put(GOBLIN_DIPLOMACY, ASGARNIA); + put(THE_KNIGHTS_SWORD, ASGARNIA); + put(WITCHS_POTION, ASGARNIA); + put(BLACK_KNIGHTS_FORTRESS, ASGARNIA); + put(DORICS_QUEST, ASGARNIA); + put(PRINCE_ALI_RESCUE, DESERT); + put(IMP_CATCHER, MISTHALIN); + put(VAMPYRE_SLAYER, MISTHALIN); + put(ERNEST_THE_CHICKEN, MISTHALIN); + put(THE_RESTLESS_GHOST, MISTHALIN); + put(SHEEP_SHEARER, MISTHALIN); + put(SHIELD_OF_ARRAV_PHOENIX_GANG, MISTHALIN); + put(SHIELD_OF_ARRAV_BLACK_ARM_GANG, MISTHALIN); + put(DEMON_SLAYER, MISTHALIN); + put(ROMEO__JULIET, MISTHALIN); + put(COOKS_ASSISTANT, MISTHALIN); + + // Members quests + put(WITCHS_HOUSE, ASGARNIA); + put(HEROES_QUEST, ASGARNIA); + put(SCORPION_CATCHER, ASGARNIA, KANDARIN, MISTHALIN); + put(FISHING_CONTEST, KANDARIN); + put(TRIBAL_TOTEM, KARAMJA, KANDARIN); + put(MONKS_FRIEND, KANDARIN); + put(TEMPLE_OF_IKOV, KANDARIN, MISTHALIN); + put(CLOCK_TOWER, KANDARIN); + put(FIGHT_ARENA, KANDARIN); + put(HAZEEL_CULT, KANDARIN); + put(SHEEP_HERDER, KANDARIN); + put(PLAGUE_CITY, KANDARIN); + put(SEA_SLUG, KANDARIN); + put(WATERFALL_QUEST, KANDARIN); + put(OBSERVATORY_QUEST, KANDARIN); + put(DWARF_CANNON, ASGARNIA, KANDARIN); + put(GERTRUDES_CAT, MISTHALIN); + put(BIG_CHOMPY_BIRD_HUNTING, KANDARIN); + put(TAI_BWO_WANNAI_TRIO, KARAMJA); + put(SHADES_OF_MORTTON, MORYTANIA); + put(THRONE_OF_MISCELLANIA, FREMENNIK); + put(HAUNTED_MINE, MORYTANIA); + put(TROLL_ROMANCE, ASGARNIA, KANDARIN); + put(GHOSTS_AHOY, MORYTANIA); + put(BETWEEN_A_ROCK, ASGARNIA, FREMENNIK, KANDARIN); + put(THE_GOLEM, DESERT); + put(THE_GIANT_DWARF, ASGARNIA, FREMENNIK); + put(RECRUITMENT_DRIVE, ASGARNIA); + put(FORGETTABLE_TALE, ASGARNIA, FREMENNIK, KANDARIN); + put(A_TAIL_OF_TWO_CATS, ASGARNIA, DESERT); + put(WANTED, ASGARNIA, MORYTANIA, WILDERNESS); + put(SHADOW_OF_THE_STORM, DESERT); + put(MAKING_HISTORY, FREMENNIK, KANDARIN, MORYTANIA); + put(SPIRITS_OF_THE_ELID, DESERT); + put(DEVIOUS_MINDS, ASGARNIA, MORYTANIA, WILDERNESS); + put(THE_HAND_IN_THE_SAND, ASGARNIA, KANDARIN); + put(THE_SLUG_MENACE, ASGARNIA, KANDARIN); // also needs Misthalin OR Desert OR Wilderness for altars + put(ELEMENTAL_WORKSHOP_II, MISTHALIN, KANDARIN); + put(ENLIGHTENED_JOURNEY, ASGARNIA); + put(EAGLES_PEAK, KANDARIN); + put(ANIMAL_MAGNETISM, ASGARNIA, MORYTANIA); + put(CONTACT, DESERT); + put(THE_FREMENNIK_ISLES, FREMENNIK); + put(WHAT_LIES_BELOW, DESERT, WILDERNESS); + put(OLAFS_QUEST, FREMENNIK); + put(ANOTHER_SLICE_OF_HAM, ASGARNIA, FREMENNIK); + put(GRIM_TALES, ASGARNIA); + put(BIOHAZARD, ASGARNIA, KANDARIN); + put(TOWER_OF_LIFE, KANDARIN); + put(LAND_OF_THE_GOBLINS, ASGARNIA, FREMENNIK, KANDARIN); + put(ZOGRE_FLESH_EATERS, KANDARIN); + put(CLIENT_OF_KOUREND, KOUREND); + put(THE_QUEEN_OF_THIEVES, KOUREND); + put(THE_DEPTHS_OF_DESPAIR, KOUREND); + put(A_TASTE_OF_HOPE, MORYTANIA); + put(TALE_OF_THE_RIGHTEOUS, KOUREND); + put(THE_ASCENT_OF_ARCEUUS, KOUREND); + put(THE_FORSAKEN_TOWER, KOUREND); + put(THE_FREMENNIK_EXILES, FREMENNIK); + put(SINS_OF_THE_FATHER, MORYTANIA); + put(A_PORCINE_OF_INTEREST, ASGARNIA); + put(GETTING_AHEAD, KOUREND); + put(A_NIGHT_AT_THE_THEATRE, MORYTANIA); + put(A_KINGDOM_DIVIDED, KOUREND); + put(BENEATH_CURSED_SANDS, DESERT); + put(SLEEPING_GIANTS, DESERT); + put(THE_GARDEN_OF_DEATH, KOUREND); + put(THE_PATH_OF_GLOUPHRIE, KANDARIN); + put(CHILDREN_OF_THE_SUN, MISTHALIN); + put(AT_FIRST_LIGHT, VARLAMORE); + put(PERILOUS_MOON, VARLAMORE); + put(THE_RIBBITING_TALE_OF_A_LILY_PAD_LABOUR_DISPUTE, VARLAMORE); + put(THE_HEART_OF_DARKNESS, VARLAMORE); + put(DEATH_ON_THE_ISLE, VARLAMORE); + put(MEAT_AND_GREET, VARLAMORE); + put(ETHICALLY_ACQUIRED_ANTIQUITIES, ASGARNIA, VARLAMORE); + put(THE_FINAL_DAWN, VARLAMORE); + put(SHADOWS_OF_CUSTODIA, VARLAMORE); + put(SCRAMBLED, VARLAMORE); + put(A_SOULS_BANE, MISTHALIN); + put(RAG_AND_BONE_MAN_I, MISTHALIN, KARAMJA); + put(ROYAL_TROUBLE, FREMENNIK); + put(DEATH_TO_THE_DORGESHUUN, MISTHALIN); + + put(BELOW_ICE_MOUNTAIN, ASGARNIA, MISTHALIN); + put(BIG_CHOMPY_BIRD_HUNTING, KANDARIN); + put(CABIN_FEVER, MORYTANIA); + put(COLD_WAR, KANDARIN, FREMENNIK); + put(THE_CURSE_OF_ARRAV, DESERT, MISTHALIN, ASGARNIA); + put(DARKNESS_OF_HALLOWVALE, MISTHALIN, MORYTANIA); + put(DEFENDER_OF_VARROCK, MISTHALIN); + put(DESERT_TREASURE, DESERT, MISTHALIN, KANDARIN, ASGARNIA, MORYTANIA); + put(ENAKHRAS_LAMENT, DESERT); + put(THE_FEUD, DESERT); + put(THE_GREAT_BRAIN_ROBBERY, MORYTANIA, ASGARNIA); + put(HORROR_FROM_THE_DEEP, FREMENNIK, KANDARIN); + put(THE_IDES_OF_MILK, MISTHALIN); + put(IN_AID_OF_THE_MYREQUE, MISTHALIN, MORYTANIA); + put(IN_SEARCH_OF_THE_MYREQUE, MORYTANIA); + put(THE_LOST_TRIBE, MISTHALIN, ASGARNIA); + put(MAKING_FRIENDS_WITH_MY_ARM, MISTHALIN, FREMENNIK); + put(MOUNTAIN_DAUGHTER, FREMENNIK, KANDARIN); + put(MOURNINGS_END_PART_I, KANDARIN, TIRANNWN, ASGARNIA); + put(MOURNINGS_END_PART_II, KANDARIN, TIRANNWN); + put(MY_ARMS_BIG_ADVENTURE, ASGARNIA, KARAMJA); + put(RAG_AND_BONE_MAN_II, MISTHALIN, KARAMJA, KANDARIN, ASGARNIA, MORYTANIA, DESERT); + put(RATCATCHERS, MISTHALIN, KANDARIN, FREMENNIK, ASGARNIA, DESERT); + put(REGICIDE, KANDARIN, TIRANNWN, ASGARNIA); + put(ROVING_ELVES, KANDARIN, TIRANNWN); + put(RUM_DEAL, MORYTANIA); + put(SECRETS_OF_THE_NORTH, KANDARIN, FREMENNIK); + put(SONG_OF_THE_ELVES, TIRANNWN, KANDARIN); + put(TEARS_OF_GUTHIX, MISTHALIN); + // Possibly Wilderness, but only if the abyss rcing area when tele'd there counts as wildy? + put(TEMPLE_OF_THE_EYE, DESERT, MISTHALIN); + put(THE_TOURIST_TRAP, DESERT); + put(WHILE_GUTHIX_SLEEPS, MISTHALIN, ASGARNIA, KANDARIN); + + // put(TROUBLED_TORTUGANS, SEA); + // put(PRYING_TIMES, SEA); + // put(PANDEMONIUM, ASGARNIA, SEA); + // put(CURRENT_AFFAIRS, KANDARIN, SEA); + + // RFD subquests + put(RECIPE_FOR_DISASTER_START, MISTHALIN, FREMENNIK, VARLAMORE); + put(RECIPE_FOR_DISASTER_WARTFACE_AND_BENTNOZE, MISTHALIN, ASGARNIA); + put(RECIPE_FOR_DISASTER_DWARF, MISTHALIN, ASGARNIA, KANDARIN); + put(RECIPE_FOR_DISASTER_EVIL_DAVE, MISTHALIN, DESERT); + put(RECIPE_FOR_DISASTER_PIRATE_PETE, MISTHALIN, KANDARIN); + put(RECIPE_FOR_DISASTER_LUMBRIDGE_GUIDE, MISTHALIN, ASGARNIA, KANDARIN); + put(RECIPE_FOR_DISASTER_SIR_AMIK_VARZE, MISTHALIN, ASGARNIA, FREMENNIK); + put(RECIPE_FOR_DISASTER_MONKEY_AMBASSADOR, MISTHALIN, KANDARIN); + put(RECIPE_FOR_DISASTER_SKRACH_UGLOGWEE, MISTHALIN, KANDARIN); + + // Miniquests + put(ALFRED_GRIMHANDS_BARCRAWL, KANDARIN); + put(BARBARIAN_TRAINING, KARAMJA, KANDARIN); + put(SKIPPY_AND_THE_MOGRES, ASGARNIA); + put(LAIR_OF_TARN_RAZORLOR, MORYTANIA); + put(BEAR_YOUR_SOUL, ASGARNIA, KOUREND); + put(THE_MAGE_ARENA, WILDERNESS); + put(FAMILY_PEST, DESERT, FREMENNIK, KANDARIN); + put(THE_MAGE_ARENA_II, WILDERNESS); + put(IN_SEARCH_OF_KNOWLEDGE, KOUREND); + put(DADDYS_HOME, MISTHALIN); + // THE_FROZEN_DOOR and INTO_THE_TOMBS don't have QuestHelperQuest entries yet + put(HIS_FAITHFUL_SERVANTS, MORYTANIA); + put(VALE_TOTEMS, VARLAMORE); + + // Diaries + put(DESERT_EASY, DESERT); + put(DESERT_MEDIUM, DESERT); + put(DESERT_HARD, DESERT); + put(DESERT_ELITE, DESERT); + + put(FALADOR_EASY, ASGARNIA); + put(FALADOR_MEDIUM, ASGARNIA); + put(FALADOR_HARD, ASGARNIA); + put(FALADOR_ELITE, ASGARNIA); + + put(FREMENNIK_EASY, FREMENNIK); + put(FREMENNIK_MEDIUM, FREMENNIK); + put(FREMENNIK_HARD, FREMENNIK); + put(FREMENNIK_ELITE, FREMENNIK); + + put(ARDOUGNE_EASY, KANDARIN); + put(ARDOUGNE_MEDIUM, KANDARIN); + put(ARDOUGNE_HARD, KANDARIN); + put(ARDOUGNE_ELITE, KANDARIN); + + put(KANDARIN_EASY, KANDARIN); + put(KANDARIN_MEDIUM, KANDARIN); + put(KANDARIN_HARD, KANDARIN); + put(KANDARIN_ELITE, KANDARIN); + + put(KARAMJA_EASY, KARAMJA); + put(KARAMJA_MEDIUM, KARAMJA); + put(KARAMJA_HARD, KARAMJA); + put(KARAMJA_ELITE, KARAMJA); + + put(KOUREND_EASY, KOUREND); + put(KOUREND_MEDIUM, KOUREND); + put(KOUREND_HARD, KOUREND); + put(KOUREND_ELITE, KOUREND); + + put(LUMBRIDGE_EASY, MISTHALIN); + put(LUMBRIDGE_MEDIUM, MISTHALIN); + put(LUMBRIDGE_HARD, MISTHALIN); + put(LUMBRIDGE_ELITE, MISTHALIN); + + put(MORYTANIA_EASY, MORYTANIA); + put(MORYTANIA_MEDIUM, MORYTANIA); + put(MORYTANIA_HARD, MORYTANIA); + put(MORYTANIA_ELITE, MORYTANIA); + + put(VARROCK_EASY, MISTHALIN); + put(VARROCK_MEDIUM, MISTHALIN); + put(VARROCK_HARD, MISTHALIN); + put(VARROCK_ELITE, MISTHALIN); + + put(WESTERN_EASY, KANDARIN, TIRANNWN); + put(WESTERN_MEDIUM, KANDARIN, TIRANNWN); + put(WESTERN_HARD, KANDARIN, TIRANNWN); + put(WESTERN_ELITE, KANDARIN, TIRANNWN); + + put(WILDERNESS_EASY, WILDERNESS); + put(WILDERNESS_MEDIUM, WILDERNESS); + put(WILDERNESS_HARD, WILDERNESS); + put(WILDERNESS_ELITE, WILDERNESS); + } + + private static void put(QuestHelperQuest quest, LeagueRegion... regions) + { + QUEST_REGIONS.put(quest, EnumSet.of(regions[0], regions)); + } + + public static boolean isCompletableWith(QuestHelperQuest quest, EnumSet playerRegions) + { + EnumSet required = QUEST_REGIONS.get(quest); + if (required == null) + { + return false; + } + return playerRegions.containsAll(required); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueRegion.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueRegion.java new file mode 100644 index 0000000000..c010941725 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/LeagueRegion.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2026, Syrif + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.questinfo; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.gameval.SpriteID; + +/** + * Regions available in OSRS leagues. Area codes match param 1017 values from the game cache. + */ +@AllArgsConstructor +@Getter +public enum LeagueRegion +{ + MISTHALIN("Misthalin", 1, SpriteID.TrailblazerMapShields._0), + KARAMJA("Karamja", 2, SpriteID.TrailblazerMapShields._1), + ASGARNIA("Asgarnia", 3, SpriteID.TrailblazerMapShields._2), + KANDARIN("Kandarin", 4, SpriteID.TrailblazerMapShields._6), + MORYTANIA("Morytania", 5, SpriteID.TrailblazerMapShields._4), + DESERT("Desert", 6, SpriteID.TrailblazerMapShields._3), + TIRANNWN("Tirannwn", 7, SpriteID.TrailblazerMapShields._8), + FREMENNIK("Fremennik Province", 8, SpriteID.TrailblazerMapShields._7), + KOUREND("Kourend & Kebos", 10, SpriteID.League4MapShields01._9), + WILDERNESS("Wilderness", 11, SpriteID.TrailblazerMapShields._5), + VARLAMORE("Varlamore", 21, SpriteID.League5MapShields01._10); + + private final String displayName; + private final int areaCode; + private final int spriteId; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java index 6c18daca5b..597ab3a83b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestHelperQuest.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.microbot.questhelper.questinfo; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.ChartingHelper; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.ardougne.ArdougneEasy; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.ardougne.ArdougneElite; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.ardougne.ArdougneHard; @@ -70,7 +71,6 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.wilderness.WildernessElite; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.wilderness.WildernessHard; import net.runelite.client.plugins.microbot.questhelper.helpers.achievementdiaries.wilderness.WildernessMedium; -import net.runelite.client.plugins.microbot.questhelper.helpers.activities.charting.ChartingHelper; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.alfredgrimhandsbarcrawl.AlfredGrimhandsBarcrawl; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.barbariantraining.BarbarianTraining; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.curseoftheemptylord.CurseOfTheEmptyLord; @@ -88,10 +88,10 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.themagearenaii.TheMageArenaII; import net.runelite.client.plugins.microbot.questhelper.helpers.miniquests.valetotems.ValeTotems; import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.allneededitems.AllNeededItems; -import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.HerbRun; -import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.TreeRun; import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.knightswaves.KnightWaves; import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.strongholdofsecurity.StrongholdOfSecurity; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.HerbRun; +import net.runelite.client.plugins.microbot.questhelper.helpers.mischelpers.farmruns.TreeRun; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.akingdomdivided.AKingdomDivided; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.anightatthetheatre.ANightAtTheTheatre; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.animalmagnetism.AnimalMagnetism; @@ -246,10 +246,12 @@ import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thegreatbrainrobbery.TheGreatBrainRobbery; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thehandinthesand.TheHandInTheSand; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theheartofdarkness.TheHeartOfDarkness; +import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theidesofmilk.TheIdesOfMilk; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theknightssword.TheKnightsSword; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thelosttribe.TheLostTribe; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thepathofglouphrie.ThePathOfGlouphrie; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.thequeenofthieves.TheQueenOfThieves; +import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theredreef.TheRedReef; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.therestlessghost.TheRestlessGhost; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theribbitingtaleofalilypadlabourdispute.TheRibbitingTaleOfALilyPadLabourDispute; import net.runelite.client.plugins.microbot.questhelper.helpers.quests.theslugmenace.TheSlugMenace; @@ -303,6 +305,7 @@ public enum QuestHelperQuest ERNEST_THE_CHICKEN(new ErnestTheChicken(), Quest.ERNEST_THE_CHICKEN, QuestVarPlayer.QUEST_ERNEST_THE_CHICKEN, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), GOBLIN_DIPLOMACY(new GoblinDiplomacy(), Quest.GOBLIN_DIPLOMACY, QuestVarbits.QUEST_GOBLIN_DIPLOMACY, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), IMP_CATCHER(new ImpCatcher(), Quest.IMP_CATCHER, QuestVarPlayer.QUEST_IMP_CATCHER, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), + THE_IDES_OF_MILK(new TheIdesOfMilk(), Quest.THE_IDES_OF_MILK, QuestVarbits.QUEST_THE_IDES_OF_MILK, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), THE_KNIGHTS_SWORD(new TheKnightsSword(), Quest.THE_KNIGHTS_SWORD, QuestVarPlayer.QUEST_THE_KNIGHTS_SWORD, QuestDetails.Type.F2P, QuestDetails.Difficulty.INTERMEDIATE), MISTHALIN_MYSTERY(new MisthalinMystery(), Quest.MISTHALIN_MYSTERY, QuestVarbits.QUEST_MISTHALIN_MYSTERY, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), PIRATES_TREASURE(new PiratesTreasure(), Quest.PIRATES_TREASURE, QuestVarPlayer.QUEST_PIRATES_TREASURE, QuestDetails.Type.F2P, QuestDetails.Difficulty.NOVICE), @@ -482,6 +485,7 @@ public enum QuestHelperQuest PRYING_TIMES(new PryingTimes(), Quest.PRYING_TIMES, QuestVarbits.QUEST_PRYING_TIMES, QuestDetails.Type.P2P, QuestDetails.Difficulty.INTERMEDIATE), CURRENT_AFFAIRS(new CurrentAffairs(), Quest.CURRENT_AFFAIRS, QuestVarbits.QUEST_CURRENT_AFFAIRS, QuestDetails.Type.P2P, QuestDetails.Difficulty.NOVICE), TROUBLED_TORTUGANS(new TroubledTortugans(), Quest.TROUBLED_TORTUGANS, QuestVarbits.QUEST_TROUBLED_TORTUGANS, QuestDetails.Type.P2P, QuestDetails.Difficulty.EXPERIENCED), + THE_RED_REEF(new TheRedReef(), Quest.THE_RED_REEF, QuestVarbits.QUEST_THE_RED_REEF, QuestDetails.Type.P2P, QuestDetails.Difficulty.EXPERIENCED), //Miniquests ENTER_THE_ABYSS(new EnterTheAbyss(), Quest.ENTER_THE_ABYSS, QuestVarPlayer.QUEST_ENTER_THE_ABYSS, QuestDetails.Type.MINIQUEST, QuestDetails.Difficulty.MINIQUEST), BEAR_YOUR_SOUL(new BearYourSoul(), Quest.BEAR_YOUR_SOUL, QuestVarbits.QUEST_BEAR_YOUR_SOUL, QuestDetails.Type.MINIQUEST, QuestDetails.Difficulty.MINIQUEST), @@ -657,7 +661,6 @@ public enum QuestHelperQuest WOODCUTTING(new Woodcutting(), "Woodcutting", Skill.WOODCUTTING, 99, QuestDetails.Type.SKILL_F2P, QuestDetails.Difficulty.SKILL), MINING(new Mining(), "Mining", Skill.MINING, 99, QuestDetails.Type.SKILL_F2P, QuestDetails.Difficulty.SKILL), - // Player Quests BIKE_SHEDDER(new BikeShedder(), "Bike Shedder", PlayerQuests.BIKE_SHEDDER, 4, true); @@ -675,9 +678,11 @@ public enum QuestHelperQuest @Getter private final QuestDetails.Difficulty difficulty; + @Getter private final QuestVarbits varbit; + @Getter private final QuestVarPlayer varPlayer; private Skill skill; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java index d6ce0c9536..e87cfd4340 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/questinfo/QuestVarbits.java @@ -18,6 +18,7 @@ public enum QuestVarbits QUEST_GOBLIN_DIPLOMACY(VarbitID.GOBDIP_MAIN), QUEST_MISTHALIN_MYSTERY(VarbitID.MISTMYST_PROGRESS), QUEST_THE_CORSAIR_CURSE(VarbitID.CORSCURS_PROGRESS), + QUEST_THE_IDES_OF_MILK(VarbitID.COWQUEST), QUEST_X_MARKS_THE_SPOT(VarbitID.CLUEQUEST), /** @@ -127,7 +128,8 @@ public enum QuestVarbits QUEST_PANDEMONIUM(VarbitID.SAILING_INTRO), QUEST_PRYING_TIMES(VarbitID.QUEST_PRY), QUEST_CURRENT_AFFAIRS(VarbitID.CURRENT_AFFAIRS), - QUEST_TROUBLED_TORTUGANS(VarbitID.TT), + QUEST_TROUBLED_TORTUGANS(VarbitID.TT), + QUEST_THE_RED_REEF(VarbitID.TRR), /** * mini-quest varbits, these don't hold the completion value. */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java index b1f02da01f..e4480df65e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/AbstractRequirement.java @@ -24,8 +24,8 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements; -import net.runelite.api.Client; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.api.Client; import net.runelite.client.ui.overlay.components.LineComponent; import javax.annotation.Nonnull; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java index 7bef5083ec..1f15f19c2e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/ChatMessageRequirement.java @@ -26,11 +26,11 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ConditionForStep; import lombok.Setter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.events.ChatMessage; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.ConditionForStep; import java.util.Arrays; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java index 343a8b16c8..0384ec8631 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/Requirement.java @@ -26,9 +26,9 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements; +import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.api.Client; import net.runelite.client.config.ConfigManager; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.ui.overlay.components.LineComponent; import javax.annotation.Nonnull; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java index a8d6dbc232..cea3370279 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/StepIsActiveRequirement.java @@ -26,7 +26,7 @@ import net.runelite.client.plugins.microbot.questhelper.steps.DetailedQuestStep; import net.runelite.api.Client; -import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; public class StepIsActiveRequirement extends AbstractRequirement { @@ -43,7 +43,7 @@ public boolean check(Client client) return questStep.isStarted(); } - @NotNull + @Nonnull @Override public String getDisplayText() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java index cb767e0181..ac054d69b0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ConditionForStep.java @@ -40,6 +40,7 @@ public abstract class ConditionForStep implements InitializableRequirement @Getter protected boolean hasPassed; protected boolean onlyNeedToPassOnce; + @Getter protected LogicType logicType; @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java index 2931517683..9faf5edac8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/Conditions.java @@ -36,6 +36,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Set; public class Conditions extends ConditionForStep { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java index 2117c649a1..edf7ff1d66 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/conditional/ObjectCondition.java @@ -24,13 +24,13 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.conditional; +import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import lombok.Setter; import net.runelite.api.Client; import net.runelite.api.GameObject; import net.runelite.api.Tile; import net.runelite.api.TileObject; import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; import java.util.Objects; import java.util.Set; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java index 0c6e999b09..4885ee8542 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirement.java @@ -43,13 +43,13 @@ import net.runelite.api.Item; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.util.Text; -import org.jetbrains.annotations.Nullable; +import javax.annotation.Nullable; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -93,7 +93,6 @@ public class ItemRequirement extends AbstractRequirement * Indicates whether the item must be equipped. */ @Setter - @Getter protected boolean mustBeEquipped; public boolean mustBeEquipped() { @@ -647,11 +646,11 @@ public void setAdditionalOptions(Requirement additionalOptions) public String getWikiUrl() { if (getUrlSuffix() != null) { - return "https://oldschool.runescape.wiki/w/" + getUrlSuffix(); + return "https://oldschool.runescape.wiki/w/" + getUrlSuffix() + "#Item_sources"; } if (getId() != -1) { - return "https://oldschool.runescape.wiki/w/Special:Lookup?type=item&id=" + getId(); + return "https://oldschool.runescape.wiki/w/Special:Lookup?type=item&id=" + getId() + "#Item_sources"; } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java index 6b7c039a10..8ff3696cfe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/ItemRequirements.java @@ -36,8 +36,8 @@ import net.runelite.api.Item; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java index 0326f47b07..7b0567b28d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/KeyringRequirement.java @@ -24,115 +24,26 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.item; -import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.collections.KeyringCollection; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.gameval.ItemID; -import net.runelite.client.config.ConfigManager; -import java.awt.*; -import java.util.Set; - -// TODO: Convert this to be a TrackedContainer instead? +/// A requirement of a key that can be found on a key ring. +/// +/// This requirement helps the bank tag service show the keyring if the key can be found in the player's key ring. public class KeyringRequirement extends ItemRequirement { - RuneliteRequirement runeliteRequirement; - @Getter KeyringCollection keyringCollection; - ConfigManager configManager; - - ItemRequirement keyring; - - public KeyringRequirement(String name, ConfigManager configManager, KeyringCollection key) + public KeyringRequirement(String name, KeyringCollection key) { super(name, key.getItemID()); - keyring = new ItemRequirement("Steel key ring", ItemID.FAVOUR_KEY_RING); - runeliteRequirement = new RuneliteRequirement(configManager, key.runeliteName(), - "true", key.toChatText()); this.keyringCollection = key; - this.configManager = configManager; - } - - public KeyringRequirement(ConfigManager configManager, KeyringCollection key) - { - super(key.toChatText(), key.getItemID()); - keyring = new ItemRequirement("Steel key ring", ItemID.FAVOUR_KEY_RING); - runeliteRequirement = new RuneliteRequirement(configManager, key.runeliteName(), - "true", key.toChatText()); - this.keyringCollection = key; - this.configManager = configManager; - } - - public String chatboxText() - { - return keyringCollection.toChatText(); - } - - public void setConfigValue(String value) - { - runeliteRequirement.setConfigValue(value); - } - - @Override - public ItemRequirement copy() - { - KeyringRequirement newItem = new KeyringRequirement(getName(), configManager, keyringCollection); - newItem.addAlternates(alternateItems); - newItem.setDisplayItemId(getDisplayItemId()); - newItem.setHighlightInInventory(highlightInInventory); - newItem.setDisplayMatchedItemName(isDisplayMatchedItemName()); - newItem.setConditionToHide(getConditionToHide()); - newItem.setShouldCheckBank(isShouldCheckBank()); - newItem.setTooltip(getTooltip()); - newItem.setUrlSuffix(getUrlSuffix()); - - return newItem; - } - - @Override - public boolean check(Client client) - {; - if (hasKeyOnKeyRing() && keyring.check(client)) - { - return true; - } - - return super.check(client); - } - - public boolean hasKeyOnKeyRing() - { - return runeliteRequirement.check(); - } - - @Override - public Color getColor(Client client, QuestHelperConfig config) - { - if (hasKeyOnKeyRing()) - { - return keyring.getColor(client, config); - } - - return this.check(client) ? config.passColour() : config.failColour(); - } - - protected String getTooltipFromEnumSet(Set containers) - { - String basicTooltip = super.getTooltipFromEnumSet(containers); - if (hasKeyOnKeyRing()) - { - return basicTooltip + " on your key ring."; - } - return basicTooltip; } @Override protected KeyringRequirement copyOfClass() { - return new KeyringRequirement(getName(), configManager, keyringCollection); + return new KeyringRequirement(getName(), keyringCollection); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java index aefce2c64b..21abbb41d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/item/TrackedContainers.java @@ -32,5 +32,6 @@ public enum TrackedContainers POTION_STORAGE, GROUP_STORAGE, RUNE_POUCH, + KEY_RING, UNDEFINED } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java index 97f66bb017..d27e7602f7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/DialogRequirement.java @@ -29,6 +29,7 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.events.ChatMessage; +import net.runelite.api.gameval.InterfaceID; import net.runelite.client.util.Text; import java.util.ArrayList; @@ -40,16 +41,23 @@ public class DialogRequirement extends SimpleRequirement @Setter String talkerName; final List text = new ArrayList<>(); - final boolean mustBeActive; + + @Setter + boolean mustBeActive; boolean hasSeenDialog = false; + /// Also allow the dialog message to check MESBOX messages + @Setter + boolean allowMesbox = false; + public DialogRequirement(String... text) { this.talkerName = null; this.text.addAll(Arrays.asList(text)); this.mustBeActive = false; } + public DialogRequirement(String talkerName, String text, boolean mustBeActive) { this.talkerName = talkerName; @@ -75,9 +83,35 @@ public boolean check(Client client) return hasSeenDialog; } + public void validateActiveWidget(Client client) + { + if (!mustBeActive) return; + + var chatModal = client.getWidget(InterfaceID.Chatbox.CHATMODAL); + + if (chatModal == null || chatModal.isHidden()) + { + hasSeenDialog = false; + } + } + public void validateCondition(ChatMessage chatMessage) { - if (chatMessage.getType() != ChatMessageType.DIALOG) return; + if (chatMessage.getType() != ChatMessageType.DIALOG) + { + if (allowMesbox) + { + // This requirement also allows validating the condition against MESBOX entries + if (chatMessage.getType() != ChatMessageType.MESBOX) + { + return; + } + } + else + { + return; + } + } String dialogMessage = chatMessage.getMessage(); if (!hasSeenDialog) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java index 5538b4c324..c1dace149c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NoFollowerRequirement.java @@ -27,11 +27,10 @@ package net.runelite.client.plugins.microbot.questhelper.requirements.npc; import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; +import javax.annotation.Nonnull; import net.runelite.api.Client; import net.runelite.api.gameval.VarPlayerID; -import javax.annotation.Nonnull; - public class NoFollowerRequirement extends AbstractRequirement { String text; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java index 8ccdf7e21b..1e6efe0a98 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/npc/NpcRequirement.java @@ -131,7 +131,13 @@ public NpcRequirement(int npcID, String npcName) @Override public boolean check(Client client) { - List found = client.getTopLevelWorldView().npcs().stream() + var localPlayer = client.getLocalPlayer(); + if (localPlayer == null) + { + return false; + } + + List found = localPlayer.getWorldView().npcs().stream() .filter(npc -> npc.getId() == npcID || npc.getComposition().getId() == npcID) .filter(npc -> npcName == null || (npc.getName() != null && npc.getName().equals(npcName))) .collect(Collectors.toList()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java index f4f56b6e00..1eff7f8781 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/Boosts.java @@ -38,11 +38,11 @@ public enum Boosts DEFENCE("Defence",21), FARMING("Farming",3), FIREMAKING("Firemaking",1), - FISHING("Fishing",5), + FISHING("Fishing",6), FLETCHING("Fletching",4), HERBLORE("Herblore",4), HITPOINTS("Hitpoints",22), - HUNTER("Hunter",3), + HUNTER("Hunter",6), MAGIC("Magic",19), MINING("Mining",3), PRAYER("Prayer",0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java index 79d1b132f3..f5dc54956a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreeInventorySlotRequirement.java @@ -36,6 +36,7 @@ import net.runelite.api.gameval.InventoryID; import javax.annotation.Nonnull; +import java.util.Locale; /** * Requirement that checks if a player has a required number of slots free in a given diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java index 9340e324b9..4fa1229998 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/FreePortTaskSlotsRequirement.java @@ -27,12 +27,13 @@ package net.runelite.client.plugins.microbot.questhelper.requirements.player; import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; -import lombok.Getter; import net.runelite.api.Client; -import net.runelite.api.gameval.VarbitID; import javax.annotation.Nonnull; +import lombok.Getter; +import net.runelite.api.gameval.VarbitID; + /** * Requirement that checks if a player has a required number of Port Task slots free. */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java index 3fd9c19176..5853612f55 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/player/ShipInPortRequirement.java @@ -28,11 +28,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.util.Port; -import lombok.Getter; import net.runelite.api.Client; -import net.runelite.api.gameval.VarbitID; import javax.annotation.Nonnull; + +import lombok.Getter; +import net.runelite.api.gameval.VarbitID; import java.util.stream.IntStream; /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java index 5ec4ff4261..c12783702f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/sailing/HasBoatResistanceRequirement.java @@ -24,10 +24,10 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.sailing; +import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.gameval.VarbitID; -import net.runelite.client.plugins.microbot.questhelper.requirements.AbstractRequirement; import javax.annotation.Nonnull; import java.util.Objects; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java index 3de13dd104..a83d855c33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/InventorySlots.java @@ -27,9 +27,9 @@ package net.runelite.client.plugins.microbot.questhelper.requirements.util; import net.runelite.api.Client; +import net.runelite.api.gameval.InventoryID; import net.runelite.api.Item; import net.runelite.api.ItemContainer; -import net.runelite.api.gameval.InventoryID; import java.util.Arrays; import java.util.Objects; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java index e693900f06..f6fc9481bf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/ItemSlots.java @@ -26,6 +26,8 @@ */ package net.runelite.client.plugins.microbot.questhelper.requirements.util; +import java.util.ArrayList; +import java.util.List; import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.Item; @@ -38,34 +40,38 @@ @Getter public enum ItemSlots { - ANY_EQUIPPED_AND_INVENTORY(-3, "inventory or equipped", InventorySlots.EQUIPMENT_AND_INVENTORY_SLOTS), - ANY_INVENTORY(-2, "inventory slots", InventorySlots.INVENTORY_SLOTS), - ANY_EQUIPPED(-1, "equipped slots", InventorySlots.EQUIPMENT_SLOTS), - HEAD(0, "head slot"), - CAPE(1, "cape slot"), - AMULET(2, "amulet slot"), - WEAPON(3, "weapon slot"), - BODY(4, "body slot"), - SHIELD(5, "shield slot"), - LEGS(7, "legs slot"), - GLOVES(9, "gloves slot"), - BOOTS(10, "boots slot"), - RING(12, "ring slot"), - AMMO(13, "ammo slot"); + ANY_EQUIPPED_AND_INVENTORY("inventory or equipped", InventorySlots.EQUIPMENT_AND_INVENTORY_SLOTS, -3), + ANY_INVENTORY("inventory slots", InventorySlots.INVENTORY_SLOTS, -2), + ANY_EQUIPPED("equipped slots", InventorySlots.EQUIPMENT_SLOTS, -1), - private final int slotIdx; + EMPTY_HANDS("weapons and shield slot", 3, 5), + BARE_HANDS("weapon, shield and gloves slot", 3, 5, 9), + + HEAD("head slot", 0), + CAPE("cape slot", 1), + AMULET("amulet slot", 2), + WEAPON("weapon slot", 3), + BODY("body slot", 4), + SHIELD("shield slot", 5), + LEGS("legs slot", 7), + GLOVES("gloves slot", 9), + BOOTS("boots slot", 10), + RING("ring slot", 12), + AMMO("ammo slot", 13); + + private final int[] slotIdxs; private final String name; private final InventorySlots inventorySlots; - ItemSlots(int slotIdx, String name) + ItemSlots(String name, int... slotIdx) { - this.slotIdx = slotIdx; + this.slotIdxs = slotIdx; this.name = name; this.inventorySlots = null; } - ItemSlots(int slotIdx, String name, InventorySlots slots) + ItemSlots(String name, InventorySlots slots, int... slotIdx) { - this.slotIdx = slotIdx; + this.slotIdxs = slotIdx; this.name = name; this.inventorySlots = slots; } @@ -90,14 +96,7 @@ public boolean checkInventory(Client client, Predicate predicate) { return false; } - ItemContainer equipment = client.getItemContainer(InventoryID.WORN); - if (equipment == null || getSlotIdx() < 0) // unknown slot - { - return false; - } - Item item = equipment.getItem(getSlotIdx()); - - return predicate.test(item); + return getItems(client).allMatch(predicate); } /** @@ -120,17 +119,21 @@ public boolean contains(Client client, Predicate predicate) { return false; } + return getItems(client).anyMatch(predicate); + } + + private Stream getItems(Client client){ ItemContainer equipment = client.getItemContainer(InventoryID.WORN); - if (equipment == null || getSlotIdx() < 0) // unknown slot - { - return false; - } - Item item = equipment.getItem(getSlotIdx()); - if (item == null) + + List items = new ArrayList<>(); + for(int slotIdx: getSlotIdxs()) { - return false; + if (equipment == null || slotIdx < 0) // unknown slot + { + continue; + } + items.add(equipment.getItem(slotIdx)); } - - return predicate.test(item); + return items.stream(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java index b6ec18cdea..6284c137c2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/util/Port.java @@ -36,37 +36,37 @@ @Getter public enum Port { - PORT_SARIM(0, "Port Sarim", ObjectID.SAILING_DOCKING_BUOY_PORT_SARIM, new WorldPoint(3048, 3186, 0), new Zone(new WorldPoint(3045, 3183, 0), new WorldPoint(3061, 3208, 0)), new WorldPoint(3051, 3193, 0), new WorldPoint(3028, 3194, 0), ObjectID.PORT_TASK_BOARD_PORT_SARIM, new WorldPoint(3030, 3197, 0)) - , PANDEMONIUM(1, "the Pandemonium", ObjectID.SAILING_DOCKING_BUOY_THE_PANDEMONIUM, new WorldPoint(3069, 2981, 0), new Zone(new WorldPoint(3065, 2974, 0), new WorldPoint(3084, 2998, 0)), new WorldPoint(3070, 2987, 0), new WorldPoint(3061,2985, 0), ObjectID.PORT_TASK_BOARD_PANDEMONIUM, new WorldPoint(3058, 2958, 0)) -// , LANDS_END(2, "Land's End", ObjectID.SAILING_DOCKING_BUOY_LANDS_END, null, null, null, null, ObjectID.PORT_TASK_BOARD_LANDS_END, null) - , MUSA_POINT(3, "Musa Point", ObjectID.SAILING_DOCKING_BUOY_MUSA_POINT, new WorldPoint(2961, 3152, 0), new Zone(new WorldPoint(2974, 3156, 0), new WorldPoint(2956, 3144, 0)), new WorldPoint(2961, 3146, 0), new WorldPoint(2952, 3150, 0), ObjectID.PORT_TASK_BOARD_MUSA_POINT, new WorldPoint(2956, 3144, 0)) -// , HOSIDIUS(4, "Hosidius", ObjectID.SAILING_DOCKING_BUOY_HOSIDIUS, null, null, null, null, -1, null) -// , PORT_PISCARILIUS(-1, "Port Piscarilius", ObjectID.SAILING_DOCKING_BUOY_PORT_PISCARILIUS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_PISCARILIUS, null) -// , RIMMINGTON(-1, "Rimmington", ObjectID.SAILING_DOCKING_BUOY_RIMMINGTON, null, null, null, null, -1, null) - , CATHERBY(6, "Catherby", ObjectID.SAILING_DOCKING_BUOY_CATHERBY, new WorldPoint(2788, 3409, 0), new Zone(new WorldPoint(2804, 3401, 0), new WorldPoint(2786, 3413, 0)), new WorldPoint(2796, 3412, 0), new WorldPoint(2799, 3413, 0), ObjectID.PORT_TASK_BOARD_CATHERBY, new WorldPoint(2803, 3418, 0)) -// , BRIMHAVEN(-1, "Brimhaven", ObjectID.SAILING_DOCKING_BUOY_BRIMHAVEN, null, null, null, null, ObjectID.PORT_TASK_BOARD_BRIMHAVEN, null) -// , ARDOUGNE(-1, "Ardougne", ObjectID.SAILING_DOCKING_BUOY_ARDOUGNE, null, null, null, null, ObjectID.PORT_TASK_BOARD_ARDOUGNE, null) -// , PORT_KHAZARD(-1, "Port Khazard", ObjectID.SAILING_DOCKING_BUOY_PORT_KHAZARD, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_KHAZARD, null) -// , WITCHAVEN(-1, "Witchaven", ObjectID.SAILING_DOCKING_BUOY_WITCHAVEN, null, null, null, null, -1, null) -// , ENTRANA(-1, "Entrana", ObjectID.SAILING_DOCKING_BUOY_ENTRANA, null, null, null, null, -1, null) -// , CIVITAS_ILLA_FORTIS(-1, "Civitas illa Fortis", ObjectID.SAILING_DOCKING_BUOY_CIVITAS_ILLA_FORTIS, null, null, null, null, ObjectID.PORT_TASK_BOARD_CIVITAS_ILLA_FORTIS, null) -// , CORSAIR_COVE(-1, "Corsair Cove", ObjectID.SAILING_DOCKING_BUOY_CORSAIR_COVE, null, null, null, null, ObjectID.PORT_TASK_BOARD_CORSAIR_COVE, null) -// , CAIRN_ISLE(-1, "Cairn Isle", ObjectID.SAILING_DOCKING_BUOY_CAIRN_ISLE, null, null, null, null, -1, null) -// , THE_SUMMER_SHORE(-1, "the Summer Shore", ObjectID.SAILING_DOCKING_BUOY_THE_SUMMER_SHORE, null, null, null, null, ObjectID.PORT_TASK_BOARD_THE_SUMMER_SHORE, null) -// , ALDARIN(-1, "Aldarin", ObjectID.SAILING_DOCKING_BUOY_ALDARIN, null, null, null, null, ObjectID.PORT_TASK_BOARD_ALDARIN, null) -// , RUINS_OF_UNKAH(-1, "Ruins of Unkah", ObjectID.SAILING_DOCKING_BUOY_RUINS_OF_UNKAH, null, null, null, null, ObjectID.PORT_TASK_BOARD_RUINS_OF_UNKAH, null) -// , VOID_KNIGHTS_OUTPOST(-1, "Void Knights Outpost", ObjectID.SAILING_DOCKING_BUOY_VOID_KNIGHTS_OUTPOST, null, null, null, null, ObjectID.PORT_TASK_BOARD_VOID_KNIGHTS_OUTPOST, null) -// , PORT_ROBERTS(-1, "Port Roberts", ObjectID.SAILING_DOCKING_BUOY_PORT_ROBERTS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_ROBERTS, null) -// , RELLEKKA(-1, "Rellekka", ObjectID.SAILING_DOCKING_BUOY_RELLEKKA, null, null, null, null, ObjectID.PORT_TASK_BOARD_RELLEKKA, null) -// , ETCETERIA(-1, "Etceteria", ObjectID.SAILING_DOCKING_BUOY_ETCETERIA, null, null, null, null, ObjectID.PORT_TASK_BOARD_ETCETERIA, null) -// , PORT_TYRAS(-1, "Port Tyras", ObjectID.SAILING_DOCKING_BUOY_PORT_TYRAS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PORT_TYRAS, null) -// , DEEPFIN_POINT(-1, "Deepfin Point", ObjectID.SAILING_DOCKING_BUOY_DEEPFIN_POINT, null, null, null, null, ObjectID.PORT_TASK_BOARD_DEEPFIN_POINT, null) -// , JATIZSO(-1, "Jatizso", ObjectID.SAILING_DOCKING_BUOY_JATIZSO, null, null, null, null, -1, null) -// , NEITIZNOT(-1, "Neitiznot", ObjectID.SAILING_DOCKING_BUOY_NEITIZNOT, null, null, null, null, -1, null) -// , PRIFDDINAS(-1, "Prifddinas", ObjectID.SAILING_DOCKING_BUOY_PRIFDDINAS, null, null, null, null, ObjectID.PORT_TASK_BOARD_PRIFDDINAS, null) -// , PISCATORIS(-1, "Piscatoris", ObjectID.SAILING_DOCKING_BUOY_PISCATORIS, null, null, null, null, -1, null) -// , LUNAR_ISLE(-1, "Lunar Isle", ObjectID.SAILING_DOCKING_BUOY_LUNAR_ISLE, null, null, null, null, ObjectID.PORT_TASK_BOARD_LUNAR_ISLE, null) - ; + PORT_SARIM(0, "Port Sarim", ObjectID.SAILING_DOCKING_BUOY_PORT_SARIM, new WorldPoint(3048, 3186, 0), new Zone(new WorldPoint(3045, 3183, 0), new WorldPoint(3061, 3208, 0)), new WorldPoint(3051, 3193, 0), new WorldPoint(3028, 3194, 0), ObjectID.PORT_TASK_BOARD_PORT_SARIM, new WorldPoint(3030, 3197, 0)), + PANDEMONIUM(1, "the Pandemonium", ObjectID.SAILING_DOCKING_BUOY_THE_PANDEMONIUM, new WorldPoint(3069, 2981, 0), new Zone(new WorldPoint(3065, 2974, 0), new WorldPoint(3084, 2998, 0)), new WorldPoint(3070, 2987, 0), new WorldPoint(3061,2985, 0), ObjectID.PORT_TASK_BOARD_PANDEMONIUM, new WorldPoint(3058, 2958, 0)), + LANDS_END(2, "Land's End", ObjectID.SAILING_DOCKING_BUOY_LANDS_END, new WorldPoint(1515, 3405, 0), new Zone( new WorldPoint(1520, 3408, 0), new WorldPoint(1507, 3393, 0)), new WorldPoint(1507, 3403, 0), new WorldPoint(1506, 3407, 0), ObjectID.PORT_TASK_BOARD_LANDS_END, new WorldPoint(1502, 3407, 0)), + MUSA_POINT(3, "Musa Point", ObjectID.SAILING_DOCKING_BUOY_MUSA_POINT, new WorldPoint(2961, 3152, 0), new Zone(new WorldPoint(2974, 3156, 0), new WorldPoint(2956, 3144, 0)), new WorldPoint(2961, 3146, 0), new WorldPoint(2952, 3150, 0), ObjectID.PORT_TASK_BOARD_MUSA_POINT, new WorldPoint(2956, 3144, 0)), + HOSIDIUS(4, "Hosidius", ObjectID.SAILING_DOCKING_BUOY_HOSIDIUS, new WorldPoint(1719, 3450, 0), null, new WorldPoint(1726, 3452, 0), new WorldPoint(1725, 3460, 0), -1, null), + PORT_PISCARILIUS(-1, "Port Piscarilius", ObjectID.SAILING_DOCKING_BUOY_PORT_PISCARILIUS, new WorldPoint(1840, 3681, 0), new Zone( new WorldPoint(1854, 3686, 0), new WorldPoint(1836, 3674, 0)), new WorldPoint(1845, 3687, 0), new WorldPoint(1837, 3691, 0), ObjectID.PORT_TASK_BOARD_PORT_PISCARILIUS, new WorldPoint(1839, 3691, 0)), + RIMMINGTON(-1, "Rimmington", ObjectID.SAILING_DOCKING_BUOY_RIMMINGTON, new WorldPoint(2908, 3216, 0), null, new WorldPoint(3906, 3225, 0), null, -1, null), + CATHERBY(6, "Catherby", ObjectID.SAILING_DOCKING_BUOY_CATHERBY, new WorldPoint(2788, 3409, 0), new Zone(new WorldPoint(2804, 3401, 0), new WorldPoint(2786, 3413, 0)), new WorldPoint(2796, 3412, 0), new WorldPoint(2799, 3413, 0), ObjectID.PORT_TASK_BOARD_CATHERBY, new WorldPoint(2803, 3418, 0)), + BRIMHAVEN(-1, "Brimhaven", ObjectID.SAILING_DOCKING_BUOY_BRIMHAVEN, new WorldPoint(2755, 3223, 0), new Zone( new WorldPoint(2746, 3219, 0), new WorldPoint(2758, 3239, 0)), new WorldPoint(2758, 3230, 0), new WorldPoint(2769, 3225, 0), ObjectID.PORT_TASK_BOARD_BRIMHAVEN, new WorldPoint(2764, 3227, 0)), + ARDOUGNE(-1, "Ardougne", ObjectID.SAILING_DOCKING_BUOY_ARDOUGNE, new WorldPoint(2663, 3261, 0), null, new WorldPoint(2671, 3265, 0), new WorldPoint(2674, 3269, 0), ObjectID.PORT_TASK_BOARD_ARDOUGNE, new WorldPoint(2676, 3276, 0)), + PORT_KHAZARD(-1, "Port Khazard", ObjectID.SAILING_DOCKING_BUOY_PORT_KHAZARD, new WorldPoint(2663, 3261, 0), new Zone( new WorldPoint(2694, 3171, 0), new WorldPoint(2682, 3153, 0)), new WorldPoint(2686, 3162, 0), new WorldPoint(2684, 3164, 0), ObjectID.PORT_TASK_BOARD_PORT_KHAZARD, new WorldPoint(2678, 3162, 0)), + WITCHAVEN(-1, "Witchaven", ObjectID.SAILING_DOCKING_BUOY_WITCHAVEN, new WorldPoint(2746, 3297, 0), new Zone( new WorldPoint(2759, 3312, 0), new WorldPoint(2741, 3294, 0)), new WorldPoint(2747, 3305, 0), null, -1, null), + ENTRANA(-1, "Entrana", ObjectID.SAILING_DOCKING_BUOY_ENTRANA, new WorldPoint(2880, 3330, 0), new Zone( new WorldPoint(2874, 3322, 0), new WorldPoint(2892, 3340, 0)), new WorldPoint(2879, 3336, 0), new WorldPoint(2874, 3339, 0), -1, null), + CIVITAS_ILLA_FORTIS(-1, "Civitas illa Fortis", ObjectID.SAILING_DOCKING_BUOY_CIVITAS_ILLA_FORTIS, new WorldPoint(1768, 3147, 0), new Zone( new WorldPoint(1764, 3129, 0), new WorldPoint(1774, 3149, 0)), new WorldPoint(1775, 3142, 0), new WorldPoint(1781, 3147, 0), ObjectID.PORT_TASK_BOARD_CIVITAS_ILLA_FORTIS, new WorldPoint(1782, 3142, 0)), + CORSAIR_COVE(-1, "Corsair Cove", ObjectID.SAILING_DOCKING_BUOY_CORSAIR_COVE, new WorldPoint(2585, 3847, 0), new Zone( new WorldPoint(2581, 2834, 0), new WorldPoint(2593, 2847, 0)), new WorldPoint(2580, 2844, 0), new WorldPoint(2581, 2848, 0), ObjectID.PORT_TASK_BOARD_CORSAIR_COVE, new WorldPoint(2579, 2853, 0)), + CAIRN_ISLE(-1, "Cairn Isle", ObjectID.SAILING_DOCKING_BUOY_CAIRN_ISLE, new WorldPoint(2748, 2944, 0), null, new WorldPoint(2750, 2952, 0), new WorldPoint(2756, 2949, 0), -1, null), + SUNSET_COAST(-1, "the Sunset Coast", ObjectID.SAILING_DOCKING_BUOY_SUNSET_COAST, new WorldPoint(1505, 2977, 0), new Zone( new WorldPoint(1500, 2958, 0), new WorldPoint(1511, 2979, 0)), new WorldPoint(1512, 2974, 0), new WorldPoint(1515, 2977, 0), -1, null), + THE_SUMMER_SHORE(-1, "the Summer Shore", ObjectID.SAILING_DOCKING_BUOY_THE_SUMMER_SHORE, new WorldPoint(3168, 2364, 0), new Zone( new WorldPoint(3200, 2353, 0), new WorldPoint(3160, 2372, 0)), new WorldPoint(3174, 2367, 0), new WorldPoint(3173, 2370, 0), ObjectID.PORT_TASK_BOARD_THE_SUMMER_SHORE, new WorldPoint(3183, 2368, 0)), + ALDARIN(-1, "Aldarin", ObjectID.SAILING_DOCKING_BUOY_ALDARIN, new WorldPoint(1457, 2975, 0), new Zone( new WorldPoint(1444, 2970, 0), new WorldPoint(1461, 2984, 0)), new WorldPoint(1452, 2970, 0), new WorldPoint(1449, 2969, 0), ObjectID.PORT_TASK_BOARD_ALDARIN, new WorldPoint(1438, 2939, 0)), + RUINS_OF_UNKAH(-1, "Ruins of Unkah", ObjectID.SAILING_DOCKING_BUOY_RUINS_OF_UNKAH, new WorldPoint(3144, 2818, 0), new Zone( new WorldPoint(3136, 2813, 0), new WorldPoint(3146, 2831, 0)), new WorldPoint(3144, 2825, 0), new WorldPoint(3148, 2826, 0), ObjectID.PORT_TASK_BOARD_RUINS_OF_UNKAH, new WorldPoint(3146, 2828, 0)), + VOID_KNIGHTS_OUTPOST(-1, "Void Knights Outpost", ObjectID.SAILING_DOCKING_BUOY_VOID_KNIGHTS_OUTPOST, new WorldPoint(2643, 2678, 0), new Zone( new WorldPoint(2641, 2675, 0), new WorldPoint(2659, 2687, 0)), new WorldPoint(2651, 2678, 0), new WorldPoint(2652, 2673, 0), ObjectID.PORT_TASK_BOARD_VOID_KNIGHTS_OUTPOST, new WorldPoint(2659, 2672, 0)), + PORT_ROBERTS(-1, "Port Roberts", ObjectID.SAILING_DOCKING_BUOY_PORT_ROBERTS, new WorldPoint(1859, 3302, 0), new Zone( new WorldPoint(1850, 3297, 0), new WorldPoint(1862, 3317, 0)), new WorldPoint(1861, 3307, 0), new WorldPoint(1867, 3306, 0), ObjectID.PORT_TASK_BOARD_PORT_ROBERTS, new WorldPoint(1872, 3303, 0)), + RELLEKKA(-1, "Rellekka", ObjectID.SAILING_DOCKING_BUOY_RELLEKKA, new WorldPoint(2633, 3711, 0), new Zone( new WorldPoint(2624, 3704, 0), new WorldPoint(2636, 3716, 0)), new WorldPoint(2630, 3705, 0), new WorldPoint(2629, 3699, 0), ObjectID.PORT_TASK_BOARD_RELLEKKA, new WorldPoint(2629, 3685, 0)), + ETCETERIA(-1, "Etceteria", ObjectID.SAILING_DOCKING_BUOY_ETCETERIA, new WorldPoint(2618, 3836, 0), new Zone( new WorldPoint(2607, 3833, 0), new WorldPoint(2619, 3839, 0)), new WorldPoint(2613, 2840, 0), new WorldPoint(2612, 3846, 0), ObjectID.PORT_TASK_BOARD_ETCETERIA, new WorldPoint(2617, 3849, 0)), + PORT_TYRAS(-1, "Port Tyras", ObjectID.SAILING_DOCKING_BUOY_PORT_TYRAS, new WorldPoint(2149, 3117, 0), new Zone( new WorldPoint(2132, 3109, 0), new WorldPoint(2152, 3120, 0)), new WorldPoint(2144, 3120, 0), new WorldPoint(2151, 3123, 0), ObjectID.PORT_TASK_BOARD_PORT_TYRAS, new WorldPoint(2146, 3123, 0)), + DEEPFIN_POINT(-1, "Deepfin Point", ObjectID.SAILING_DOCKING_BUOY_DEEPFIN_POINT, new WorldPoint(1930, 2755, 0), new Zone( new WorldPoint(1935, 2743, 0), new WorldPoint(1914, 2759, 0)), new WorldPoint(1923, 2758, 0), new WorldPoint(1928, 2761, 0), ObjectID.PORT_TASK_BOARD_DEEPFIN_POINT, new WorldPoint(1931, 2761, 0)), + JATIZSO(-1, "Jatizso", ObjectID.SAILING_DOCKING_BUOY_JATIZSO, new WorldPoint(2405, 3776, 0), new Zone( new WorldPoint(2404, 3770, 0), new WorldPoint(2422, 3779, 0)), new WorldPoint(2412, 3780, 0), new WorldPoint(2401, 3788, 0), -1, null), + NEITIZNOT(-1, "Neitiznot", ObjectID.SAILING_DOCKING_BUOY_NEITIZNOT, new WorldPoint(2304, 3786, 0), new Zone( new WorldPoint(2298, 3771, 0), new WorldPoint(2307, 3789, 0)), new WorldPoint(2309, 3782, 0), new WorldPoint(2308, 3775, 0), -1, null), + PRIFDDINAS(-1, "Prifddinas", ObjectID.SAILING_DOCKING_BUOY_PRIFDDINAS, new WorldPoint(2165, 3321, 0), new Zone( new WorldPoint(2165, 3307, 0), new WorldPoint(2141, 3325, 0)), new WorldPoint(2158, 3324, 0), new WorldPoint(2170, 3328, 0), ObjectID.PORT_TASK_BOARD_PRIFDDINAS, new WorldPoint(2163, 3326, 0)), + PISCATORIS(-1, "Piscatoris", ObjectID.SAILING_DOCKING_BUOY_PISCATORIS, new WorldPoint(2304, 3696, 0), new Zone( new WorldPoint(2293, 3682, 0), new WorldPoint(2306, 3700, 0)), new WorldPoint(2304, 3689, 0), new WorldPoint(2313, 3693, 0), -1, null), + LUNAR_ISLE(-1, "Lunar Isle", ObjectID.SAILING_DOCKING_BUOY_LUNAR_ISLE, new WorldPoint(2154, 3886, 0), new Zone( new WorldPoint(2151, 3875, 0), new WorldPoint(2163, 3887, 0)), new WorldPoint(2152, 3881, 0), new WorldPoint(2146, 3879, 0), ObjectID.PORT_TASK_BOARD_LUNAR_ISLE, new WorldPoint(2139, 3884, 0));; private final int id; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java index 77aeda7457..ae6267d773 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/var/VarbitRequirement.java @@ -53,7 +53,8 @@ public class VarbitRequirement extends AbstractRequirement @Setter private int requiredValue; private final Operation operation; - private final String displayText; + @Setter + private String displayText; // bit positions private boolean bitIsSet = false; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java index c0e6e8fc09..bcd7013b59 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/requirements/zone/ZoneRequirement.java @@ -33,6 +33,8 @@ import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.Player; +import net.runelite.api.WorldEntity; +import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import javax.annotation.Nonnull; @@ -46,6 +48,13 @@ public class ZoneRequirement extends AbstractRequirement private final boolean checkInZone; private String displayText; + /// Contains the value of the most recent successful zone check. + /// null = no check has succeeded + /// true = the last check was deemed a success (check returned true) + /// false = the last check was deemed a failure (check returned false) + @Getter + private Boolean matchedZoneLastCheck = null; + /** * Check if the player is either in the specified zone. * @@ -107,7 +116,8 @@ public boolean check(Client client) if (player != null && zones != null) { boolean inZone = zones.stream().anyMatch(z -> z.contains(client, player.getLocalLocation())); - return inZone == checkInZone; + matchedZoneLastCheck = inZone == checkInZone; + return matchedZoneLastCheck; } return false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java index b1a1726aaa..a16a67e1fe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/Cheerer.java @@ -45,19 +45,16 @@ public class Cheerer public static void createCheerers(RuneliteObjectManager runeliteObjectManager, Client client, ConfigManager configManager) { cheerers.clear(); - if (client.getLocalPlayer() == null) - { - return; - } createWOM(runeliteObjectManager, client); createZoinkwiz(runeliteObjectManager, client); } private static void createWOM(RuneliteObjectManager runeliteObjectManager, Client client) { - WorldPoint playerPos = client.getLocalPlayer().getWorldLocation(); - WorldPoint pointAbovePlayer = new WorldPoint(playerPos.getX(), playerPos.getY() + 1, playerPos.getPlane()); - FakeNpc wiseOldMan = runeliteObjectManager.createFakeNpc("global", wiseOldManOutfit(client), pointAbovePlayer, 862); + // Spawn the initial NPC in lumbridge. + // When the NPC is activated from the player completing a quest, we will always update the position anyway. + var spawnPos = new WorldPoint(3223, 3218, 0); + FakeNpc wiseOldMan = runeliteObjectManager.createFakeNpc("global", wiseOldManOutfit(client), spawnPos, 862); wiseOldMan.setName("Wise Old Man"); wiseOldMan.setExamine("Loves questing."); wiseOldMan.addExamineAction(runeliteObjectManager); @@ -86,9 +83,10 @@ private static Model wiseOldManOutfit(Client client) private static void createZoinkwiz(RuneliteObjectManager runeliteObjectManager, Client client) { - WorldPoint playerPos = client.getLocalPlayer().getWorldLocation(); - WorldPoint pointAbovePlayer = new WorldPoint(playerPos.getX(), playerPos.getY() + 1, playerPos.getPlane()); - FakeNpc zoinkwiz = runeliteObjectManager.createFakeNpc("global", zoinkwizOutfit(client), pointAbovePlayer, 862); + // Spawn the initial NPC in lumbridge. + // When the NPC is activated from the player completing a quest, we will always update the position anyway. + var spawnPos = new WorldPoint(3223, 3218, 0); + FakeNpc zoinkwiz = runeliteObjectManager.createFakeNpc("global", zoinkwizOutfit(client), spawnPos, 862); zoinkwiz.setName("Zoinkwiz"); zoinkwiz.setExamine("Loves questing."); zoinkwiz.addExamineAction(runeliteObjectManager); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java index ef91ce9c5c..ed1ffbdc2d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/GlobalFakeObjects.java @@ -25,9 +25,18 @@ package net.runelite.client.plugins.microbot.questhelper.runeliteobjects; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import net.runelite.client.plugins.microbot.questhelper.questinfo.PlayerQuests; +import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.PlayerQuestStateRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.Operation; +import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.ReplacedNpc; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.RuneliteObjectManager; +import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.WidgetReplacement; +import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetDetails; import lombok.Setter; import net.runelite.api.Client; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.NpcID; import net.runelite.client.config.ConfigManager; public class GlobalFakeObjects diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java index 0e315b7445..2f940912e6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/ExtendedRuneliteObject.java @@ -45,8 +45,8 @@ import net.runelite.client.game.chatbox.ChatboxPanelManager; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java index 68e1af5f9f..e9d2200bdf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/runeliteobjects/extendedruneliteobjects/RuneliteObjectManager.java @@ -29,15 +29,15 @@ import com.google.inject.Singleton; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetDetails; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.*; import net.runelite.api.Menu; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.*; import net.runelite.api.gameval.InterfaceID; -import net.runelite.api.gameval.SpriteID; import net.runelite.api.widgets.Widget; +import net.runelite.api.gameval.SpriteID; import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.Hooks; import net.runelite.client.chat.ChatColorType; @@ -54,8 +54,8 @@ import java.awt.*; import java.awt.image.BufferedImage; -import java.util.*; import java.util.List; +import java.util.*; import java.util.function.Consumer; // This will hold all RuneliteObjects @@ -817,15 +817,18 @@ public void onGameTick(GameTick event) @Subscribe public void onClientTick(ClientTick event) { + var localPlayer = client.getLocalPlayer(); + + if (localPlayer == null) + { + return; + } + bufferRedClickAnimation = Math.floorMod(bufferRedClickAnimation + 1, ANIMATION_PERIOD); if (bufferRedClickAnimation == 0) { redClickAnimationFrame++; } - if (client.getLocalPlayer() == null) - { - return; - } WorldPoint playerPosition = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()); runeliteObjectGroups.forEach((groupID, extendedRuneliteObjectGroup) -> { for (ExtendedRuneliteObject extendedRuneliteObject : extendedRuneliteObjectGroup.extendedRuneliteObjects) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java index f14f066e13..588eb47c9c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/AchievementDiaryStepManager.java @@ -36,6 +36,7 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.NpcLootReceived; +import net.runelite.client.events.ServerNpcLoot; import javax.inject.Singleton; @@ -46,7 +47,7 @@ public class AchievementDiaryStepManager static Zone workshop; @Getter - static Requirement inWorkshop; + static ZoneRequirement inWorkshop; @Getter static RuneliteRequirement killedFire, killedEarth, killedWater, killedAir; @@ -68,7 +69,7 @@ private static void setupKandarin(ConfigManager configManager) public static void check(Client client) { - if (!inWorkshop.check(client)) + if (!Boolean.FALSE.equals(inWorkshop.getMatchedZoneLastCheck()) && !inWorkshop.check(client)) { killedFire.setConfigValue("false"); killedEarth.setConfigValue("false"); @@ -78,14 +79,27 @@ public static void check(Client client) } @Subscribe - public void onNpcLootReceived(final NpcLootReceived npcLootReceived) + public static void onServerNpcLoot(final ServerNpcLoot npcLootReceived) { - final NPC npc = npcLootReceived.getNpc(); + final var npc = npcLootReceived.getComposition(); - final int id = npc.getId(); - if (id == NpcID.ELEMENTAL_FIRE) killedFire.setConfigValue("true"); - if (id == NpcID.ELEMENTAL_EARTH) killedEarth.setConfigValue("true"); - if (id == NpcID.ELEMENTAL_WATER) killedWater.setConfigValue("true"); - if (id == NpcID.ELEMENTAL_AIR) killedAir.setConfigValue("true"); + switch (npc.getId()) + { + case NpcID.ELEMENTAL_FIRE: + killedFire.setConfigValue("true"); + break; + + case NpcID.ELEMENTAL_EARTH: + killedEarth.setConfigValue("true"); + break; + + case NpcID.ELEMENTAL_WATER: + killedWater.setConfigValue("true"); + break; + + case NpcID.ELEMENTAL_AIR: + killedAir.setConfigValue("true"); + break; + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/BarbarianTrainingStateTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/BarbarianTrainingStateTracker.java deleted file mode 100644 index f8820c6761..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/BarbarianTrainingStateTracker.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2024, Zoinkwiz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.microbot.questhelper.statemanagement; - -import net.runelite.client.plugins.microbot.questhelper.config.ConfigKeys; -import net.runelite.client.plugins.microbot.questhelper.requirements.*; -import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; -import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.runelite.RuneliteRequirement; -import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.requirements.widget.WidgetTextRequirement; -import net.runelite.api.Client; -import net.runelite.api.gameval.InterfaceID; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class BarbarianTrainingStateTracker -{ - @Inject - Client client; - - Requirement taskedWithFishing, taskedWithHarpooning, taskedWithFarming, taskedWithBowFiremaking, taskedWithPyre, taskedWithPotSmashing, - taskedWithSpears, taskedWithHastae, taskedWithHerblore, plantedSeed, smashedPot, litFireWithBow, sacrificedRemains, caughtBarbarianFish, - caughtFishWithoutHarpoon, madePotion, madeSpear, madeHasta, finishedFishing, finishedHarpoon, finishedSeedPlanting, finishedPotSmashing, - finishedFiremaking, finishedPyre, finishedSpear, finishedHasta, finishedHerblore; - - RequirementValidator reqs; - - - public void startUp(ConfigManager configManager, EventBus eventBus) - { - taskedWithFishing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Certainly. Take the rod from under my bed and fish in the lake. When you have caught a few fish, I am sure you will be ready to talk more with me."), - new DialogRequirement("Alas, I do not sense that you have been successful in your fishing yet. The look in your eyes is not that of the osprey."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with a new") - ) - ); - - taskedWithHarpooning = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("... and I thought fishing was a safe way to pass the time."), - new DialogRequirement("I see you need encouragement in learning the ways of fishing without a harpoon."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "fish with my") - ) - ); - - taskedWithFarming = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Remember to be calm, and good luck."), - new DialogRequirement("I see you have yet to be successful in planting a seed with your fists."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "plant a seed with") - ) - ); - - taskedWithPotSmashing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("May the spirits guide you into success."), - new DialogRequirement("You have not yet attempted to plant a tree. Why not?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smash pots after") - ) - ); - - taskedWithBowFiremaking = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The spirits will aid you. The power they supply will guide your hands. Go and benefit from their guidance upon oak logs."), - new DialogRequirement("By now you know my response."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "light a fire with") - ) - ); - - taskedWithPyre = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Dive into the whirlpool in the lake to the east. The spirits will use their abilities to ensure you arrive in the correct location. Be warned, their influence fades, so you must find y"), - new DialogRequirement("I will repeat myself fully, since this is quite complex. Listen well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to create pyre ships") - ) - ); - - taskedWithHerblore = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Have I become so predictable? But yes, I do indeed require a potion. It is of the highest importance that you bring me a lesser attack potion combined with fish roe."), - new DialogRequirement("Do you have my potion?"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to make a new type") - ) - ); - - taskedWithSpears = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Note well that you will require wood for the spear shafts. The quality of wood must be similar to that of the metal involved."), - new DialogRequirement("You do not exude the presence of one who has poured his soul into manufacturing spears."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "Otto has tasked me with learning how to smith spears") - ) - ); - - taskedWithHastae = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_STARTED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Indeed. You may use our special anvil for this spear type too. The ways of black and dragon hastae are beyond our knowledge, however."), - new DialogRequirement("Take some wood and metal and make a spear upon the
nearby anvil, then you may return to me. As an
example, you may use bronze bars with normal logs or
iron bars with oak logs."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, " has tasked me with learning how to smith a hasta") - ) - ); - - // Finished tasks - finishedFishing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_FISHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Patience young one. These are fish which are fat with eggs rather than fat of flesh. It is these eggs that are the thing to make use of."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to catch a fish with the new rod!") - ), - "Finished Barbarian Fishing" - ); - - finishedHarpoon = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_HARPOON.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I mean that when you eventually die and find peace, at least the spirits you encounter will be your friends. Alas for you adventurous sort, the natural ways of passing are close to imp"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to fish with my hands!") - ), - "Finished Barbarian Harpooning" - ); - - finishedSeedPlanting = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_SEED_PLANTING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("No child, but we all have potential to improve our strength."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to plant a seed with my fists!") - ), - "Finished Barbarian Seed Planting" - ); - - finishedPotSmashing = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_POT_SMASHING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("It will become more natural with practice."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smash a plant pot without littering!") - ), - "Finished Barbarian Pot Smashing" - ); - - finishedFiremaking = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_FIREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("Fine news indeed!"), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to light a fire with a bow!") - ), - "Finished Barbarian Firemaking" - ); - - finishedPyre = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_PYREMAKING.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("On this great day you have my eternal thanks. May you find riches while rescuing my spiritual ancestors in the caverns for many moons to come."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a pyre ship!") - ), - "Finished Barbarian Pyremaking" - ); - - finishedSpear = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("The manufacture of spears is now yours as a speciality. Use your skill well."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to smith a spear!") - ), - "Finished Barbarian Spear Smithing" - ); - - finishedHasta = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("To live life to it's fullest of course - that you may be a peaceful spirit when your time ends."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a hasta!") - ), - "Finished Barbarian Hasta Smithing" - ); - - finishedHerblore = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_FINISHED_HERBLORE.getKey(), - new Conditions(true, LogicType.OR, - new DialogRequirement("I will take that off your hands now. I will say no more than that I am eternally grateful."), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I managed to create a new potion!") - ), - "Finished Barbarian Herblore" - ); - - // Mid-conditions - plantedSeed = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_PLANTED_SEED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to plant a seed with my fists!") - ) - ); - - smashedPot = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_SMASHED_POT.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You plant "), - new ChatMessageRequirement(" sapling"), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smash a pot without littering!") - ) - ); - - litFireWithBow = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_BOW_FIRE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The fire catches and the logs begin to burn."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to light a fire with a bow!") - ) - ); - - sacrificedRemains = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_PYRE_MADE.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("The ancient barbarian is laid to rest."), - new ChatMessageRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to create a pyre ship! I should let") - ) - ); - - caughtBarbarianFish = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_BARBFISHED.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a leaping trout.", "You catch a leaping salmon.", "You catch a leaping sturgeon."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to catch a fish with the new rod! I should let") - ) - ); - - caughtFishWithoutHarpoon = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_HARPOONED_FISH.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You catch a raw tuna.", "You catch a swordfish.", "You catch a shark.", "You catch a shark!"), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to fish with my hands! I should let Otto know") - ) - ); - - madePotion = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_MADE_POTION.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You combine your potion with the fish eggs."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to make a new type of potion! I should let") - ) - ); - - madeSpear = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_MADE_SPEAR.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" spear."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a spear!") - ) - ); - - madeHasta = new RuneliteRequirement( - configManager, ConfigKeys.BARBARIAN_TRAINING_MADE_HASTA.getKey(), - new Conditions(true, LogicType.OR, - new MultiChatMessageRequirement( - new ChatMessageRequirement("You make a "), - new ChatMessageRequirement(" hasta."), - new MesBoxRequirement("You feel you have learned more of barbarian ways. Otto might wish to talk to you more.") - ), - new WidgetTextRequirement(InterfaceID.Questjournal.TEXTLAYER, true, "I've managed to smith a hasta!") - ) - ); - - - reqs = new RequirementValidator(client, eventBus, - taskedWithFishing, taskedWithHarpooning, taskedWithFarming, taskedWithBowFiremaking, taskedWithPyre, taskedWithPotSmashing, - taskedWithSpears, taskedWithHastae, taskedWithHerblore, plantedSeed, smashedPot, litFireWithBow, sacrificedRemains, caughtBarbarianFish, - caughtFishWithoutHarpoon, madePotion, madeSpear, madeHasta, finishedFishing, finishedHarpoon, finishedSeedPlanting, finishedPotSmashing, - finishedFiremaking, finishedPyre, finishedSpear, finishedHasta, finishedHerblore - ); - - eventBus.register(reqs); - reqs.startUp(); - } - - - public void shutDown(EventBus eventBus) - { - eventBus.unregister(reqs); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java index de991b8078..4844da0f1c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/statemanagement/PlayerStateManager.java @@ -26,12 +26,13 @@ import net.runelite.client.plugins.microbot.questhelper.collections.KeyringCollection; import net.runelite.client.plugins.microbot.questhelper.domain.AccountType; -import net.runelite.client.plugins.microbot.questhelper.requirements.item.KeyringRequirement; +import net.runelite.client.plugins.microbot.questhelper.managers.QuestContainerManager; import net.runelite.client.plugins.microbot.questhelper.runeliteobjects.extendedruneliteobjects.QuestCompletedWidget; import lombok.Getter; import lombok.NonNull; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.Item; import net.runelite.api.Player; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; @@ -39,36 +40,33 @@ import net.runelite.api.events.VarbitChanged; import net.runelite.api.gameval.VarbitID; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.EventBus; +import net.runelite.client.config.RuneScapeProfileType; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.plugins.microbot.util.player.Rs2Player; +import net.runelite.client.events.ServerNpcLoot; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.List; +import java.util.ArrayList; @Singleton public class PlayerStateManager { + private final KeyringCollection[] keyringKeys = KeyringCollection.values(); + @Inject Client client; @Inject ConfigManager configManager; - @Inject - EventBus eventBus; - @Inject QuestCompletedWidget playerQuestCompleteWidget; - @Inject - BarbarianTrainingStateTracker barbarianTrainingStateTracker; - - List keyringKeys; - WorldPoint lastPlayerPos = null; + private boolean loggedInStateKnown = false; + private RuneScapeProfileType worldType; + /** * The type of the logged in account (e.g. ironman, hardcore ironman) * Quest helpers should use this value when building their requirements instead of fetching the value themselves. @@ -78,42 +76,44 @@ public class PlayerStateManager public void startUp() { - keyringKeys = KeyringCollection.allKeyRequirements(configManager); AchievementDiaryStepManager.setup(configManager); - barbarianTrainingStateTracker.startUp(configManager, eventBus); } public void shutDown() { - barbarianTrainingStateTracker.shutDown(eventBus); } @Subscribe public void onChatMessage(ChatMessage chatMessage) { - if (keyringKeys == null || chatMessage.getType() != ChatMessageType.GAMEMESSAGE) return; + if (chatMessage.getType() != ChatMessageType.GAMEMESSAGE) return; if (chatMessage.getMessage().contains("to your key ring.")) { - for (KeyringRequirement keyringKey : keyringKeys) + for (var keyringKey : keyringKeys) { if (chatMessage.getMessage().contains("You add the " + keyringKey.chatboxText())) { - keyringKey.setConfigValue("true"); + keyringKey.setHasKeyOnKeyRing(configManager, true); + + QuestContainerManager.getKeyRingData().add(client.getTickCount(), keyringKey.getItemID(), 1); + break; } } } - if (chatMessage.getMessage().contains("from your key ring.")) + else if (chatMessage.getMessage().contains("from your key ring.")) { - for (KeyringRequirement keyringKey : keyringKeys) + for (var keyringKey : keyringKeys) { if (chatMessage.getMessage().contains("You remove the " + keyringKey.chatboxText())) { - keyringKey.setConfigValue("false"); + keyringKey.setHasKeyOnKeyRing(configManager, false); + + QuestContainerManager.getKeyRingData().removeByItemID(client.getTickCount(), keyringKey.getItemID()); + break; } } } - - if (chatMessage.getMessage().contains("Achievement Diary Stage Task - ")) + else if (chatMessage.getMessage().contains("Achievement Diary Stage Task - ")) { AchievementDiaryStepManager.check(client); } @@ -125,7 +125,7 @@ public void onGameTick(GameTick gameTick) Player player = client.getLocalPlayer(); if (player != null) { - WorldPoint newPos = Rs2Player.getWorldLocation(); + WorldPoint newPos = player.getWorldLocation(); if (newPos != null && lastPlayerPos != null) { if (newPos.distanceTo(lastPlayerPos) != 0) @@ -134,6 +134,8 @@ public void onGameTick(GameTick gameTick) } } lastPlayerPos = newPos; + + AchievementDiaryStepManager.check(client); } } @@ -160,4 +162,60 @@ public String getPlayerName() } return client.getLocalPlayer().getName(); } + + public void loadInitialStateFromConfig() + { + if (loggedInStateKnown) + { + return; + } + + var localPlayer = client.getLocalPlayer(); + if (localPlayer != null && localPlayer.getName() != null) + { + loggedInStateKnown = true; + loadState(); + } + } + + private void loadState() + { + // Only re-load from config if loading from a new profile + if (!RuneScapeProfileType.getCurrent(client).equals(worldType)) + { + // Load key ring state from config + loadKeyRingFromConfig(); + } + } + + private void loadKeyRingFromConfig() + { + var keys = new ArrayList(); + + for (var keyringKey : keyringKeys) + { + if (keyringKey.hasKeyOnKeyRing(configManager)) + { + keys.add(new Item(keyringKey.getItemID(), 1)); + } + } + + QuestContainerManager.getKeyRingData().update(client.getTickCount(), keys.toArray(new Item[0])); + } + + public void emptyState() + { + worldType = null; + } + + public void setUnknownInitialState() + { + loggedInStateKnown = false; + } + + @Subscribe + public void onServerNpcLoot(ServerNpcLoot event) + { + AchievementDiaryStepManager.onServerNpcLoot(event); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java index ef3e894728..c3b19d18ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/BoardShipStep.java @@ -8,7 +8,6 @@ import lombok.NonNull; import net.runelite.api.gameval.ObjectID; import net.runelite.client.ui.overlay.components.PanelComponent; - import java.util.ArrayList; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java index 9802adc2c3..e4033952d6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ConditionalStep.java @@ -30,7 +30,9 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.ChatMessageRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.MultiChatMessageRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.InitializableRequirement; +import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.NpcCondition; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.npc.DialogRequirement; @@ -41,13 +43,14 @@ import lombok.Setter; import net.runelite.api.GameState; import net.runelite.api.events.*; +import net.runelite.api.gameval.InterfaceID; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.components.PanelComponent; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -107,9 +110,16 @@ public ConditionalStep(QuestHelper questHelper, Integer id, QuestStep step, Stri this.id = id; } + public void addStep(ConditionalStep step) + { + var newSet = new HashSet<>(step.steps.keySet()); + newSet.remove(null); + addStep(passOnceCompleted(new Conditions(LogicType.OR, new ArrayList<>(newSet)), step), step, false); + } + public void addStep(Requirement requirement, QuestStep step) { - addStep(requirement, step, false); + addStep(passOnceCompleted(requirement, step), step, false); } // Each addStep can have an ID. When you add an ID, it keeps a separate ID to Steps OrderedHashSet. @@ -119,11 +129,49 @@ public void addStep(Requirement requirement, QuestStep step) public void addStep(Requirement requirement, QuestStep step, boolean isLockable) { step.setLockable(isLockable); - this.steps.put(requirement, step); + this.steps.put(passOnceCompleted(requirement, step), step); checkForConditions(requirement); } + private Requirement passOnceCompleted(Requirement completion, QuestStep step) + { + return completion; +// var manualOverride = step.getSidebarManualSkipRequirement(); +// if (completion == null || manualOverride == null) +// { +// return completion; +// } +// // Only auto-tick the sidebar when completion becomes true (rising edge). If we setShouldPass every +// // tick while the game still reports the step complete, an explicit untick is overwritten immediately. +// final boolean[] completionWasPassingLastCheck = { false }; +// return not(new Requirement() +// { +// @Override +// public boolean check(Client client) +// { +// if (manualOverride.check(client)) +// { +// completionWasPassingLastCheck[0] = true; +// return true; +// } +// boolean passed = completion.check(client); +// if (passed && !completionWasPassingLastCheck[0]) +// { +// manualOverride.setShouldPass(true); +// } +// completionWasPassingLastCheck[0] = passed; +// return passed; +// } +// +// @Override +// public @NotNull String getDisplayText() +// { +// return completion.getDisplayText(); +// } +// }); + } + private void checkForConditions(Requirement requirement) { checkForChatConditions(requirement); @@ -269,6 +317,17 @@ public void handleChatMessage(ChatMessage chatMessage, boolean parentDefinedRecu handleChildRequirementValidation(step -> step.handleChatMessage(chatMessage, parentDefinedRecursion), parentDefinedRecursion); } + @Subscribe + public void onWidgetClosed(WidgetClosed event) + { + final var DIALOG_GROUP_IDS = List.of(InterfaceID.CHAT_LEFT, InterfaceID.CHAT_RIGHT, InterfaceID.OBJECTBOX); + if (!DIALOG_GROUP_IDS.contains(event.getGroupId())) return; + + clientThread.invokeAtTickEnd(() -> { + dialogConditions.forEach(requirement -> requirement.validateActiveWidget(client)); + }); + } + @Subscribe public void onNpcSpawned(NpcSpawned event) { @@ -428,6 +487,7 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) .map(ItemRequirement.class::cast) .collect(Collectors.toList()); renderInventory(graphics, activeDp, itemRequirements, false); + renderBank(graphics, requirements); for (AbstractWidgetHighlight widgetHighlights : widgetsToHighlight) { widgetHighlights.highlightChoices(graphics, client, plugin); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java index 106aaf186e..ee85486802 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DetailedQuestStep.java @@ -43,17 +43,17 @@ import lombok.Getter; import lombok.NonNull; import lombok.Setter; -import net.runelite.api.*; import net.runelite.api.Menu; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemDespawned; import net.runelite.api.events.ItemSpawned; -import net.runelite.api.gameval.SpriteID; import net.runelite.api.widgets.Widget; +import net.runelite.api.gameval.SpriteID; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.PluginMessage; @@ -65,8 +65,8 @@ import java.awt.*; import java.awt.image.BufferedImage; -import java.util.*; import java.util.List; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -304,11 +304,6 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) return; } - if (inCutscene) - { - return; - } - if (!markedTiles.isEmpty()) { for (QuestTile location : markedTiles) @@ -359,11 +354,6 @@ public void makeWorldArrowOverlayHint(Graphics2D graphics, QuestHelperPlugin plu return; } - if (inCutscene) - { - return; - } - if (currentRender < (MAX_RENDER_SIZE / 2)) { renderArrow(graphics); @@ -378,11 +368,6 @@ public void makeWorldLineOverlayHint(Graphics2D graphics, QuestHelperPlugin plug return; } - if (inCutscene) - { - return; - } - if (linePoints != null && linePoints.size() > 1) { WorldLines.drawLinesOnWorld(graphics, client, linePoints, getQuestHelper().getConfig().targetOverlayColor()); @@ -468,6 +453,13 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) .collect(Collectors.toList()); renderInventory(graphics, definedPoint, itemRequirements, false); renderInventory(graphics, definedPoint, teleportRequirements, true); + + // TODO: Add a config to turn off as well? + if (!questHelper.getQuestHelperPlugin().isBankTabOpen()) + { + renderBank(graphics, requirements); + } + for (AbstractWidgetHighlight widgetHighlights : widgetsToHighlight) { widgetHighlights.highlightChoices(graphics, client, plugin); @@ -494,11 +486,6 @@ public void renderMapArrows(Graphics2D graphics) return; } - if (inCutscene) - { - return; - } - WorldPoint point = mapPoint.getWorldPoint(); if (currentRender < MAX_RENDER_SIZE / 2 || !getQuestHelper().getConfig().haveMinimapArrowFlash()) @@ -559,7 +546,7 @@ public void makeOverlayHint(PanelComponent panelComponent, QuestHelperPlugin plu { super.makeOverlayHint(panelComponent, plugin, additionalText, new ArrayList<>()); - if (inCutscene || hideRequirements) + if (hideRequirements) { return; } @@ -688,10 +675,6 @@ private boolean requirementContainsID(ItemRequirement requirement, Collection ids, Graphics2D graphics) { - if (inCutscene) - { - return; - } Player player = client.getLocalPlayer(); if (player == null) @@ -812,7 +795,7 @@ protected void renderHoveredMenuEntryPanel(PanelComponent panelComponent, String if (currentMenuEntries != null) { - Point mousePosition = client.getMouseCanvasPosition(); + net.runelite.api.Point mousePosition = client.getMouseCanvasPosition(); int menuX = menu.getMenuX(); int menuY = menu.getMenuY(); int menuWidth = menu.getMenuWidth(); @@ -881,7 +864,14 @@ public void setShortestPath() { return; } - var playerWp = client.getLocalPlayer().getWorldLocation(); + + var localPlayer = client.getLocalPlayer(); + if (localPlayer == null) + { + return; + } + + var playerWp = localPlayer.getWorldLocation(); if (playerWp == null) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java index 26e40a7638..048f6aec1f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/DigStep.java @@ -29,6 +29,8 @@ import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; +import java.awt.*; +import java.awt.image.BufferedImage; import lombok.Setter; import net.runelite.api.Player; import net.runelite.api.coords.LocalPoint; @@ -38,9 +40,6 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.OverlayUtil; -import java.awt.*; -import java.awt.image.BufferedImage; - public class DigStep extends DetailedQuestStep { private final ItemRequirement spade; @@ -97,11 +96,6 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) { super.makeWorldOverlayHint(graphics, plugin); - if (inCutscene) - { - return; - } - LocalPoint localLocation = definedPoint.resolveLocalPoint(client); if (localLocation == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java index 8eecf548ee..367ad426a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/EmoteStep.java @@ -98,24 +98,30 @@ public void makeWidgetOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) void scrollToWidget(Widget widget) { - final Widget parent = client.getWidget(InterfaceID.Emote.CONTENTS); + final Widget parent = client.getWidget(InterfaceID.Emote.SCROLLABLE); if (widget == null || parent == null) { return; } + int averageCentralY = 0; + int nonnullCount = 0; + averageCentralY += widget.getRelativeY() + widget.getHeight() / 2; + nonnullCount += 1; + averageCentralY /= nonnullCount; final int newScroll = Math.max(0, Math.min(parent.getScrollHeight(), - (widget.getRelativeY() + widget.getHeight() / 2) - parent.getHeight() / 2)); + averageCentralY - parent.getHeight() / 2)); client.runScript( ScriptID.UPDATE_SCROLLBAR, - InterfaceID.Emote.SCROLLBAR, - InterfaceID.Emote.CONTENTS, + InterfaceID.Emote.SCROLLBAR, + InterfaceID.Emote.SCROLLABLE, newScroll ); } + @Override protected void setupIcon() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java index 8c32b29a11..ed3219f6ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcEmoteStep.java @@ -24,12 +24,12 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.steps.emote.QuestEmote; import net.runelite.client.plugins.microbot.questhelper.steps.overlay.IconOverlay; +import lombok.Getter; import net.runelite.api.ScriptID; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java index f68d90fd5e..10610b0ed3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/NpcStep.java @@ -25,7 +25,6 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; @@ -33,9 +32,10 @@ import net.runelite.client.plugins.microbot.questhelper.steps.overlay.DirectionArrow; import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import lombok.Getter; import lombok.Setter; -import net.runelite.api.*; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.NpcChanged; @@ -63,8 +63,8 @@ public class NpcStep extends DetailedQuestStep protected final int npcID; protected final List alternateNpcIDs = new ArrayList<>(); - @Setter @Getter + @Setter protected boolean allowMultipleHighlights; @Getter @@ -210,6 +210,19 @@ public void scanForNpcs() { addNpcToListGivenMatchingID(npc, this::npcPassesChecks, npcs); } + + /* TODO: Configurable boolean per NpcStep for whether to consider all world views + This is as you're likely to want to only highlight stuff on your own ship, not on others' + */ + for (WorldView worldView : client.getTopLevelWorldView().worldViews()) + { + if (worldView == playerWorldView) continue; + + for (NPC npc : worldView.npcs()) + { + addNpcToListGivenMatchingID(npc, this::npcPassesChecks, npcs); + } + } } public NpcStep addAlternateNpcs(Integer... alternateNpcIDs) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java index 9cf33dfdd9..36e74b7800 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/ObjectStep.java @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; @@ -33,9 +32,11 @@ import net.runelite.client.plugins.microbot.questhelper.steps.overlay.DirectionArrow; import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import lombok.Getter; +import lombok.NonNull; import lombok.Setter; -import net.runelite.api.*; import net.runelite.api.Point; +import net.runelite.api.*; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.*; @@ -67,6 +68,11 @@ public class ObjectStep extends DetailedQuestStep @Setter private boolean revalidateObjects; + /// Force the highlight to use the clickbox highlight, regardless of the user's setting. + /// This is useful if the object you're trying to highlight is technically visible but cannot feasibly be outline-highlighted. + @Setter + private boolean forceClickboxHighlight = false; + public ObjectStep(QuestHelper questHelper, int objectID, WorldPoint worldPoint, String text, Requirement... requirements) { super(questHelper, worldPoint, text, requirements); @@ -147,11 +153,9 @@ protected void loadObjects() { // TODO: This needs to be tested in Shadow of the Storm's Demon Room objects.clear(); - loadObjectsInWorldView(client.getTopLevelWorldView()); - var playerWorldView = client.getLocalPlayer().getWorldView(); - if (playerWorldView != client.getTopLevelWorldView()) + for (WorldView worldView : client.getTopLevelWorldView().worldViews()) { - loadObjectsInWorldView(client.getLocalPlayer().getWorldView()); + loadObjectsInWorldView(worldView); } } @@ -308,11 +312,6 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) return; } - if (inCutscene) - { - return; - } - Point mousePosition = client.getMouseCanvasPosition(); if (client.getLocalPlayer() == null) @@ -352,10 +351,15 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) Color configColor = getQuestHelper().getConfig().targetOverlayColor(); - QuestHelperConfig.ObjectHighlightStyle highlightStyle = visibilityHelper.isObjectVisible(tileObject) + var isObjectVisible = visibilityHelper.isObjectVisible(tileObject); + var highlightStyle = isObjectVisible ? questHelper.getConfig().highlightStyleObjects() : CLICK_BOX; + if (highlightStyle == QuestHelperConfig.ObjectHighlightStyle.OUTLINE && forceClickboxHighlight) { + highlightStyle = QuestHelperConfig.ObjectHighlightStyle.CLICK_BOX; + } + switch (highlightStyle) { case CLICK_BOX: @@ -385,7 +389,7 @@ public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) if (iconItemID != -1 && closestObject != null && questHelper.getConfig().showSymbolOverlay()) { Shape clickbox = closestObject.getClickbox(); - if (clickbox != null && !inCutscene) + if (clickbox != null) { Rectangle2D boundingBox = clickbox.getBounds2D(); graphics.drawImage(icon, (int) boundingBox.getCenterX() - 15, (int) boundingBox.getCenterY() - 10, @@ -465,12 +469,6 @@ protected void handleObjects(TileObject object) return; } - var worldViewsToConsider = List.of(client.getTopLevelWorldView(), client.getLocalPlayer().getWorldView()); - if (!worldViewsToConsider.contains(object.getWorldView())) - { - return; - } - if (object.getId() == objectID || alternateObjectIDs.contains(object.getId())) { setObjects(object); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java index cadd9f9aa3..c1b4f4c0e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PortTaskStep.java @@ -9,12 +9,10 @@ import lombok.Getter; import net.runelite.api.gameval.ObjectID; import net.runelite.api.gameval.VarbitID; - import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; - import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.and; import static net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicHelper.or; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java index 61a81e980a..8ae37997ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleStep.java @@ -1,6 +1,5 @@ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; @@ -8,6 +7,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.widgets.Widget; import net.runelite.client.eventbus.Subscribe; +import lombok.Getter; import java.awt.*; import java.util.HashSet; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java index b2f10303d9..3b42bf606c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/PuzzleWrapperStep.java @@ -32,11 +32,12 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.conditional.Conditions; import net.runelite.client.plugins.microbot.questhelper.requirements.util.LogicType; -import net.runelite.client.plugins.microbot.questhelper.steps.choice.DialogChoiceStep; import lombok.Getter; +import net.runelite.client.plugins.microbot.questhelper.steps.choice.DialogChoiceStep; import lombok.NonNull; import net.runelite.client.ui.overlay.components.PanelComponent; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java index c5f9068481..7102a40628 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/QuestStep.java @@ -30,6 +30,7 @@ import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestUtil; +import net.runelite.client.plugins.microbot.questhelper.requirements.ManualRequirement; import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.choice.*; @@ -65,10 +66,11 @@ import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ImageUtil; +import javax.annotation.Nullable; import java.awt.*; import java.awt.image.BufferedImage; -import java.util.*; import java.util.List; +import java.util.*; import java.util.regex.Pattern; import static net.runelite.client.plugins.microbot.questhelper.overlays.QuestHelperOverlay.TITLED_CONTENT_COLOR; @@ -126,9 +128,7 @@ public abstract class QuestStep implements Module @Setter private Requirement lockingCondition; - private int currentCutsceneStatus = 0; - protected boolean inCutscene; - + @Getter @Setter protected boolean allowInCutscene = false; @@ -161,6 +161,24 @@ public abstract class QuestStep implements Module @Setter private boolean showInSidebar = true; + /** + * When set, the Quest Helper sidebar can show a small skip control that toggles this requirement and persists per helper. + */ + @Nullable + @Getter + @Setter + private ManualRequirement sidebarManualSkipRequirement; + + /** + * Stable id for {@link #sidebarManualSkipRequirement} persistence (e.g. maker order slot id). + */ + @Nullable + @Getter + @Setter + private String sidebarManualSkipPersistenceKey; + + + protected String lastDialogSeen = ""; @Setter @@ -248,19 +266,6 @@ public void addSubSteps(Collection substeps) @Subscribe public void onVarbitChanged(VarbitChanged event) { - if (!allowInCutscene) - { - int newCutsceneStatus = client.getVarbitValue(VarbitID.CUTSCENE_STATUS); - if (currentCutsceneStatus == 0 && newCutsceneStatus == 1) - { - enteredCutscene(); - } - else if (currentCutsceneStatus == 1 && newCutsceneStatus == 0) - { - leftCutscene(); - } - currentCutsceneStatus = newCutsceneStatus; - } } @Subscribe @@ -290,16 +295,6 @@ public void addText(String newLine) text.add(newLine); } - public void enteredCutscene() - { - inCutscene = true; - } - - public void leftCutscene() - { - inCutscene = false; - } - public void highlightChoice() { choices.checkChoices(client, lastDialogSeen); @@ -623,6 +618,45 @@ protected Widget getInventoryWidget() return client.getWidget(InterfaceID.Inventory.ITEMS); } + protected Widget getBankWidget() + { + return client.getWidget(InterfaceID.Bankmain.ITEMS); + } + + protected void renderBank(Graphics2D graphics, List passedRequirements) + { + Widget bankWidget = getBankWidget(); + if (bankWidget == null || bankWidget.isHidden()) + { + return; + } + Color baseColor = questHelper.getConfig().targetOverlayColor(); + + if (bankWidget.getDynamicChildren() == null) return; + + + for (Widget item : bankWidget.getDynamicChildren()) + { + for (Requirement requirement : passedRequirements) + { + if (isValidRequirementForRenderInBank(requirement, item)) + { + highlightItem(item, baseColor, graphics); + } + } + } + } + + private boolean isValidRequirementForRenderInBank(Requirement requirement, Widget item) + { + return requirement instanceof ItemRequirement && isValidRenderRequirementInBank((ItemRequirement) requirement, item); + } + + protected boolean isValidRenderRequirementInBank(ItemRequirement requirement, Widget item) + { + return (item.getItemId() > 0 && !item.isHidden() && requirement.getAllIds().contains(item.getItemId())); + } + protected void renderInventory(Graphics2D graphics, DefinedPoint definedPoint, List passedRequirements, boolean distanceLimit) { Widget inventoryWidget = getInventoryWidget(); @@ -649,13 +683,13 @@ protected void renderInventory(Graphics2D graphics, DefinedPoint definedPoint, L if (isValidRequirementForRenderInInventory(requirement, item)) { - highlightInventoryItem(item, baseColor, graphics); + highlightItem(item, baseColor, graphics); } } } } - private void highlightInventoryItem(Widget item, Color color, Graphics2D graphics) + private void highlightItem(Widget item, Color color, Graphics2D graphics) { Rectangle slotBounds = item.getBounds(); switch (questHelper.getConfig().highlightStyleInventoryItems()) @@ -740,4 +774,14 @@ public PuzzleWrapperStep puzzleWrapStep(boolean hiddenInSidebar) { return new PuzzleWrapperStep(getQuestHelper(), this).withNoHelpHiddenInSidebar(hiddenInSidebar); } + + public void withPersistedManualSkip(String persistenceKey) { + setSidebarManualSkipWithPersistenceKey(new ManualRequirement(), persistenceKey); + } + + public void setSidebarManualSkipWithPersistenceKey(ManualRequirement requirement, String persistenceKey) + { + setSidebarManualSkipRequirement(requirement); + setSidebarManualSkipPersistenceKey(persistenceKey); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java index bb9179ff23..23c03336cd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WidgetStep.java @@ -24,10 +24,10 @@ */ package net.runelite.client.plugins.microbot.questhelper.steps; -import lombok.Getter; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetDetails; +import lombok.Getter; import lombok.Setter; import net.runelite.api.widgets.Widget; @@ -39,8 +39,8 @@ public class WidgetStep extends DetailedQuestStep { - @Setter @Getter + @Setter protected List widgetDetails = new ArrayList<>(); protected List> extraWidgetOverlayHintFunctions = new ArrayList<>(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WorldEntityStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WorldEntityStep.java new file mode 100644 index 0000000000..158ea87c3d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/WorldEntityStep.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2026, Zoinkwiz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.microbot.questhelper.steps; + +import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.questhelpers.QuestHelper; +import net.runelite.client.plugins.microbot.questhelper.requirements.Requirement; +import net.runelite.client.plugins.microbot.questhelper.steps.overlay.DirectionArrow; +import net.runelite.client.plugins.microbot.questhelper.steps.tools.DefinedPoint; +import net.runelite.client.plugins.microbot.questhelper.steps.tools.QuestPerspective; +import net.runelite.api.WorldEntity; +import net.runelite.api.WorldEntityConfig; +import net.runelite.api.WorldView; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.gameval.NpcID; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.ColorUtil; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; +import java.util.Arrays; + +public class WorldEntityStep extends DetailedQuestStep +{ + public final int worldEntityConfigID; + + // Used to know where to put the hint arrow + private Shape lastFrameStructure; + + public WorldEntityStep(QuestHelper questHelper, int worldEntityConfigID, DefinedPoint definedPoint, String text, Requirement... requirements) + { + super(questHelper, definedPoint, text, requirements); + this.worldEntityConfigID = worldEntityConfigID; + } + + public WorldEntityStep(QuestHelper questHelper, int worldEntityConfigID, WorldPoint worldPoint, String text, Requirement... requirements) + { + this(questHelper, worldEntityConfigID, DefinedPoint.of(worldPoint), text, requirements); + } + + @Override + public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin) + { + super.makeWorldOverlayHint(graphics, plugin); + + lastFrameStructure = null; + + WorldEntity worldEntity = findWorldEntity(); + if (worldEntity == null) return; + + // Currently fine as only one boat per world view. Perhaps in the future an issue where multiple things exist in a world view? + Shape structure = QuestPerspective.getAreaFromWorldView(client, worldEntity.getWorldView()); + if (structure == null) return; + + lastFrameStructure = structure; + + Color configColor = getQuestHelper().getConfig().targetOverlayColor(); + OverlayUtil.renderHoverableArea( + graphics, + structure, + client.getMouseCanvasPosition(), + ColorUtil.colorWithAlpha(configColor, 20), + configColor.darker(), + configColor + ); + } + + + @Override + public void renderArrow(Graphics2D graphics) + { + if (hideWorldArrow || !questHelper.getConfig().showMiniMapArrow()) + { + return; + } + + Shape structure = lastFrameStructure; + if (structure == null) + { + super.renderArrow(graphics); + return; + } + + Rectangle bounds = structure.getBounds(); + if (bounds.width <= 0 || bounds.height <= 0) + { + super.renderArrow(graphics); + return; + } + + int tipX = bounds.x + bounds.width / 2; + int tipY = bounds.y; + DirectionArrow.drawWorldArrow(graphics, getQuestHelper().getConfig().targetOverlayColor(), tipX, tipY); + } + + + private WorldEntity findWorldEntity() + { + WorldEntity worldEntity = findWorldEntityInWorldView(client.getTopLevelWorldView(), worldEntityConfigID); + if (worldEntity != null) + { + return worldEntity; + } + + for (WorldView worldView : client.getTopLevelWorldView().worldViews()) + { + worldEntity = findWorldEntityInWorldView(worldView, worldEntityConfigID); + if (worldEntity != null) + { + return worldEntity; + } + } + + return null; + } + + public static WorldEntity findWorldEntityInWorldView(WorldView worldView, int configId) + { + if (worldView == null) + { + return null; + } + + for (WorldEntity worldEntity : worldView.worldEntities()) + { + WorldEntityConfig config = worldEntity.getConfig(); + if (config != null && config.getId() == configId) + { + return worldEntity; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java index 4d291340f8..61a259381e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/DialogChoiceStep.java @@ -1,10 +1,10 @@ package net.runelite.client.plugins.microbot.questhelper.steps.choice; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import java.util.Map; import lombok.Getter; import lombok.Setter; -import java.util.Map; import java.util.regex.Pattern; public class DialogChoiceStep extends WidgetChoiceStep diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java index 35f3018419..2ed8a0c4f8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/choice/WidgetChoiceStep.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.microbot.questhelper.steps.choice; import net.runelite.client.plugins.microbot.questhelper.QuestHelperConfig; +import java.util.Map; import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; @@ -34,7 +35,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.regex.Pattern; public class WidgetChoiceStep @@ -54,6 +54,7 @@ public class WidgetChoiceStep protected int excludedGroupId; protected int excludedChildId; + @Getter private final int choiceById; @Getter @@ -64,6 +65,7 @@ public class WidgetChoiceStep protected int varbitValue = -1; protected final Map varbitValueToAnswer; + @Getter protected boolean shouldNumber = false; @Setter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java index 67cd6f540f..b7f64b0a27 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/emote/QuestEmote.java @@ -44,7 +44,9 @@ public enum QuestEmote STAMP("Stamp", SpriteID.Emotes.STAMP), FLAP("Flap", SpriteID.Emotes.FLAP), SLAP_HEAD("Slap Head", SpriteID.Emotes.SLAP_HEAD), - SPIN("Spin", SpriteID.Emotes.SPIN); + SALUTE("Salute", SpriteID.Emotes.SALUTE), + SPIN("Spin", SpriteID.Emotes.SPIN), + SIT("Sit", 5248); private String name; private int spriteId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java index c76e78aa95..19b56fbad7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/overlay/DirectionArrow.java @@ -33,8 +33,8 @@ import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; -import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; @@ -193,7 +193,7 @@ protected static void createMinimapDirectionArrow(Graphics2D graphics, Client cl drawMinimapArrow(graphics, line, color); } - @NotNull + @Nonnull private static Line2D.Double getLine(Point playerPosOnMinimap, Point destinationPosOnMinimap) { double xDiff = playerPosOnMinimap.getX() - destinationPosOnMinimap.getX(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java index 158e0f611e..7794b12f2e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/DefinedPoint.java @@ -32,7 +32,6 @@ import net.runelite.api.WorldView; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; - import javax.annotation.Nullable; import java.util.List; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java index d758cfce97..a140ee668e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/tools/QuestPerspective.java @@ -25,8 +25,16 @@ package net.runelite.client.plugins.microbot.questhelper.steps.tools; import net.runelite.client.plugins.microbot.questhelper.requirements.zone.Zone; -import net.runelite.api.*; +import net.runelite.api.Client; +import net.runelite.api.DecorativeObject; +import net.runelite.api.GameObject; +import net.runelite.api.GroundObject; +import net.runelite.api.Perspective; import net.runelite.api.Point; +import net.runelite.api.Tile; +import net.runelite.api.WallObject; +import net.runelite.api.WorldView; +import net.runelite.api.Player; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.gameval.InterfaceID; @@ -34,8 +42,8 @@ import net.runelite.api.widgets.Widget; import java.awt.*; -import java.util.ArrayList; -import java.util.LinkedHashSet; +import java.awt.geom.Area; +import java.util.*; import java.util.List; public class QuestPerspective @@ -77,8 +85,7 @@ public static WorldPoint getWorldPointConsideringWorldView(Client client, LocalP } var mainLocal = worldEntity.transformToMainWorld(localPoint); - return WorldPoint.fromLocal(client.getTopLevelWorldView(), - mainLocal.getX(), mainLocal.getY(), client.getTopLevelWorldView().getPlane()); + return WorldPoint.fromLocalInstance(client, mainLocal, client.getTopLevelWorldView().getPlane()); } else { @@ -123,8 +130,7 @@ public static WorldPoint getWorldPointConsideringWorldView(Client client, WorldV } var mainLocal = worldEntity.transformToMainWorld(localPoint); - return WorldPoint.fromLocal(client.getTopLevelWorldView(), - mainLocal.getX(), mainLocal.getY(), client.getTopLevelWorldView().getPlane()); + return WorldPoint.fromLocalInstance(client, mainLocal, client.getTopLevelWorldView().getPlane()); } else { @@ -266,10 +272,10 @@ public static Point getMinimapPoint(Client client, WorldPoint start, WorldPoint return null; } - final int angle = client.getCameraYawTarget() & 0x7FF; + final int angle = client.getCameraYawTarget() & 0x3FFF; - final int sin = Perspective.SINE[angle]; - final int cos = Perspective.COSINE[angle]; + final int sin = Perspective.SINE14[angle]; + final int cos = Perspective.COSINE14[angle]; final int xx = y * sin + cos * x >> 16; final int yy = sin * x - y * cos >> 16; @@ -359,6 +365,73 @@ private static void addToPoly(Client client, Polygon areaPoly, LocalPoint localP } } + public static Shape getAreaFromWorldView(Client client, WorldView view) + { + if (view == null || view.getScene() == null) + { + return null; + } + + Tile[][][] tiles = view.getScene().getTiles(); + + Area area = new Area(); + for (Tile[][] planeTiles : tiles) + { + if (planeTiles == null) continue; + for (Tile[] column : planeTiles) + { + if (column == null) continue; + for (Tile tile : column) + { + if (tile == null) continue; + addTileHulls(area, client, tile); + } + } + } + + return area.isEmpty() ? null : area; + } + + private static void addTileHulls(Area area, Client client, Tile tile) + { + GameObject[] gameObjects = tile.getGameObjects(); + if (gameObjects != null) + { + for (GameObject go : gameObjects) + { + if (go == null || !isUnnamedScenery(client, go.getId())) continue; + addHull(area, go.getConvexHull()); + } + } + + WallObject wall = tile.getWallObject(); + if (wall != null && isUnnamedScenery(client, wall.getId())) + { + addHull(area, wall.getConvexHull()); + addHull(area, wall.getConvexHull2()); + } + + GroundObject ground = tile.getGroundObject(); + if (ground != null && isUnnamedScenery(client, ground.getId())) + { + addHull(area, ground.getConvexHull()); + } + } + + private static void addHull(Area target, Shape hull) + { + if (hull != null) + { + target.add(new Area(hull)); + } + } + + private static boolean isUnnamedScenery(Client client, int objectId) + { + var def = client.getObjectDefinition(objectId); + return def != null && Objects.equals(def.getName(), "null"); + } + /** * Compares a quest-defined {@link WorldPoint} with a runtime {@link LocalPoint}, normalizing * both into the top-level world space so they can be compared safely across WorldViews. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java index 90e9ad5b2f..2229e47193 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/steps/widget/WidgetHighlight.java @@ -25,6 +25,7 @@ package net.runelite.client.plugins.microbot.questhelper.steps.widget; import net.runelite.client.plugins.microbot.questhelper.QuestHelperPlugin; +import net.runelite.client.plugins.microbot.questhelper.domain.QuetzalDestination; import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; @@ -38,6 +39,7 @@ public class WidgetHighlight extends AbstractWidgetHighlight { @Getter protected final int interfaceID; + @Getter protected final int childChildId; @@ -138,6 +140,18 @@ public static WidgetHighlight createShopItemHighlight(int itemIdRequirement) return w; } + /** + * Create a widget highlight that highlights the given destination in the quetzal interface + * @param quetzalDestination The quetzal destination to highlight + * @return a fully built WidgetHighlight + */ + public static WidgetHighlight createQuetzalHighlight(QuetzalDestination quetzalDestination) + { + var w = new WidgetHighlight(InterfaceID.QuetzalMenu.ICONS, true); + w.modelIdRequirement = quetzalDestination.modelID; + return w; + } + @Override public void highlightChoices(Graphics2D graphics, Client client, QuestHelperPlugin questHelper) { @@ -154,6 +168,7 @@ private void highlightChoices(Widget parentWidget, Graphics2D graphics, QuestHel Widget[] widgets = parentWidget.getChildren(); Widget[] staticWidgets = parentWidget.getStaticChildren(); + var dynamicWidgets = parentWidget.getDynamicChildren(); if (childChildId != -1 && widgets != null) { @@ -171,6 +186,10 @@ private void highlightChoices(Widget parentWidget, Graphics2D graphics, QuestHel { highlightChoices(widget, graphics, questHelper); } + for (var widget : dynamicWidgets) + { + highlightChoices(widget, graphics, questHelper); + } } highlightWidget(graphics, questHelper, parentWidget); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java index 11b5140149..5dfacb00f8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/util/Utils.java @@ -36,7 +36,6 @@ import net.runelite.api.gameval.VarbitID; import net.runelite.client.util.ColorUtil; import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import java.awt.*; @@ -52,7 +51,7 @@ public class Utils * @return {@link AccountType} * @apiNote This function should only be called from the client thread. */ - public AccountType getAccountType(@NotNull Client client) + public AccountType getAccountType(@Nonnull Client client) { if (client.getGameState() != GameState.LOGGED_IN) { From fe771870a1255bbee0e008d4f4635d837e312f0b Mon Sep 17 00:00:00 2001 From: infuse21 Date: Sun, 19 Jul 2026 17:26:34 +0100 Subject: [PATCH 05/48] regen client-thread-guardrail-baseline.txt removed toll-gate helper pattern to avoid guardrail violation --- .../microbot/util/walker/Rs2Walker.java | 8 +--- .../client-thread-guardrail-baseline.txt | 48 +++++++++---------- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 9afa31c64c..6bf2a33f90 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -8585,12 +8585,6 @@ private static int transportHandlingPreference(Transport transport) { return 0; } - private static boolean isAlKharidTollGateTransport(Transport transport, TileObject tileObject) { - return isAlKharidTollGateTransport(transport) - && tileObject != null - && isAlKharidTollGateObjectId(tileObject.getId()); - } - private static boolean isAlKharidTollGateTransport(Transport transport) { return transport != null && isAlKharidTollGateObjectId(transport.getObjectId()) @@ -8664,7 +8658,7 @@ private static boolean handleObjectExceptions(Transport transport, TileObject ti } } - if (isAlKharidTollGateTransport(transport, tileObject) && isPayTollAction(transport.getAction())) { + if (isAlKharidTollGateTransport(transport) && isPayTollAction(transport.getAction())) { return handleAlKharidTollGate(transport); } diff --git a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt index a2605ab88d..dab8036f3b 100644 --- a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt +++ b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt @@ -783,6 +783,7 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#invokeCharterDestinat net.runelite.client.plugins.microbot.util.walker.Rs2Walker#invokeCharterDestinationWidget(Widget, String): boolean -> net.runelite.api.widgets.Widget#getIndex(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isCatalogTransportObject(TileObject): boolean -> net.runelite.api.TileObject#getId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isCatalogTransportObject(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isClientThread(): boolean -> net.runelite.api.Client#isClientThread(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isCloseToRegion(int, int, int): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isCloseToRegion(int, int, int): boolean -> net.runelite.api.WorldView#getPlane(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isDoorComposition(ObjectComposition, List): boolean -> net.runelite.api.ObjectComposition#getImpostorIds(): int[] @@ -797,32 +798,32 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObj net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.ObjectComposition#getName(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$40(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$41(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$38(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$41(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$42(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$39(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$185(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$154(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$156(String): boolean -> net.runelite.api.widgets.Widget#getText(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$132(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$138(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$138(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$139(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$139(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$21(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$112(int, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$112(int, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$114(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$115(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$116(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$40(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$187(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$156(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$158(String): boolean -> net.runelite.api.widgets.Widget#getText(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$134(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$140(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$140(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$141(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$141(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$22(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$113(int, boolean, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$113(int, boolean, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$115(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$116(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$117(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$119(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$146(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$147(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$118(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$121(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$148(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$149(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$2(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$3(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$68(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$69(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.WorldView#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint @@ -838,7 +839,6 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#processWalk(WorldPoin net.runelite.client.plugins.microbot.util.walker.Rs2Walker#resolveDoorSegment(List, int): WorldPoint[] -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#resolveDoorSegment(List, int): WorldPoint[] -> net.runelite.api.Scene#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#resolveDoorSegment(List, int): WorldPoint[] -> net.runelite.api.WorldView#getScene(): Scene -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#setStart(WorldPoint): void -> net.runelite.api.Client#isClientThread(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#setTarget(WorldPoint, String): void -> net.runelite.api.Client#getLocalPlayer(): Player net.runelite.client.plugins.microbot.util.walker.Rs2Walker#staminaThreshold(): int -> net.runelite.api.Client#getLocalPlayer(): Player net.runelite.client.plugins.microbot.util.walker.Rs2Walker#staminaThreshold(): int -> net.runelite.api.Player#getName(): String @@ -865,11 +865,9 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastLocal(LocalPo net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkFastLocal(LocalPoint): void -> net.runelite.api.WorldView#getPlane(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkNextToInstance(GameObject): void -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkNextToInstance(GameObject): void -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkWithBankedTransportsAndState(WorldPoint, int, boolean): WalkerState -> net.runelite.api.Client#isClientThread(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkWithBankedTransportsAndStateLocked(WorldPoint, int, boolean): WalkerState -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkWithBankedTransportsAndStateLocked(WorldPoint, int, boolean): WalkerState -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkWithStateInternal(WorldPoint, int): WalkerState -> net.runelite.api.Client#getTopLevelWorldView(): WorldView -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkWithStateInternal(WorldPoint, int): WalkerState -> net.runelite.api.Client#isClientThread(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#walkWithStateInternal(WorldPoint, int): WalkerState -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.widget.Rs2Widget#checkBoundsOverlapWidgetInMainModal(Rectangle, int, int): boolean -> net.runelite.api.widgets.Widget#isHidden(): boolean net.runelite.client.plugins.microbot.util.widget.Rs2Widget#checkWidgetAndDescendantsForOverlapCanvas(Widget, Rectangle, int, int): boolean -> net.runelite.api.widgets.Widget#getBounds(): Rectangle From ceed42f5ad4446fcbca1308840967db2bc16436c Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 17:56:09 +0100 Subject: [PATCH 06/48] Reconcile shortestpath tracker; set facade-first direction Verified against the live tree on So-I-dont-Fuck-The-Walker-KEK: - #3 (POH TSV) reclassified OPEN -> NEEDS-VERIFY: teleportation_poh.tsv is absent by design; POH is routed programmatically via util/poh/, not a TSV. teleportation_portals.tsv (101 rows) is a different TELEPORTATION_PORTAL type (Castle Wars/god-wars), not POH. - #27 (mushtrees) corrected 8 -> 12 of 16 pairs. - Confirmed boat world-view DONE (WorldPointUtil.fromLocalInstance), closing UPSTREAM_COMPARISON.md #6; PrimitiveIntList (#11) still OPEN. - Added 2026-07-20 reconciliation note and a Facade migration section documenting the frozen 23-member ShortestPathPlugin coupling contract and the staged decouple-before-backport plan. Docs only; no walker/engine code changed. Co-Authored-By: Claude Opus 4.8 --- .../WEBWALKER_IMPROVEMENT_PLAN.md | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md index 91da5035a7..923405557d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md @@ -9,6 +9,8 @@ Consolidated findings from a four-angle audit (pathfinder algorithm, Rs2Walker r **Rollup (2026-04-18 audit):** 22 DONE · 9 PARTIAL · 8 OPEN · total 39. (Tier 3 closed.) +> **2026-07-20 reconciliation — direction set: FACADE-FIRST.** Spot-verified against the live tree on `So-I-dont-Fuck-The-Walker-KEK`. Confirmed: boat world-view is **DONE** (`WorldPointUtil.fromLocalInstance`, closes `UPSTREAM_COMPARISON.md` #6); `PrimitiveIntList` (#11) still **OPEN**; #3 **reclassified** (see row); #27 now **12/16** pairs (was 8). A full 39-item re-audit was **not** performed — only the items below were re-checked. **Decision:** before any further upstream backport, introduce a Microbot-owned path facade so `Rs2Walker` and the other consumers stop importing upstream internals directly. See the **"Facade migration (2026-07-20)"** section at the bottom for the frozen coupling contract and staged plan. + --- ## Tier 1 — Correctness bugs (fix first) @@ -19,7 +21,7 @@ Small patches, big payoff. Most are known but still unlanded. |---|---|---|---|---| | 1 | DONE | `PrimitiveIntHashMap.rehash()` data loss — `return;` → `continue;` | `PrimitiveIntHashMap.java:210` | S | | 2 | PARTIAL | Wilderness boundaries 8 tiles off, underground 198 tiles narrow — Chebyshev mod-6400 landed (`Pathfinder.java:155–162`), wilderness widths not re-verified | `Pathfinder.java`, `PathfinderConfig.java` | M | -| 3 | OPEN | `teleportation_poh.tsv` is 0 bytes — backport ~88 upstream rows (file currently deleted in working tree, rows not migrated) | resources TSV | M | +| 3 | NEEDS-VERIFY | `teleportation_poh.tsv` absent **by design** — local routes POH programmatically via `util/poh/` (`PohTransport`/`PohTeleports`), not a TSV. (`teleportation_portals.tsv`, 101 rows, is a *different* `TELEPORTATION_PORTAL` type: Castle Wars / god-wars portals, not POH.) Correct action is **not** "backport the TSV" but "confirm `util/poh` covers upstream's POH destination set". *Reclassified 2026-07-20.* | `util/poh/` | M | | 4 | DONE | `growBucket()` integer overflow — `Math.min(len, MAX/2-4)*2` | `PrimitiveIntHashMap.java:147` | S | | 5 | DONE | Missing `onGameStateChanged` refresh — quest/varbit goes stale after re-login | `ShortestPathPlugin.java:488` | S | @@ -68,7 +70,7 @@ The "completeness of navigating the world" half. | 24 | PARTIAL | Quest Cape + Max Cape teleport rows — Max Cape rows present in `teleportation_items.tsv`, Quest Cape rows still missing | Endgame automation | S | | 25 | OPEN | 20+ skill cape teleports missing (Cooking, Magic, Prayer, Slayer, Herblore, …) — only Slayer/Skills necklace covered | | M | | 26 | PARTIAL | Achievement diary teleport toggles incomplete — only Varrock medium fully wired; Ardougne/Karamja/Desert harder tiers missing | | M | -| 27 | PARTIAL | Magic Mushtree permutation matrix incomplete — 8 of expected 16 pairs present | Recent commit `75b1f167ce` added feature; confirm matrix coverage | M | +| 27 | PARTIAL | Magic Mushtree permutation matrix incomplete — **12 of expected 16** data rows present in `magic_mushtrees.tsv` (re-counted 2026-07-20; was 8) | Recent commit `75b1f167ce` added feature; confirm remaining 4 pairs | M | | 28 | PARTIAL | Stronghold of Security spirit tree + Prifddinas crystal-tier destinations — placeholders in `spirit_trees.tsv`, actual rows incomplete | | S | | 29 | PARTIAL | Slayer Ring Ankous (3193,3611), Fairy Ring CJQ (Great Conch) — CJQ present, Ankous Slayer Ring variant still missing | | S | | 30 | OPEN | No `isOneWay` flag on transports — return-only boats and Legends' jagged-wall used bidirectionally | | M | @@ -119,3 +121,42 @@ This plan synthesizes four parallel sub-agent reports, each with its own reasoni 4. Concurrency / observability (static state, client-thread compliance, allocation hotspots, region eviction, structured logging, metrics, tests). Items already catalogued in `UPSTREAM_COMPARISON.md` are surfaced here only where they overlap with an execution tier; refer to that doc for the full upstream-sync punch list. + +--- + +## Facade migration (2026-07-20) + +**Goal:** decouple automation from the shortest-path *internals* so future upstream backports stop rippling into `Rs2Walker` and the other consumers. The fork stays a fork; this is a boundary, not a rewrite. Once the boundary exists, backporting an upstream fix means changing code behind the facade only. + +### Why first +`Rs2Walker` (~9k lines) reaches directly into `ShortestPathPlugin` static state — `getPathfinder`, `setPathfinder`, `getPathfinderFuture`, `getPathfinderMutex`, `getMarker`, `isStartPointSet`, etc. Every upstream change that touches those internals currently risks the walker (hence the branch name). A facade freezes the surface the walker sees. + +### Frozen coupling contract (what the facade MUST expose) +Verified 2026-07-20 by grepping all consumers under `plugins/microbot/`. + +`ShortestPathPlugin` static members referenced externally (23): + +| Category | Members | +|---|---| +| Pathfinder lifecycle | `getPathfinder` / `setPathfinder` / `pathfinder`, `getPathfinderFuture` / `setPathfinderFuture`, `getPathfindingExecutor` / `setPathfindingExecutor`, `getPathfinderMutex` | +| Config | `getPathfinderConfig` / `pathfinderConfig`, `setReachedDistance`, `configOverride`, `override`, `CONFIG_GROUP` | +| Target / state | `exit`, `isStartPointSet` / `setStartPointSet`, `setLastLocation` | +| Marker (overlay) | `getMarker` / `setMarker`, `MARKER_IMAGE` | +| Data | `getTransports` | + +`Pathfinder` external surface is small — only `getPath()` and `isDone()`. `PathfinderConfig` is heavily used *inside* `Rs2Walker` (43 refs) and by `leaguetransport` — its surface must be catalogued before Stage 2. + +### Consumers to migrate (24 files) +`util/walker/*` (Rs2Walker + lifecycle/awaits/banking/shared), `util/bank/Rs2Bank`, `util/depositbox/Rs2DepositBox`, `util/skills/slayer/Rs2Slayer`, `util/poh/*`, `util/leaguetransport/*`, `util/tile/Rs2Tile`, `util/reachable/Rs2Reachable`, `util/npc/Rs2NpcManager`, `questhelper/QuestScript`, `breakhandler/**`, `Script.java`. + +### Staged plan (each stage compiles + walker still runs before the next) +1. **Catalogue** the full external surface of `Pathfinder`, `PathfinderConfig`, `Transport`, `TransportType`, `WorldPointUtil`, `CollisionMap` (not just `ShortestPathPlugin`). Produce the complete contract table. +2. **Introduce `Rs2PathApi`** (Microbot-owned, e.g. under `util/walker/`) — a thin facade delegating to today's `ShortestPathPlugin` statics 1:1. No behaviour change. +3. **Migrate consumers** to `Rs2PathApi`, one package at a time, compiling + smoke-testing the walker after each. Leave `Rs2Walker` for last (largest, riskiest). +4. **Backport behind the facade** — resume the Tier 1–5 items (wilderness widths #2, `PrimitiveIntList` #11, POH coverage #3, etc.) changing only internals; consumers untouched. +5. **(Optional) re-baseline** against latest `Skretzo/shortest-path` — the pinned comparison is `07fca57`; no upstream remote is configured yet. + +### Guardrails +- **No walker edits** until the facade exists and the contract is frozen. +- Keep every `ShortestPathPlugin` member above **binary-compatible** through the migration (the facade delegates; it does not replace them until all consumers move). +- Validate each stage with `./gradlew :client:compileJava` and the existing `ShortestPathTier1RegressionTest` / `PathfinderBenchmarkTest`. From 2119eb9e7771fb0fe5759af5a62e2688def1f320 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 17:58:08 +0100 Subject: [PATCH 07/48] Stage 1: catalogue full external shortestpath contract Read-only sweep of all 26 consumer files outside the shortestpath package. Documents the complete member surface Rs2PathApi must reproduce: - Pathfinder external surface: getPath, isDone (only 2). - PathfinderConfig: refresh, setUseBankItems, isUseBankItems, getTransports, getAllTransports, setIgnoreTeleportAndItems, isTransportUsableWithLeaguesContext, isUseSpiritTrees. - Transport: 15 getters/setters (getDestination/getDisplayInfo/getType dominate); TransportType: all 20 constants + isTeleport + valueOf. - WorldPointUtil: packWorldPoint/unpackWorldPoint/undergroundAwareDistance. - CollisionMap: only the static ignoreCollisionPacked field (Rs2Tile). Key finding: the facade only needs to wrap mutable plugin state (Pathfinder/PathfinderConfig/marker/future/mutex); Transport, TransportType and WorldPointUtil are pure data / pure functions and can stay as-is behind it. Docs only; no walker/engine code changed. Co-Authored-By: Claude Opus 4.8 --- .../WEBWALKER_IMPROVEMENT_PLAN.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md index 923405557d..3665cce8b0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md @@ -146,6 +146,51 @@ Verified 2026-07-20 by grepping all consumers under `plugins/microbot/`. `Pathfinder` external surface is small — only `getPath()` and `isDone()`. `PathfinderConfig` is heavily used *inside* `Rs2Walker` (43 refs) and by `leaguetransport` — its surface must be catalogued before Stage 2. +### Stage 1 catalogue — complete external contract (2026-07-20) + +Read-only sweep of all **26** consumer files (`grep` for `microbot.shortestpath` usage outside the `shortestpath/` package). Counts are call-site occurrences, distinct methods only. This is the surface `Rs2PathApi` must reproduce. + +**`Pathfinder`** (instance, via `ShortestPathPlugin.getPathfinder()`): + +| Member | Uses | +|---|---| +| `getPath()` | 1 | +| `isDone()` | 2 | + +**`PathfinderConfig`** (via `getPathfinderConfig()` / `pathfinderConfig`): + +| Member | Uses | +|---|---| +| `refresh()` | 18 | +| `setUseBankItems(boolean)` | 13 | +| `isUseBankItems()` | 5 | +| `getTransports()` | 4 | +| `getAllTransports()` | 2 | +| `setIgnoreTeleportAndItems(boolean)` | 2 | +| `isTransportUsableWithLeaguesContext(...)` | 2 | +| `isUseSpiritTrees()` | 1 | + +**`Transport`** (instance getters/setters): + +| Member | Uses | | Member | Uses | +|---|---|---|---|---| +| `getDestination()` | 96 | | `getName()` | 11 | +| `getDisplayInfo()` | 89 | | `getCurrencyAmount()` | 9 | +| `getType()` | 85 | | `getCurrencyName()` | 7 | +| `getOrigin()` | 48 | | `setItemIdRequirements(...)` | 3 | +| `getObjectId()` | 20 | | `isMembers()` | 2 | +| `getAction()` | 18 | | `getMaxWildernessLevel()` | 2 | +| `getItemIdRequirements()` | 14 | | `setName(String)` | 1 | +| | | | `distanceTo(...)` | 1 | + +**`TransportType`** (enum): all 20 constants referenced (`AGILITY_SHORTCUT`, `BOAT`, `CANOE`, `CHARTER_SHIP`, `FAIRY_RING`, `GNOME_GLIDER`, `MAGIC_CARPET`, `MINECART`, `NPC`, `POH`, `QUETZAL`, `SEASONAL_TRANSPORT`, `SHIP`, `SPIRIT_TREE`, `TELEPORTATION_ITEM`, `TELEPORTATION_MINIGAME`, `TELEPORTATION_PORTAL`, `TELEPORTATION_SPELL`, `TRANSPORT`, `WILDERNESS_OBELISK`) plus `isTeleport()` and `valueOf(...)`. + +**`WorldPointUtil`** (static): `packWorldPoint(...)` ×19, `unpackWorldPoint(...)` ×2, `undergroundAwareDistance(...)` ×2. (Note: also exposes `fromLocalInstance` internally — not called by consumers.) + +**`CollisionMap`**: only the static field `CollisionMap.ignoreCollisionPacked` (packed-point set), referenced once in `Rs2Tile`. No instance methods called externally. + +**Caveat:** counts include `Rs2Walker` (the largest consumer). `Transport` getter counts are call-sites, not distinct code paths. The `Transport`/`TransportType` value types and `WorldPointUtil` static helpers are cheap to keep as-is behind the facade (they are effectively pure data / pure functions); the facade's real job is wrapping the **mutable plugin state** (`Pathfinder`/`PathfinderConfig`/marker/future/mutex) enumerated in the contract table above. + ### Consumers to migrate (24 files) `util/walker/*` (Rs2Walker + lifecycle/awaits/banking/shared), `util/bank/Rs2Bank`, `util/depositbox/Rs2DepositBox`, `util/skills/slayer/Rs2Slayer`, `util/poh/*`, `util/leaguetransport/*`, `util/tile/Rs2Tile`, `util/reachable/Rs2Reachable`, `util/npc/Rs2NpcManager`, `questhelper/QuestScript`, `breakhandler/**`, `Script.java`. From e52b7815755fb6a042bf9bba13d395d74ea6aa58 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 19:52:57 +0100 Subject: [PATCH 08/48] Stage 2: add Rs2PathApi facade over shortestpath plugin state Introduce a Microbot-owned facade (util/walker/Rs2PathApi) that delegates 1:1 to ShortestPathPlugin's mutable static surface catalogued in Stage 1: pathfinder lifecycle (get/set pathfinder, future, executor, mutex), config (getPathfinderConfig, setReachedDistance, override x3), target/walker state (exit, start-point flag, lastLocation), marker get/set, and getTransports; plus the CONFIG_GROUP and MARKER_IMAGE constants. Thin delegation only: no behaviour change, no state of its own. Value types (Pathfinder, PathfinderConfig, Transport) are intentionally not re-wrapped - they are the stable Microbot-facing path API. No consumers migrated yet (that is Stage 3, walker last); ShortestPathPlugin members stay public and binary-compatible until then. Compiles clean (:client:compileJava). Walker untouched. Co-Authored-By: Claude Opus 4.8 --- .../microbot/util/walker/Rs2PathApi.java | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java new file mode 100644 index 0000000000..bd39058ff2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java @@ -0,0 +1,176 @@ +package net.runelite.client.plugins.microbot.util.walker; + +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.shortestpath.TeleportationItem; +import net.runelite.client.plugins.microbot.shortestpath.Transport; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; +import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; + +import java.awt.image.BufferedImage; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +/** + * Microbot-owned facade over the shortest-path plugin's mutable static state. + * + *

Why this exists (Stage 2 of the facade migration — see + * {@code shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md} "Facade migration"). + * Automation code ({@code Rs2Walker} and ~25 other consumers) currently reaches directly into + * {@link ShortestPathPlugin}'s public static fields and accessors. Every time an upstream + * (Skretzo/shortest-path) fix touches that internal wiring, the walker is at risk. Routing all + * plugin-state access through this single class freezes the surface the walker sees, so future + * upstream backports can change the plugin internals while only this facade (and not every + * consumer) has to move with them.

+ * + *

Contract. This is a thin, 1:1 delegation. Every method here forwards verbatim to + * the corresponding {@link ShortestPathPlugin} static member catalogued in the Stage 1 sweep. It + * intentionally introduces no behaviour change and holds no state of its own. The + * value types it returns ({@link Pathfinder}, {@link PathfinderConfig}, {@link Transport}, + * {@code TransportType}, {@code WorldPointUtil}) are treated as the stable Microbot-facing path API + * and are deliberately not re-wrapped — they are pure data / pure functions.

+ * + *

Migration status. No consumers have been switched over yet; that is Stage 3, done one + * package at a time with the walker last. Until then {@link ShortestPathPlugin}'s members remain + * public and binary-compatible. Do not add logic here — if a call needs new behaviour, put it + * behind the plugin and expose it through a matching delegate.

+ */ +public final class Rs2PathApi +{ + private Rs2PathApi() + { + } + + /** Config group key for the shortest-path plugin ({@link ShortestPathPlugin#CONFIG_GROUP}). */ + public static final String CONFIG_GROUP = ShortestPathPlugin.CONFIG_GROUP; + + /** Shared world-map marker sprite ({@link ShortestPathPlugin#MARKER_IMAGE}). */ + public static final BufferedImage MARKER_IMAGE = ShortestPathPlugin.MARKER_IMAGE; + + // ------------------------------------------------------------------ + // Pathfinder lifecycle + // ------------------------------------------------------------------ + + /** @return the current pathfinder instance, or {@code null} if none is running. */ + public static Pathfinder getPathfinder() + { + return ShortestPathPlugin.getPathfinder(); + } + + public static void setPathfinder(Pathfinder pathfinder) + { + ShortestPathPlugin.setPathfinder(pathfinder); + } + + /** @return the {@link Future} tracking the in-flight pathfinding task, or {@code null}. */ + public static Future getPathfinderFuture() + { + return ShortestPathPlugin.getPathfinderFuture(); + } + + public static void setPathfinderFuture(Future future) + { + ShortestPathPlugin.setPathfinderFuture(future); + } + + /** @return the single-threaded executor pathfinding runs on. */ + public static ExecutorService getPathfindingExecutor() + { + return ShortestPathPlugin.getPathfindingExecutor(); + } + + public static void setPathfindingExecutor(ExecutorService executor) + { + ShortestPathPlugin.setPathfindingExecutor(executor); + } + + /** @return the monitor guarding pathfinder start/cancel transitions. */ + public static Object getPathfinderMutex() + { + return ShortestPathPlugin.getPathfinderMutex(); + } + + // ------------------------------------------------------------------ + // Config + // ------------------------------------------------------------------ + + /** @return the shared pathfinder configuration (transports, restrictions, toggles). */ + public static PathfinderConfig getPathfinderConfig() + { + return ShortestPathPlugin.getPathfinderConfig(); + } + + /** Distance from the target at which the path is considered reached. */ + public static void setReachedDistance(int reachedDistance) + { + ShortestPathPlugin.setReachedDistance(reachedDistance); + } + + public static boolean override(String configOverrideKey, boolean defaultValue) + { + return ShortestPathPlugin.override(configOverrideKey, defaultValue); + } + + public static int override(String configOverrideKey, int defaultValue) + { + return ShortestPathPlugin.override(configOverrideKey, defaultValue); + } + + public static TeleportationItem override(String configOverrideKey, TeleportationItem defaultValue) + { + return ShortestPathPlugin.override(configOverrideKey, defaultValue); + } + + // ------------------------------------------------------------------ + // Target / walker state + // ------------------------------------------------------------------ + + /** Clears the active target and tears down the current path (see {@link ShortestPathPlugin#exit()}). */ + public static void exit() + { + ShortestPathPlugin.exit(); + } + + public static boolean isStartPointSet() + { + return ShortestPathPlugin.isStartPointSet(); + } + + public static void setStartPointSet(boolean startPointSet) + { + ShortestPathPlugin.setStartPointSet(startPointSet); + } + + /** Records the player's last known world location (write-only on the plugin). */ + public static void setLastLocation(WorldPoint lastLocation) + { + ShortestPathPlugin.setLastLocation(lastLocation); + } + + // ------------------------------------------------------------------ + // Marker (world-map overlay) + // ------------------------------------------------------------------ + + public static WorldMapPoint getMarker() + { + return ShortestPathPlugin.getMarker(); + } + + public static void setMarker(WorldMapPoint marker) + { + ShortestPathPlugin.setMarker(marker); + } + + // ------------------------------------------------------------------ + // Transport data + // ------------------------------------------------------------------ + + /** @return the transport graph keyed by origin tile. */ + public static Map> getTransports() + { + return ShortestPathPlugin.getTransports(); + } +} From eb0e274d430d0fa8b8a3135ff9f471c4fb129411 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 19:58:11 +0100 Subject: [PATCH 09/48] Stage 3a: migrate leaf consumers to Rs2PathApi Route the low-risk, single-package consumers through the facade instead of ShortestPathPlugin directly: - Script.exit path -> Rs2PathApi.exit - questhelper/QuestScript -> Rs2PathApi.getMarker/exit/getPathfinder - util/bank/Rs2Bank, util/depositbox/Rs2DepositBox, util/npc/Rs2NpcManager, util/skills/slayer/Rs2Slayer -> Rs2PathApi.getPathfinderConfig - util/leaguetransport/Rs2LeaguesTransport: field access ShortestPathPlugin.pathfinderConfig -> Rs2PathApi.getPathfinderConfig() Import-only swap where all refs were method calls; value-type imports (Pathfinder, Transport, TransportType, PathfinderConfig) kept as-is. MicrobotPluginChoice keeps ShortestPathPlugin.class (config registration, not state). No residual ShortestPathPlugin refs in migrated files. Rs2Walker deferred to last. Compiles clean (:client:compileJava, exit 0). Co-Authored-By: Claude Opus 4.8 --- .../runelite/client/plugins/microbot/Script.java | 4 ++-- .../microbot/questhelper/QuestScript.java | 16 ++++++++-------- .../plugins/microbot/util/bank/Rs2Bank.java | 8 ++++---- .../microbot/util/depositbox/Rs2DepositBox.java | 8 ++++---- .../leaguetransport/Rs2LeaguesTransport.java | 4 ++-- .../plugins/microbot/util/npc/Rs2NpcManager.java | 8 ++++---- .../microbot/util/skills/slayer/Rs2Slayer.java | 6 +++--- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java index 9994f5eb40..9b2a503ed7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java @@ -3,7 +3,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.util.Global; import net.runelite.client.plugins.microbot.agentserver.handler.ScriptHeartbeatRegistry; import net.runelite.client.plugins.microbot.util.antiban.SessionFatigue; @@ -56,7 +56,7 @@ public void shutdown() { ScriptHeartbeatRegistry.remove(this.getClass().getName()); if (mainScheduledFuture != null && !mainScheduledFuture.isDone()) { mainScheduledFuture.cancel(true); - ShortestPathPlugin.exit(); + Rs2PathApi.exit(); if (Microbot.getClientThread().scheduledFuture != null) Microbot.getClientThread().scheduledFuture.cancel(true); initialPlayerLocation = null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestScript.java index 1ccfffa404..1fd3d3d569 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestScript.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/questhelper/QuestScript.java @@ -18,7 +18,7 @@ import net.runelite.client.plugins.microbot.questhelper.requirements.item.ItemRequirement; import net.runelite.client.plugins.microbot.questhelper.steps.*; import net.runelite.client.plugins.microbot.questhelper.steps.widget.WidgetHighlight; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; import net.runelite.client.plugins.microbot.util.camera.Rs2Camera; import net.runelite.client.plugins.microbot.util.combat.Rs2Combat; @@ -234,8 +234,8 @@ public boolean run(QuestHelperConfig config, QuestHelperPlugin mQuestPlugin) { boolean isInCutscene = Microbot.getVarbitValue(4606) > 0; if (isInCutscene) { - if (ShortestPathPlugin.getMarker() != null) - ShortestPathPlugin.exit(); + if (Rs2PathApi.getMarker() != null) + Rs2PathApi.exit(); return; } @@ -1385,11 +1385,11 @@ public boolean applyObjectStep(ObjectStep step) { for (var tile : Rs2Tile.getWalkableTilesAroundTile(object.getWorldLocation(), unreachableTargetCheckDist)) { if (tileObjects.stream().noneMatch(x -> x.getWorldLocation().equals(tile))) { - if (!Rs2Walker.walkTo(tile) && ShortestPathPlugin.getPathfinder() == null) + if (!Rs2Walker.walkTo(tile) && Rs2PathApi.getPathfinder() == null) return false; - sleepUntil(() -> ShortestPathPlugin.getPathfinder() == null || ShortestPathPlugin.getPathfinder().isDone()); - if (ShortestPathPlugin.getPathfinder() == null || ShortestPathPlugin.getPathfinder().isDone()) { + sleepUntil(() -> Rs2PathApi.getPathfinder() == null || Rs2PathApi.getPathfinder().isDone()); + if (Rs2PathApi.getPathfinder() == null || Rs2PathApi.getPathfinder().isDone()) { unreachableTarget = false; unreachableTargetCheckDist = 1; } @@ -1424,8 +1424,8 @@ public boolean applyObjectStep(ObjectStep step) { Rs2Walker.walkTo(targetTile, 3); - if (ShortestPathPlugin.getPathfinder() != null) { - var path = ShortestPathPlugin.getPathfinder().getPath(); + if (Rs2PathApi.getPathfinder() != null) { + var path = Rs2PathApi.getPathfinder().getPath(); if (path.get(path.size() - 1).distanceTo(step.getDefinedPoint().getWorldPoint()) <= 1) return false; } else diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/bank/Rs2Bank.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/bank/Rs2Bank.java index e93e6ebe13..daea787f20 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/bank/Rs2Bank.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/bank/Rs2Bank.java @@ -18,8 +18,8 @@ import net.runelite.client.plugins.loottracker.LootTrackerRecord; import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.api.player.models.Rs2PlayerModel; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.util.antiban.Rs2AntibanSettings; import net.runelite.client.plugins.microbot.util.bank.enums.BankLocation; import net.runelite.client.plugins.microbot.util.coords.Rs2WorldPoint; @@ -2327,12 +2327,12 @@ private static AbstractMap.SimpleEntry, BankLocation> getPathAn .map(BankLocation::getWorldPoint) .collect(Collectors.toSet()); - if (ShortestPathPlugin.getPathfinderConfig().getTransports().isEmpty()) { - ShortestPathPlugin.getPathfinderConfig().refresh(); + if (Rs2PathApi.getPathfinderConfig().getTransports().isEmpty()) { + Rs2PathApi.getPathfinderConfig().refresh(); } long originalStart = System.nanoTime(); - Pathfinder pf = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), worldPoint, targets); + Pathfinder pf = new Pathfinder(Rs2PathApi.getPathfinderConfig(), worldPoint, targets); pf.run(); List path = pf.getPath(); long originalTime = System.nanoTime() - originalStart; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/depositbox/Rs2DepositBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/depositbox/Rs2DepositBox.java index f60a2cb99b..97d62afaef 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/depositbox/Rs2DepositBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/depositbox/Rs2DepositBox.java @@ -7,8 +7,8 @@ import net.runelite.api.coords.WorldPoint; import net.runelite.api.widgets.Widget; import net.runelite.client.plugins.microbot.Microbot; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.util.gameobject.Rs2BankID; import net.runelite.client.plugins.microbot.util.gameobject.Rs2GameObject; import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory; @@ -492,11 +492,11 @@ public static DepositBoxLocation getNearestDepositBox(WorldPoint worldPoint, int .map(DepositBoxLocation::getWorldPoint) .collect(Collectors.toSet()); - if (ShortestPathPlugin.getPathfinderConfig().getTransports().isEmpty()) { - ShortestPathPlugin.getPathfinderConfig().refresh(); + if (Rs2PathApi.getPathfinderConfig().getTransports().isEmpty()) { + Rs2PathApi.getPathfinderConfig().refresh(); } - Pathfinder pf = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), worldPoint, targets); + Pathfinder pf = new Pathfinder(Rs2PathApi.getPathfinderConfig(), worldPoint, targets); pf.run(); List path = pf.getPath(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/leaguetransport/Rs2LeaguesTransport.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/leaguetransport/Rs2LeaguesTransport.java index 09fdec97b9..3605091d60 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/leaguetransport/Rs2LeaguesTransport.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/leaguetransport/Rs2LeaguesTransport.java @@ -2,7 +2,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.shortestpath.Transport; import net.runelite.client.plugins.microbot.shortestpath.TransportType; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; @@ -198,7 +198,7 @@ public static boolean isTransportAllowed(LeaguesContext ctx, Transport transport public static void invalidateContext() { - PathfinderConfig cfg = ShortestPathPlugin.pathfinderConfig; + PathfinderConfig cfg = Rs2PathApi.getPathfinderConfig(); if (cfg != null) { cfg.invalidateTransportRefreshCache(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/npc/Rs2NpcManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/npc/Rs2NpcManager.java index a63d7687a8..e452669288 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/npc/Rs2NpcManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/npc/Rs2NpcManager.java @@ -5,7 +5,7 @@ import com.google.gson.reflect.TypeToken; import net.runelite.api.coords.WorldPoint; import net.runelite.client.plugins.microbot.Microbot; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.util.walker.Rs2Walker; import org.slf4j.event.Level; @@ -285,8 +285,8 @@ public static List getNpcLocations(String npcName) * @param avoidWilderness Whether to avoid locations in the Wilderness. */ public static MonsterLocation getClosestLocation(String npcName, int minClustering, boolean avoidWilderness) { - boolean originalUseBankItems = ShortestPathPlugin.getPathfinderConfig().isUseBankItems(); - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(true); + boolean originalUseBankItems = Rs2PathApi.getPathfinderConfig().isUseBankItems(); + Rs2PathApi.getPathfinderConfig().setUseBankItems(true); Microbot.log(Level.INFO,"Finding closest location for: " + npcName); List allLocations = getNpcLocations(npcName); @@ -327,7 +327,7 @@ public static MonsterLocation getClosestLocation(String npcName, int minClusteri } Microbot.log(Level.INFO,"Closest location for " + npcName + ": " + closest.getLocationName()); - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(originalUseBankItems); + Rs2PathApi.getPathfinderConfig().setUseBankItems(originalUseBankItems); return closest; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/skills/slayer/Rs2Slayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/skills/slayer/Rs2Slayer.java index 3574882938..517fb328df 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/skills/slayer/Rs2Slayer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/skills/slayer/Rs2Slayer.java @@ -5,7 +5,7 @@ import net.runelite.api.gameval.ItemID; import net.runelite.api.gameval.VarPlayerID; import net.runelite.client.plugins.microbot.Microbot; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.shortestpath.Transport; import net.runelite.client.plugins.microbot.shortestpath.TransportType; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; @@ -268,7 +268,7 @@ public static boolean walkToSlayerMaster(SlayerMaster master) { * @return the list */ public static List prepareItemTransports(WorldPoint cachedMonsterLocation) { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(true); + Rs2PathApi.getPathfinderConfig().setUseBankItems(true); List transports = Rs2Walker.getTransportsForPath(Rs2Walker.getWalkPath(cachedMonsterLocation), 0) .stream() .filter(t -> t.getType() == TransportType.TELEPORTATION_ITEM || t.getType() == TransportType.FAIRY_RING) @@ -278,7 +278,7 @@ public static List prepareItemTransports(WorldPoint cachedMonsterLoca } }) .collect(Collectors.toList()); - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(false); + Rs2PathApi.getPathfinderConfig().setUseBankItems(false); transports .forEach(t -> Microbot.log(Level.DEBUG,"Item required: " + t)); From 6ee086b835701eef4f307764fa36669655fe5674 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 19:59:58 +0100 Subject: [PATCH 10/48] Stage 3b: migrate walker-package helpers to Rs2PathApi Route the walker subpackage helpers through the facade: - lifecycle/Rs2WalkerLifecycleRuntime (26 refs): marker, pathfinder, future, executor, config, start-point, lastLocation, MARKER_IMAGE - banking/Rs2WalkerBankingPlanner (13 refs): getPathfinderConfig, override MARKER_IMAGE resolves to the facade's re-exported constant. Value-type imports (Pathfinder, Transport, TransportType) kept. awaits/ and shared/ subpackages import only value types (Pathfinder/WorldPointUtil) and need no migration. No residual ShortestPathPlugin refs; Rs2Walker.java (77 refs) remains for the final Stage 3c pass. Compiles clean (:client:compileJava, exit 0). Co-Authored-By: Claude Opus 4.8 --- .../banking/Rs2WalkerBankingPlanner.java | 26 +++++----- .../lifecycle/Rs2WalkerLifecycleRuntime.java | 52 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java index 287a41bba8..8c4c153652 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java @@ -8,7 +8,7 @@ import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; import net.runelite.client.plugins.microbot.util.magic.Rs2Magic; import net.runelite.client.plugins.microbot.util.magic.Rs2Spells; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.shortestpath.Transport; import net.runelite.client.plugins.microbot.shortestpath.TransportType; import net.runelite.client.plugins.microbot.util.equipment.Rs2Equipment; @@ -40,11 +40,11 @@ public static List getTransportsForDestination(WorldPoint destination return new ArrayList<>(); } - boolean originalUseBankItems = ShortestPathPlugin.getPathfinderConfig().isUseBankItems(); + boolean originalUseBankItems = Rs2PathApi.getPathfinderConfig().isUseBankItems(); try { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(useBankItems); - ShortestPathPlugin.getPathfinderConfig().refresh(); - Pathfinder pf = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), Rs2Player.getWorldLocation(), destination); + Rs2PathApi.getPathfinderConfig().setUseBankItems(useBankItems); + Rs2PathApi.getPathfinderConfig().refresh(); + Pathfinder pf = new Pathfinder(Rs2PathApi.getPathfinderConfig(), Rs2Player.getWorldLocation(), destination); pf.run(); List path = pf.getPath(); @@ -57,8 +57,8 @@ public static List getTransportsForDestination(WorldPoint destination transports.forEach(t -> log.debug("Transport found: " + t)); return transports; } finally { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(originalUseBankItems); - ShortestPathPlugin.getPathfinderConfig().refresh(); + Rs2PathApi.getPathfinderConfig().setUseBankItems(originalUseBankItems); + Rs2PathApi.getPathfinderConfig().refresh(); } } @@ -223,10 +223,10 @@ public static TransportRouteAnalysis compareRoutes(WorldPoint startPoint, WorldP int bankingRouteDistance = -1; try { - boolean originalUseBankItems = ShortestPathPlugin.getPathfinderConfig().isUseBankItems(); + boolean originalUseBankItems = Rs2PathApi.getPathfinderConfig().isUseBankItems(); try { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(true); - ShortestPathPlugin.getPathfinderConfig().refresh(target); + Rs2PathApi.getPathfinderConfig().setUseBankItems(true); + Rs2PathApi.getPathfinderConfig().refresh(target); performanceLog.append("\t-Bank items available: ").append(Rs2Bank.bankItems().size()).append("\n"); @@ -307,8 +307,8 @@ public static TransportRouteAnalysis compareRoutes(WorldPoint startPoint, WorldP .append("\t -> No accessible bank found\n"); } } finally { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(originalUseBankItems); - ShortestPathPlugin.getPathfinderConfig().refresh(); + Rs2PathApi.getPathfinderConfig().setUseBankItems(originalUseBankItems); + Rs2PathApi.getPathfinderConfig().refresh(); } } catch (Exception e) { performanceLog.append("Banking route calculation failed: ").append(e.getMessage()).append("\n"); @@ -329,7 +329,7 @@ public static TransportRouteAnalysis compareRoutes(WorldPoint startPoint, WorldP final boolean tie = directDistance == bankingRouteDistance; final boolean directStrictlyFaster = directDistance < bankingRouteDistance; - final boolean preferTransportToTarget = ShortestPathPlugin.override("preferTransportToTarget", false); + final boolean preferTransportToTarget = Rs2PathApi.override("preferTransportToTarget", false); final String recommendation; final String verdictOneLine; if (tie) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/lifecycle/Rs2WalkerLifecycleRuntime.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/lifecycle/Rs2WalkerLifecycleRuntime.java index 81cad073df..a5b1d020cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/lifecycle/Rs2WalkerLifecycleRuntime.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/lifecycle/Rs2WalkerLifecycleRuntime.java @@ -7,8 +7,8 @@ import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.client.plugins.microbot.Microbot; -import net.runelite.client.plugins.microbot.shortestpath.ShortestPathPlugin; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; +import net.runelite.client.plugins.microbot.util.walker.Rs2PathApi; import net.runelite.client.plugins.microbot.util.player.Rs2Player; import net.runelite.client.plugins.microbot.util.walker.Rs2Walker; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; @@ -38,7 +38,7 @@ public static void applyWalkerDestination(WorldPoint target) { return; } Player localPlayer = Microbot.getClientThread().invoke(() -> client.getLocalPlayer()); - if (!ShortestPathPlugin.isStartPointSet() && localPlayer == null) { + if (!Rs2PathApi.isStartPointSet() && localPlayer == null) { log.warn("Start point is not set and player is null"); return; } @@ -48,12 +48,12 @@ public static void applyWalkerDestination(WorldPoint target) { Rs2Walker.clearWalkingRoute("walker:wmm-unavailable retry-setTarget dest=" + target); return; } - wmm.removeIf(x -> x == ShortestPathPlugin.getMarker()); - ShortestPathPlugin.setMarker(new WorldMapPoint(target, ShortestPathPlugin.MARKER_IMAGE)); - ShortestPathPlugin.getMarker().setName("Target"); - ShortestPathPlugin.getMarker().setTarget(ShortestPathPlugin.getMarker().getWorldPoint()); - ShortestPathPlugin.getMarker().setJumpOnClick(true); - wmm.add(ShortestPathPlugin.getMarker()); + wmm.removeIf(x -> x == Rs2PathApi.getMarker()); + Rs2PathApi.setMarker(new WorldMapPoint(target, Rs2PathApi.MARKER_IMAGE)); + Rs2PathApi.getMarker().setName("Target"); + Rs2PathApi.getMarker().setTarget(Rs2PathApi.getMarker().getWorldPoint()); + Rs2PathApi.getMarker().setJumpOnClick(true); + wmm.add(Rs2PathApi.getMarker()); WorldPoint start = Microbot.getClientThread().invoke(() -> { if (client.getTopLevelWorldView().isInstance()) { @@ -74,11 +74,11 @@ public static void applyWalkerDestination(WorldPoint target) { } return Rs2Player.getWorldLocation(); }); - final Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); - final WorldPoint effectiveStart = (ShortestPathPlugin.isStartPointSet() && pathfinder != null) + final Pathfinder pathfinder = Rs2PathApi.getPathfinder(); + final WorldPoint effectiveStart = (Rs2PathApi.isStartPointSet() && pathfinder != null) ? pathfinder.getStart() : start; - ShortestPathPlugin.setLastLocation(effectiveStart); + Rs2PathApi.setLastLocation(effectiveStart); Microbot.getClientThread().runOnSeperateThread(() -> restartPathfinding(effectiveStart, target)); } @@ -87,33 +87,33 @@ public static boolean restartPathfinding(WorldPoint start, WorldPoint end) { } public static boolean restartPathfinding(WorldPoint start, Set ends) { - Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder != null) { pathfinder.cancel(); - if (ShortestPathPlugin.getPathfinderFuture() != null) { - ShortestPathPlugin.getPathfinderFuture().cancel(true); + if (Rs2PathApi.getPathfinderFuture() != null) { + Rs2PathApi.getPathfinderFuture().cancel(true); } } - if (ShortestPathPlugin.getPathfindingExecutor() == null) { + if (Rs2PathApi.getPathfindingExecutor() == null) { ThreadFactory shortestPathNaming = new ThreadFactoryBuilder().setNameFormat("shortest-path-%d").build(); - ShortestPathPlugin.setPathfindingExecutor(Executors.newSingleThreadExecutor(shortestPathNaming)); + Rs2PathApi.setPathfindingExecutor(Executors.newSingleThreadExecutor(shortestPathNaming)); } WorldPoint refreshTarget = ends != null && !ends.isEmpty() ? ends.iterator().next() : null; - ShortestPathPlugin.getPathfinderConfig().refresh(refreshTarget); + Rs2PathApi.getPathfinderConfig().refresh(refreshTarget); if (Rs2Player.isInCave()) { - pathfinder = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), start, ends); + pathfinder = new Pathfinder(Rs2PathApi.getPathfinderConfig(), start, ends); pathfinder.run(); try { - ShortestPathPlugin.getPathfinderConfig().setIgnoreTeleportAndItems(true); - Pathfinder pathfinderWithoutTeleports = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), start, ends); + Rs2PathApi.getPathfinderConfig().setIgnoreTeleportAndItems(true); + Pathfinder pathfinderWithoutTeleports = new Pathfinder(Rs2PathApi.getPathfinderConfig(), start, ends); pathfinderWithoutTeleports.run(); boolean noTeleportPathAvailable = !pathfinderWithoutTeleports.getPath().isEmpty(); boolean basePathAvailable = pathfinder != null && !pathfinder.getPath().isEmpty(); if (!noTeleportPathAvailable) { - ShortestPathPlugin.setPathfinder(basePathAvailable ? pathfinder : pathfinderWithoutTeleports); + Rs2PathApi.setPathfinder(basePathAvailable ? pathfinder : pathfinderWithoutTeleports); return true; } @@ -123,16 +123,16 @@ public static boolean restartPathfinding(WorldPoint start, Set ends) if (pathWithoutTeleportsIsReachable && basePathAvailable && pathfinder.getPath().size() >= pathfinderWithoutTeleports.getPath().size()) { - ShortestPathPlugin.setPathfinder(pathfinderWithoutTeleports); + Rs2PathApi.setPathfinder(pathfinderWithoutTeleports); } else { - ShortestPathPlugin.setPathfinder(basePathAvailable ? pathfinder : pathfinderWithoutTeleports); + Rs2PathApi.setPathfinder(basePathAvailable ? pathfinder : pathfinderWithoutTeleports); } } finally { - ShortestPathPlugin.getPathfinderConfig().setIgnoreTeleportAndItems(false); + Rs2PathApi.getPathfinderConfig().setIgnoreTeleportAndItems(false); } } else { - ShortestPathPlugin.setPathfinder(new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), start, ends)); - ShortestPathPlugin.setPathfinderFuture(ShortestPathPlugin.getPathfindingExecutor().submit(ShortestPathPlugin.getPathfinder())); + Rs2PathApi.setPathfinder(new Pathfinder(Rs2PathApi.getPathfinderConfig(), start, ends)); + Rs2PathApi.setPathfinderFuture(Rs2PathApi.getPathfindingExecutor().submit(Rs2PathApi.getPathfinder())); } return true; } From e6e7f0c1fcf138e4237a938138c705094b3d7faf Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 20:03:39 +0100 Subject: [PATCH 11/48] Stage 3c: migrate Rs2Walker to Rs2PathApi (Stage 3 complete) Route the walker itself (77 refs) through the facade. Rs2PathApi is in the same package so no import is needed; the shortestpath.* wildcard import stays for value types (Transport/TransportType/WorldPointUtil/etc). - 5x ShortestPathPlugin.pathfinderConfig field reads -> getPathfinderConfig() - all method calls -> Rs2PathApi.* - method reference ShortestPathPlugin::getPathfinder -> Rs2PathApi::getPathfinder - javadoc {@link ShortestPathPlugin#...} -> {@link Rs2PathApi#...} No field assignments existed, so no missing-setter issues. Zero residual ShortestPathPlugin refs in Rs2Walker. All consumers now go through the facade; ShortestPathPlugin's public static surface is fully wrapped. Verified: :client:compileJava exit 0; shortestpath unit+regression suite green (73 tests: ShortestPathCoreTest 43, ShortestPathTier1RegressionTest 18, PathSmootherTest 6, TransportTypeTest 4, benchmark/refresh 1+1; 0 failures, 0 errors). Co-Authored-By: Claude Opus 4.8 --- .../microbot/util/walker/Rs2Walker.java | 154 +++++++++--------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 6bf2a33f90..e1f52d2234 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -110,7 +110,7 @@ public class Rs2Walker { /** * Active Microbot walk destination ({@code null} when no scripted walk). ShortestPath overlay - * must not clear {@link ShortestPathPlugin#getPathfinder()} while this is non-null — otherwise + * must not clear {@link Rs2PathApi#getPathfinder()} while this is non-null — otherwise * {@link #processWalk} loses the pathfinder while {@link #currentTarget} stays set (pathfinder-still-null EXIT). */ public static WorldPoint getCurrentTarget() { @@ -1131,7 +1131,7 @@ private static WalkerState walkWithStateInternal(WorldPoint target, int distance return WalkerState.ARRIVED; } - final Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + final Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder != null && !pathfinder.isDone()) { return WalkerState.MOVING; } @@ -1143,7 +1143,7 @@ private static WalkerState walkWithStateInternal(WorldPoint target, int distance } else { currentTarget = target; } - ShortestPathPlugin.setReachedDistance(distance); + Rs2PathApi.setReachedDistance(distance); stuckCount = 0; lastMovedTimeMs = System.currentTimeMillis(); interimTargetWp = null; @@ -1227,11 +1227,11 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part return WalkerState.EXIT; } - Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder == null) { markStartupPhase("pf_wait_enter", target, "reason=pathfinder_null"); walkerDiag("pathfinder null; waiting up to 2000ms"); - pathfinder = sleepUntilNotNull(ShortestPathPlugin::getPathfinder, 2_000); + pathfinder = sleepUntilNotNull(Rs2PathApi::getPathfinder, 2_000); if (walkCancelledDiag(target, "processWalk:after-wait-pathfinder", processWalkTail)) { return WalkerState.EXIT; } @@ -1274,7 +1274,7 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part } pathfinderPendingSinceMs = 0L; - if (ShortestPathPlugin.getMarker() == null) { + if (Rs2PathApi.getMarker() == null) { restoreTargetMarker(target); } @@ -1592,7 +1592,7 @@ && shouldYieldForActiveRouteInterim(activeInterimPlayer, path, activeInterimNowM return WalkerState.EXIT; } - if (ShortestPathPlugin.getMarker() == null) { + if (Rs2PathApi.getMarker() == null) { restoreTargetMarker(target); } // Marker is a UI/overlay artifact (ShortestPath plugin). Walking must not depend @@ -1903,7 +1903,7 @@ && handleUnresolvedDoorNearRawPath(rawPath, rawEdgeStart, if (recoverIdx < 0) { recoverIdx = findFurthestClickableIndex(path, i, playerLoc, wp -> { - Set ts = ShortestPathPlugin.getTransports().get(wp); + Set ts = Rs2PathApi.getTransports().get(wp); return ts != null && !ts.isEmpty(); }, recoveryMinimapReach); @@ -1924,7 +1924,7 @@ && handleUnresolvedDoorNearRawPath(rawPath, rawEdgeStart, // (e.g. an undead tree). The planner avoids those via avoidDangerousNpcs, // but this runtime fallback would otherwise strand us in melee. Step the // target back along the path to the nearest non-hazard tile. - PathfinderConfig dangerCfg = ShortestPathPlugin.pathfinderConfig; + PathfinderConfig dangerCfg = Rs2PathApi.getPathfinderConfig(); if (dangerCfg != null && dangerCfg.isAvoidDangerousNpcs() && recoverTarget != null && dangerCfg.isDangerousAdjacentTile(WorldPointUtil.packWorldPoint(recoverTarget))) { int safeIdx = recoverIdx; @@ -2099,7 +2099,7 @@ && walkFastCanvas(recoverTarget)) { int targetIdx = findFurthestForwardClickableIndex(path, i, playerLoc, wp -> { - Set ts = ShortestPathPlugin.getTransports().get(wp); + Set ts = Rs2PathApi.getTransports().get(wp); return ts != null && !ts.isEmpty(); }, MINIMAP_REACH_EUCLIDEAN); @@ -2410,7 +2410,7 @@ && walkFastCanvas(recoverTarget)) { } WebWalkLog.partialExhausted(finalDist); Telemetry.recordUnreachable("partial-retries-exhausted", Rs2Player.getWorldLocation(), - target, Rs2Player.getWorldLocation(), 0, distance, ShortestPathPlugin.getPathfinder()); + target, Rs2Player.getWorldLocation(), 0, distance, Rs2PathApi.getPathfinder()); setTarget(null, "rs2walker:processWalk:partial-retries-exhausted"); return WalkerState.UNREACHABLE; } else { @@ -3042,7 +3042,7 @@ private static boolean tryIssueRouteMovementClick(List rawPath, if (clickTarget == null) { int clickableIdx = findFurthestForwardClickableIndex(path, startIdx, playerLoc, wp -> { - Set ts = ShortestPathPlugin.getTransports().get(wp); + Set ts = Rs2PathApi.getTransports().get(wp); return ts != null && !ts.isEmpty(); }, maxEuclidean); @@ -3263,10 +3263,10 @@ public static WorldPoint walkCanvas(WorldPoint worldPoint) { * @return total amount of tiles */ public static int getTotalTiles(WorldPoint start, WorldPoint destination) { - if (ShortestPathPlugin.getPathfinderConfig().getTransports().isEmpty()) { - ShortestPathPlugin.getPathfinderConfig().refresh(); + if (Rs2PathApi.getPathfinderConfig().getTransports().isEmpty()) { + Rs2PathApi.getPathfinderConfig().refresh(); } - Pathfinder pathfinder = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), start, destination); + Pathfinder pathfinder = new Pathfinder(Rs2PathApi.getPathfinderConfig(), start, destination); pathfinder.run(); List path = pathfinder.getPath(); if (path.isEmpty() || path.get(path.size() - 1).getPlane() != destination.getPlane()) return Integer.MAX_VALUE; @@ -3338,7 +3338,7 @@ public static int getTotalTiles(WorldPoint destination) { // takes an avg 200-300 ms // Used mainly for agility, might have to tweak this for other stuff public static boolean canReach(WorldPoint worldPoint, int sizeX, int sizeY, int pathSizeX, int pathSizeY,boolean useBankedItems) { - boolean originalUseBankItems = ShortestPathPlugin.getPathfinderConfig().isUseBankItems(); + boolean originalUseBankItems = Rs2PathApi.getPathfinderConfig().isUseBankItems(); WorldArea pathArea = null; // Create centered WorldArea for the object instead of corner-based @@ -3350,12 +3350,12 @@ public static boolean canReach(WorldPoint worldPoint, int sizeX, int sizeY, int WorldArea objectArea = new WorldArea(objectSouthWest, sizeX + 2, sizeY + 2); try { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(useBankedItems); - ShortestPathPlugin.getPathfinderConfig().refresh(worldPoint); - if (ShortestPathPlugin.getPathfinderConfig().getTransports().isEmpty()) { - ShortestPathPlugin.getPathfinderConfig().refresh(worldPoint); + Rs2PathApi.getPathfinderConfig().setUseBankItems(useBankedItems); + Rs2PathApi.getPathfinderConfig().refresh(worldPoint); + if (Rs2PathApi.getPathfinderConfig().getTransports().isEmpty()) { + Rs2PathApi.getPathfinderConfig().refresh(worldPoint); } - Pathfinder pathfinder = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), Rs2Player.getWorldLocation(), worldPoint); + Pathfinder pathfinder = new Pathfinder(Rs2PathApi.getPathfinderConfig(), Rs2Player.getWorldLocation(), worldPoint); pathfinder.run(); // Create centered WorldArea for the path endpoint instead of corner-based @@ -3370,8 +3370,8 @@ public static boolean canReach(WorldPoint worldPoint, int sizeX, int sizeY, int log.trace("Exception in canReach: {} - ", e.getMessage(), e); return false; } finally { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(originalUseBankItems); - ShortestPathPlugin.getPathfinderConfig().refresh(worldPoint); + Rs2PathApi.getPathfinderConfig().setUseBankItems(originalUseBankItems); + Rs2PathApi.getPathfinderConfig().refresh(worldPoint); } return pathArea != null ? pathArea.intersectsWith2D(objectArea) : false; } @@ -3413,9 +3413,9 @@ public static boolean canReach(WorldPoint worldPoint, int sizeX, int sizeY, bool */ public static List getWalkPath(WorldPoint start, WorldPoint target) { long startTime = System.nanoTime(); - ShortestPathPlugin.getPathfinderConfig().refresh(target); + Rs2PathApi.getPathfinderConfig().refresh(target); long pathfinderStartTime = System.nanoTime(); - Pathfinder pathfinderLocal = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), start, target); + Pathfinder pathfinderLocal = new Pathfinder(Rs2PathApi.getPathfinderConfig(), start, target); pathfinderLocal.run(); List path = pathfinderLocal.getPath(); long pathfinderEndTime = System.nanoTime(); @@ -3503,7 +3503,7 @@ public static List getTransportsForPath(List path, int in while (currentIndex < path.size()) { WorldPoint currentPoint = path.get(currentIndex); // Get any transports that start at this point (or keyed by this point) - Set transportsAtPoint = ShortestPathPlugin.getTransports().get(currentPoint); + Set transportsAtPoint = Rs2PathApi.getTransports().get(currentPoint); if (transportsAtPoint == null || transportsAtPoint.isEmpty()) { currentIndex++; continue; @@ -3679,7 +3679,7 @@ public static int distanceToRegion(int regionX, int regionY) { } private static boolean handleRockfall(List path, int index) { - if (ShortestPathPlugin.getPathfinder() == null) return false; + if (Rs2PathApi.getPathfinder() == null) return false; if (index == path.size() - 1) return false; @@ -4297,7 +4297,7 @@ private static boolean handleCurrentTileTransportTowardPath(List raw // off-path loops, and getTransports() is already the usable (config/quest/level-filtered) set, // so we never grab a transport the pathfinder excluded. final int NEARBY_TRANSPORT_REACH = 5; - Map> transportsByOrigin = ShortestPathPlugin.getTransports(); + Map> transportsByOrigin = Rs2PathApi.getTransports(); Set transports = new HashSet<>(); Set transportsOnPlayerTile = transportsByOrigin.get(playerLoc); if (transportsOnPlayerTile != null) { @@ -4744,7 +4744,7 @@ private static boolean handleDoors(List path, int index) { } private static boolean handleDoors(List path, int index, boolean allowSegmentProbe) { - if (ShortestPathPlugin.getPathfinder() == null || index >= path.size() - 1) return false; + if (Rs2PathApi.getPathfinder() == null || index >= path.size() - 1) return false; // Skip any door whose tile was blacklisted after a prior quest-lock detection — // avoid re-triggering the same failed interact loop this session. @@ -4939,8 +4939,8 @@ && isNullOrPlaceholderObjectName(comp.getName())) { probe, name, action, dialogue); sessionBlacklistedDoors.add(probe); Rs2Dialogue.clickContinue(); - if (ShortestPathPlugin.pathfinderConfig != null) { - ShortestPathPlugin.pathfinderConfig.refresh(); + if (Rs2PathApi.getPathfinderConfig() != null) { + Rs2PathApi.getPathfinderConfig().refresh(); } recalculatePath(); } @@ -5098,8 +5098,8 @@ private static boolean tryHandleDoorObject(TileObject object, WorldPoint probe, probe, name, action, dialogue); sessionBlacklistedDoors.add(probe); Rs2Dialogue.clickContinue(); - if (ShortestPathPlugin.pathfinderConfig != null) { - ShortestPathPlugin.pathfinderConfig.refresh(); + if (Rs2PathApi.getPathfinderConfig() != null) { + Rs2PathApi.getPathfinderConfig().refresh(); } recalculatePath(); return true; @@ -5719,7 +5719,7 @@ private static boolean wasStationaryDoorOpenedRecently(WorldPoint doorTile) { } /** - * Strict catalog step: path tile equals transport origin in {@link ShortestPathPlugin#getTransports()} + * Strict catalog step: path tile equals transport origin in {@link Rs2PathApi#getTransports()} * and next tile equals that row's destination. Used where the walker must dispatch {@code handleTransports} * from the path index (origin keyed in the TSV-fed multimap). */ @@ -5746,7 +5746,7 @@ private static boolean hasImmediatePlannedTransportStep(List path, /** * Whether this path edge is covered by a transport catalog row (same coordinates loaded from TSV into - * {@link ShortestPathPlugin#getTransports()}). Includes strict origin-destination steps (including + * {@link Rs2PathApi#getTransports()}). Includes strict origin-destination steps (including * cross-plane rows such as ladders) and same-plane hops where the path starts on a tile Chebyshev-adjacent * to the catalog origin but still targets that row's destination, so door probing does not fight * {@code handleTransports}. @@ -5798,7 +5798,7 @@ private static boolean matchesDirectedTransportCatalogEdge(WorldPoint origin, Wo if (origin == null || dest == null) { return false; } - Set transports = ShortestPathPlugin.getTransports().get(origin); + Set transports = Rs2PathApi.getTransports().get(origin); if (transports == null || transports.isEmpty()) { return false; } @@ -5809,7 +5809,7 @@ private static boolean hasDoorLikeDirectedCatalogTransport(WorldPoint origin, Wo if (origin == null || dest == null) { return false; } - Set transports = ShortestPathPlugin.getTransports().get(origin); + Set transports = Rs2PathApi.getTransports().get(origin); if (transports == null || transports.isEmpty()) { return false; } @@ -5831,7 +5831,7 @@ private static boolean matchesAdjacentOriginShortTransportHop(WorldPoint from, W continue; } WorldPoint catalogOrigin = new WorldPoint(from.getX() + dx, from.getY() + dy, from.getPlane()); - Set transports = ShortestPathPlugin.getTransports().get(catalogOrigin); + Set transports = Rs2PathApi.getTransports().get(catalogOrigin); if (transports == null || transports.isEmpty()) { continue; } @@ -5855,7 +5855,7 @@ private static boolean hasDoorLikeAdjacentOriginShortTransportHop(WorldPoint fro continue; } WorldPoint catalogOrigin = new WorldPoint(from.getX() + dx, from.getY() + dy, from.getPlane()); - Set transports = ShortestPathPlugin.getTransports().get(catalogOrigin); + Set transports = Rs2PathApi.getTransports().get(catalogOrigin); if (transports == null || transports.isEmpty()) { continue; } @@ -5889,7 +5889,7 @@ private static boolean isDoorLikeTransportAction(String action) { /** * True when this scene object is the interactable listed on a transport catalog row (same - * coordinates and object ids as TSV loaded into {@link ShortestPathPlugin#getTransports()}). + * coordinates and object ids as TSV loaded into {@link Rs2PathApi#getTransports()}). * Door-ahead / fallback / LOS scans must treat it as non-door so {@link #handleTransports} owns it. */ private static boolean isCatalogTransportObject(TileObject object) { @@ -5904,7 +5904,7 @@ private static boolean isCatalogTransportObject(TileObject object) { if (id <= 0) { return false; } - Map> map = ShortestPathPlugin.getTransports(); + Map> map = Rs2PathApi.getTransports(); if (map == null || map.isEmpty()) { return false; } @@ -7562,7 +7562,7 @@ public static void setTarget(WorldPoint target, String clearReasonWhenNull) { return; } Player localPlayer = client.getLocalPlayer(); - if (!ShortestPathPlugin.isStartPointSet() && localPlayer == null) { + if (!Rs2PathApi.isStartPointSet() && localPlayer == null) { log.warn("Start point is not set and player is null"); return; } @@ -7573,34 +7573,34 @@ public static void setTarget(WorldPoint target, String clearReasonWhenNull) { if (target == null) { resetRouteProgress(); logRouteClear(clearReasonWhenNull); - synchronized (ShortestPathPlugin.getPathfinderMutex()) { - final Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + synchronized (Rs2PathApi.getPathfinderMutex()) { + final Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder != null) { pathfinder.cancel(); } - Future pathfinderFuture = ShortestPathPlugin.getPathfinderFuture(); + Future pathfinderFuture = Rs2PathApi.getPathfinderFuture(); if (pathfinderFuture != null && !pathfinderFuture.isDone()) { pathfinderFuture.cancel(true); } - ShortestPathPlugin.setPathfinderFuture(null); - ShortestPathPlugin.setPathfinder(null); + Rs2PathApi.setPathfinderFuture(null); + Rs2PathApi.setPathfinder(null); } WorldMapPointManager wmm = Microbot.getWorldMapPointManager(); if (wmm != null) { - wmm.remove(ShortestPathPlugin.getMarker()); + wmm.remove(Rs2PathApi.getMarker()); } else if (Rs2LogRateLimit.once(WORLD_MAP_REMOVE_NULL_LOGGED)) { log.debug("[Walker] WorldMapPointManager null during route clear — marker may linger until teardown"); } - ShortestPathPlugin.setMarker(null); - ShortestPathPlugin.setStartPointSet(false); + Rs2PathApi.setMarker(null); + Rs2PathApi.setStartPointSet(false); } else { applyWalkerDestination(target); } } private static void restoreTargetMarker(WorldPoint target) { - if (target == null || ShortestPathPlugin.getMarker() != null) { + if (target == null || Rs2PathApi.getMarker() != null) { return; } @@ -7610,11 +7610,11 @@ private static void restoreTargetMarker(WorldPoint target) { log.debug("[Walker] Cannot restore marker: WorldMapPointManager unavailable"); return; } - ShortestPathPlugin.setMarker(new WorldMapPoint(target, ShortestPathPlugin.MARKER_IMAGE)); - ShortestPathPlugin.getMarker().setName("Target"); - ShortestPathPlugin.getMarker().setTarget(ShortestPathPlugin.getMarker().getWorldPoint()); - ShortestPathPlugin.getMarker().setJumpOnClick(true); - wmm.add(ShortestPathPlugin.getMarker()); + Rs2PathApi.setMarker(new WorldMapPoint(target, Rs2PathApi.MARKER_IMAGE)); + Rs2PathApi.getMarker().setName("Target"); + Rs2PathApi.getMarker().setTarget(Rs2PathApi.getMarker().getWorldPoint()); + Rs2PathApi.getMarker().setJumpOnClick(true); + wmm.add(Rs2PathApi.getMarker()); log.info("[Walker] Restored missing path target marker at {}", target); } catch (Exception ex) { log.debug("[Walker] Failed to restore target marker at {}", target, ex); @@ -7665,7 +7665,7 @@ private static boolean handleTransports(List path, int indexOfStartP && recentlyOpenedStationaryDoorOnSegment(path.get(indexOfStartPoint), path.get(indexOfStartPoint + 1))) { return false; } - Set transports = ShortestPathPlugin.getTransports().get(path.get(indexOfStartPoint)); + Set transports = Rs2PathApi.getTransports().get(path.get(indexOfStartPoint)); if (transports == null || transports.isEmpty()) { return false; } @@ -7883,7 +7883,7 @@ && recentlyOpenedStationaryDoorOnSegment(path.get(indexOfStartPoint), path.get(i } if (transport.getType() == TransportType.SPIRIT_TREE) { - if (!ShortestPathPlugin.getPathfinderConfig().isUseSpiritTrees()) { + if (!Rs2PathApi.getPathfinderConfig().isUseSpiritTrees()) { log.debug("[Walker] skip spirit tree transport — setting is off"); continue; } @@ -8521,7 +8521,7 @@ private static boolean hasPrecomputedContinuationFromTransport(Transport transpo if (transport == null || transport.getDestination() == null) { return false; } - Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder == null || !pathfinder.isDone()) { return false; } @@ -9054,7 +9054,7 @@ public static boolean isInArea(WorldPoint centerOfArea, int range) { } public static boolean isNear() { - final Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + final Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder == null) return false; // idk are we near if we don't have a path? final List path = pathfinder.getPath(); if (path == null) return false; @@ -9083,7 +9083,7 @@ public static boolean isNear(WorldPoint target) { } public static boolean isNearPath() { - final Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + final Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder == null) return true; final List path = pathfinder.getWalkablePath(); @@ -9295,7 +9295,7 @@ private static void checkIfStuck() { private static final long MINIMAP_CLICK_STALL_GRACE_MS = 12_000L; private static boolean interactingActorNearWalkablePath() { - Pathfinder pf = ShortestPathPlugin.getPathfinder(); + Pathfinder pf = Rs2PathApi.getPathfinder(); if (pf == null) { return false; } @@ -9354,12 +9354,12 @@ private static boolean isStuckTooLong() { * @param start */ public void setStart(WorldPoint start) { - Pathfinder pathfinder = ShortestPathPlugin.getPathfinder(); + Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder == null) { return; } Set targets = pathfinder.getTargets(); - ShortestPathPlugin.setStartPointSet(true); + Rs2PathApi.setStartPointSet(true); if (isClientThread()) { Microbot.getClientThread().runOnSeperateThread(() -> restartPathfinding(start, targets)); } else { @@ -9376,7 +9376,7 @@ public void setStart(WorldPoint start) { */ public static int getDistanceBetween(WorldPoint startpoint, WorldPoint endpoint) { Set ends = Set.of(endpoint); - Pathfinder pathfinder = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), startpoint, ends); + Pathfinder pathfinder = new Pathfinder(Rs2PathApi.getPathfinderConfig(), startpoint, ends); pathfinder.run(); return pathfinder.getPath().size(); } @@ -10445,11 +10445,11 @@ private static int getDesiredRotation(char letter) { * @return true if the item is a teleportation item, false otherwise */ public static boolean isTeleportItem(int itemId) { - if (ShortestPathPlugin.getPathfinderConfig().getAllTransports().isEmpty()) { - ShortestPathPlugin.getPathfinderConfig().refresh(); + if (Rs2PathApi.getPathfinderConfig().getAllTransports().isEmpty()) { + Rs2PathApi.getPathfinderConfig().refresh(); } - Set teleportItemIds = ShortestPathPlugin.getPathfinderConfig().getAllTransports().values() + Set teleportItemIds = Rs2PathApi.getPathfinderConfig().getAllTransports().values() .stream() .flatMap(Set::stream) .filter(t -> TransportType.isTeleport(t.getType(), t.getOrigin())) @@ -10493,13 +10493,13 @@ public static int findNearestAccessibleTarget(WorldPoint startPoint, List targetSet = new HashSet<>(targets); // Store original configuration to restore later - boolean originalUseBankItems = ShortestPathPlugin.getPathfinderConfig().isUseBankItems(); + boolean originalUseBankItems = Rs2PathApi.getPathfinderConfig().isUseBankItems(); try { - ShortestPathPlugin.getPathfinderConfig().setUseBankItems(useBankItems); + Rs2PathApi.getPathfinderConfig().setUseBankItems(useBankItems); // Configure pathfinder - ShortestPathPlugin.getPathfinderConfig().refresh(); + Rs2PathApi.getPathfinderConfig().refresh(); // Run pathfinder - Pathfinder pf = new Pathfinder(ShortestPathPlugin.getPathfinderConfig(), startPoint, targetSet); + Pathfinder pf = new Pathfinder(Rs2PathApi.getPathfinderConfig(), startPoint, targetSet); pf.run(); List path = pf.getPath(); @@ -10527,8 +10527,8 @@ public static int findNearestAccessibleTarget(WorldPoint startPoint, List Date: Mon, 20 Jul 2026 20:04:24 +0100 Subject: [PATCH 12/48] Mark facade migration Stages 1-3 complete in tracker Record the staged-plan status: Stages 1 (catalogue), 2 (Rs2PathApi), and 3a/3b/3c (consumer migration incl. Rs2Walker) done with commit refs; Stage 4 (backport behind facade) is now the next step. Note that 100% of plugin-state access routes through Rs2PathApi and only plugin identity refs (.class / getSimpleName) remain. Co-Authored-By: Claude Opus 4.8 --- .../shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md index 3665cce8b0..6143a2fdf4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md @@ -195,11 +195,15 @@ Read-only sweep of all **26** consumer files (`grep` for `microbot.shortestpath` `util/walker/*` (Rs2Walker + lifecycle/awaits/banking/shared), `util/bank/Rs2Bank`, `util/depositbox/Rs2DepositBox`, `util/skills/slayer/Rs2Slayer`, `util/poh/*`, `util/leaguetransport/*`, `util/tile/Rs2Tile`, `util/reachable/Rs2Reachable`, `util/npc/Rs2NpcManager`, `questhelper/QuestScript`, `breakhandler/**`, `Script.java`. ### Staged plan (each stage compiles + walker still runs before the next) -1. **Catalogue** the full external surface of `Pathfinder`, `PathfinderConfig`, `Transport`, `TransportType`, `WorldPointUtil`, `CollisionMap` (not just `ShortestPathPlugin`). Produce the complete contract table. -2. **Introduce `Rs2PathApi`** (Microbot-owned, e.g. under `util/walker/`) — a thin facade delegating to today's `ShortestPathPlugin` statics 1:1. No behaviour change. -3. **Migrate consumers** to `Rs2PathApi`, one package at a time, compiling + smoke-testing the walker after each. Leave `Rs2Walker` for last (largest, riskiest). -4. **Backport behind the facade** — resume the Tier 1–5 items (wilderness widths #2, `PrimitiveIntList` #11, POH coverage #3, etc.) changing only internals; consumers untouched. -5. **(Optional) re-baseline** against latest `Skretzo/shortest-path` — the pinned comparison is `07fca57`; no upstream remote is configured yet. +1. ✅ **DONE** (`2119eb9e77`) — **Catalogue** the full external surface. See "Stage 1 catalogue" above. +2. ✅ **DONE** (`e52b781575`) — **Introduce `Rs2PathApi`** at `util/walker/Rs2PathApi.java`, thin 1:1 delegation, no behaviour change. +3. ✅ **DONE** — **Migrate consumers** to `Rs2PathApi`, package by package, walker last: + - `3a` (`eb0e274d43`): leaf consumers — `Script`, `QuestScript`, `Rs2Bank`, `Rs2DepositBox`, `Rs2NpcManager`, `Rs2Slayer`, `Rs2LeaguesTransport`. + - `3b` (`6ee086b835`): walker helpers — `Rs2WalkerLifecycleRuntime`, `Rs2WalkerBankingPlanner`. + - `3c` (`e6e7f0c1fc`): `Rs2Walker` itself (77 refs). Verified: `:client:compileJava` clean + 73 shortestpath tests green (Core 43, Tier1 regression 18, PathSmoother 6, TransportType 4, +2). + - Remaining `ShortestPathPlugin` references repo-wide are plugin **identity** only (`MicrobotPluginChoice`'s `.class`, `Microbot`'s `getSimpleName()` string check) — intentionally not routed through the facade. **100% of plugin-state access now goes through `Rs2PathApi`.** +4. ⬜ **NEXT** — **Backport behind the facade** — resume the Tier 1–5 items (wilderness widths #2, `PrimitiveIntList` #11, POH coverage #3, etc.) changing only internals; consumers untouched. +5. ⬜ **(Optional) re-baseline** against latest `Skretzo/shortest-path` — the pinned comparison is `07fca57`; no upstream remote is configured yet. ### Guardrails - **No walker edits** until the facade exists and the contract is frozen. From ad97f1b8c7767281c9502eeae9d7bccb52e09a37 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 21:30:14 +0100 Subject: [PATCH 13/48] Stage 4 audit: correct stale tracker; Tier 1-2 backlog already done Live-code verification against the KEK branch found most flagged "backport" items already implemented since the 2026-04-18 audit: - #2 wilderness boundaries DONE (PathfinderConfig.java:41-46 match the upstream values; isInLevel20/30Wilderness wired; Chebyshev landed) - #8 bidirectional BFS DONE (meet-in-the-middle, BIDIRECTIONAL_MIN_CHEBYSHEV) - #31 currency-aware transport filter DONE (PathfinderConfig.java:879-892) - #33/#34 transport-index perf DONE (buildPathFirstIndex map) - #11 stale premise: Node already packed-int, not List; the only List left is the getPath() facade boundary (not a behind-the-facade change) Genuinely-open internal items remain: #10 (reachability prune), #12 (SplitFlagMap LRU eviction), #30 (one-way flag), #3 (POH coverage) - correctness/data-sensitive, want real upstream source. No upstream remote is configured yet (still pinned to 07fca57). Docs only. Co-Authored-By: Claude Opus 4.8 --- .../shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md index 6143a2fdf4..7937f80f0a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md @@ -9,6 +9,8 @@ Consolidated findings from a four-angle audit (pathfinder algorithm, Rs2Walker r **Rollup (2026-04-18 audit):** 22 DONE · 9 PARTIAL · 8 OPEN · total 39. (Tier 3 closed.) +> **2026-07-20 Stage 4 audit — Tier 1–2 backlog is largely already implemented.** With the facade in place (Stages 1–3 done), a live-code sweep of the flagged "backport" items found most already landed since the 2026-04-18 audit: **#2 wilderness DONE** (boundaries match upstream), **#8 bidirectional BFS DONE**, **#31 currency filter DONE**, **#33/#34 transport-index perf DONE**, **#11 stale premise** (Node already packed-int). Genuinely still-open internal items: **#10** (transport reachability prune), **#12** (SplitFlagMap region LRU eviction), **#30** (one-way transport flag), and **#3** (POH coverage verify). These are correctness-/data-sensitive and want real upstream source to do accurately — **no upstream remote is configured yet** (comparison still pinned to `07fca57`). Recommended Stage 4 enabler: add the `Skretzo/shortest-path` remote and re-baseline before implementing #10/#12/#30. +> > **2026-07-20 reconciliation — direction set: FACADE-FIRST.** Spot-verified against the live tree on `So-I-dont-Fuck-The-Walker-KEK`. Confirmed: boat world-view is **DONE** (`WorldPointUtil.fromLocalInstance`, closes `UPSTREAM_COMPARISON.md` #6); `PrimitiveIntList` (#11) still **OPEN**; #3 **reclassified** (see row); #27 now **12/16** pairs (was 8). A full 39-item re-audit was **not** performed — only the items below were re-checked. **Decision:** before any further upstream backport, introduce a Microbot-owned path facade so `Rs2Walker` and the other consumers stop importing upstream internals directly. See the **"Facade migration (2026-07-20)"** section at the bottom for the frozen coupling contract and staged plan. --- @@ -20,7 +22,7 @@ Small patches, big payoff. Most are known but still unlanded. | # | Status | Issue | File | Effort | |---|---|---|---|---| | 1 | DONE | `PrimitiveIntHashMap.rehash()` data loss — `return;` → `continue;` | `PrimitiveIntHashMap.java:210` | S | -| 2 | PARTIAL | Wilderness boundaries 8 tiles off, underground 198 tiles narrow — Chebyshev mod-6400 landed (`Pathfinder.java:155–162`), wilderness widths not re-verified | `Pathfinder.java`, `PathfinderConfig.java` | M | +| 2 | DONE | Wilderness boundaries — **re-verified 2026-07-20 against upstream values**: `PathfinderConfig.java:41-46` now uses above-ground start Y=3525, level-20 Y=3680, level-30 Y=3760, underground 518×458, level-20 Y=10075, level-30 Y=10155 (all match `UPSTREAM_COMPARISON.md`), named `LEVEL_20`/`LEVEL_30`, wired via `isInLevel20/30Wilderness`. Chebyshev mod-6400 also landed. | `Pathfinder.java`, `PathfinderConfig.java` | M | | 3 | NEEDS-VERIFY | `teleportation_poh.tsv` absent **by design** — local routes POH programmatically via `util/poh/` (`PohTransport`/`PohTeleports`), not a TSV. (`teleportation_portals.tsv`, 101 rows, is a *different* `TELEPORTATION_PORTAL` type: Castle Wars / god-wars portals, not POH.) Correct action is **not** "backport the TSV" but "confirm `util/poh` covers upstream's POH destination set". *Reclassified 2026-07-20.* | `util/poh/` | M | | 4 | DONE | `growBucket()` integer overflow — `Math.min(len, MAX/2-4)*2` | `PrimitiveIntHashMap.java:147` | S | | 5 | DONE | Missing `onGameStateChanged` refresh — quest/varbit goes stale after re-login | `ShortestPathPlugin.java:488` | S | @@ -35,10 +37,10 @@ Measurable against existing `PathfinderBenchmarkTest`. |---|---|---|---|---| | 6 | DONE | A* with Chebyshev heuristic (walking subgraph; transports stay in `pending` PQ) | 30–50% node reduction on long routes | M | | 7 | DONE | Line-of-sight path smoothing post-BFS — 78–85% path-tile reduction measured across corpus (`PathSmoother.java`, `Pathfinder.getWalkablePath()`) | 15–25% fewer walker clicks | M | -| 8 | OPEN | Bidirectional BFS for long routes (Lumbridge→GE, Karamja→Iceberg) | √N speedup when src/dst far apart | L | +| 8 | DONE | Bidirectional BFS for long routes — implemented (`Pathfinder.java` meet-in-the-middle, `BIDIRECTIONAL_MIN_CHEBYSHEV=2000`, fwd/back landmark residuals). *Verified 2026-07-20.* | √N speedup when src/dst far apart | L | | 9 | PARTIAL | Cache `SplitFlagMap` + parsed transports as singletons in `PathfinderConfig` — fields cached per instance, singleton discipline across Pathfinder constructions unclear | Eliminates per-pathfinder re-parse | S | | 10 | OPEN | Transport reachability prune at config load | 10–20% fewer teleports to explore | M | -| 11 | OPEN | Backport upstream `PrimitiveIntList` for paths — still `List` via `ArrayList` (`Node.java:49–56`) | Zero-alloc packed-int paths | M | +| 11 | STALE-DESC | Premise no longer holds (2026-07-20): `Node` already uses a packed-int (`packedPosition`) linked structure, **not** `List`. The only remaining `List` is the *output* path (`Pathfinder.path/smoothedPath/joinedPath`), which is the `getPath()` facade boundary — packing it would change the public signature, so it is explicitly **not** a behind-the-facade change. Close unless a measured alloc hotspot justifies an internal packed path + conversion at `getPath()`. | `Node.java`, `Pathfinder.java` | M | | 12 | OPEN | Region LRU eviction in `SplitFlagMap` | Long-session memory bound | M | --- @@ -74,7 +76,7 @@ The "completeness of navigating the world" half. | 28 | PARTIAL | Stronghold of Security spirit tree + Prifddinas crystal-tier destinations — placeholders in `spirit_trees.tsv`, actual rows incomplete | | S | | 29 | PARTIAL | Slayer Ring Ankous (3193,3611), Fairy Ring CJQ (Great Conch) — CJQ present, Ankous Slayer Ring variant still missing | | S | | 30 | OPEN | No `isOneWay` flag on transports — return-only boats and Legends' jagged-wall used bidirectionally | | M | -| 31 | OPEN | No currency-threshold cost filter — expensive teleports picked over cheap walks when gold is low | | L | +| 31 | DONE | Currency-aware transport filtering present — `PathfinderConfig.java:879-892` checks `Transport.currencyAmount`/`currencyName` against inventory + (optionally) bank before allowing a transport. *Verified 2026-07-20.* | | L | --- @@ -83,7 +85,7 @@ The "completeness of navigating the world" half. | # | Status | Issue | File:Line | Effort | |---|---|---|---|---| | 32 | PARTIAL | `log.debug()` unconditionally builds joined transport strings — guards present at `Rs2Walker.java:1548, 1604`; other sites (`~894, 1083, 1174`) still unguarded | `Rs2Walker.java:1548, 1579, 1604, 2610` | S | -| 33 | OPEN | `getTransportsForPath` uses `path.indexOf()` per transport (O(n·m)) — build `Map` once | `Rs2Walker.java:986, 1014` | S | +| 33 | DONE | `getTransportsForPath` now builds `buildPathFirstIndex(path)` (a `Map`) once and does `pathFirstIndex.get(...)` lookups instead of per-transport `indexOf` (`Rs2Walker.java:3498, 3540`). *Verified 2026-07-20.* | | S | | 34 | DONE | `handleTransports` rebuilds `pathFirstIndex` HashMap every call — now cached per call | `Rs2Walker.java:1560–1562` | S | | 35 | OPEN | `Rs2Player.getWorldLocation()` called 10+ times per tick — capture once per loop | `Rs2Walker.java:182, 268, 318` | S | | 36 | PARTIAL | Pathfinder `Future` cancellation has no wait/timeout — `.cancel(true)` in place, bounded-wait still missing | `ShortestPathPlugin.java:294` | M | From d37a1694a427148943275c809f4c3143b32563d5 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 21:42:56 +0100 Subject: [PATCH 14/48] Stage 4 re-baseline against current upstream (7e7e5bf94b) Added the skretzo remote and fetched Skretzo/shortest-path. Upstream HEAD is 122 commits + a major refactor past the pinned 07fca57 (transport/ + transport/parser packages, Destination/ItemVariations/ JewelleryBoxTier model, NodeGraph/IntDeque/IntMinHeap/PrimitiveIntList pathfinder internals, standalone WildernessChecker, leagues/, PendingTask). Re-checked the open items against real current source: - #2 wilderness: byte-identical to upstream WildernessChecker -> DONE - #3 POH: real gap - upstream ships teleportation_portals_poh.tsv (137 rows); Microbot routes POH programmatically. Next target: diff that TSV against util/poh coverage and backfill. - #10/#12: no upstream counterpart (Microbot-original perf ideas) - #30 one-way: not confirmed upstream; deprioritized Documented in UPSTREAM_COMPARISON.md "Re-baseline 2026-07-20" and updated the facade-migration staged plan (step 5 done). The divergence now only supports selective feature/data backports, which the facade makes safe. Docs only. Co-Authored-By: Claude Opus 4.8 --- .../shortestpath/UPSTREAM_COMPARISON.md | 33 ++++++++++++++++++- .../WEBWALKER_IMPROVEMENT_PLAN.md | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md index b2309cf588..575a06c601 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md @@ -1,7 +1,38 @@ # Shortest Path: Upstream vs Microbot Comparison Comparison of [Skretzo/shortest-path](https://github.com/Skretzo/shortest-path) (upstream) against the Microbot fork. -Upstream commit: `07fca57` ("Data fixes and minor cleanups (#400)"). +Original baseline: `07fca57` ("Data fixes and minor cleanups (#400)"). **Everything below the "Re-baseline" section refers to that old baseline and is partly superseded — read the re-baseline first.** + +--- + +## Re-baseline 2026-07-20 → upstream `7e7e5bf94b` + +Added the `skretzo` remote and fetched. Current upstream HEAD (`skretzo/master`) is **`7e7e5bf94b`** ("Update collision map") — **122 commits ahead** of the pinned `07fca57`, including a **major architectural refactor**. The `07fca57`-based punch list below is now largely obsolete; use this section as the current map. + +### Upstream has restructured (the fork is now architecturally distinct) + +Current upstream is no longer a monolith. New/renamed since `07fca57`: + +- **`transport/` package** with a real parser pipeline: `TransportLoader`, `TransportType`, `TransportTypeConfig`, `LoadInterner`, `BankPickupRequirements`, and `transport/parser/*` (`TsvParser`, `FieldParser`, `TransportRecord`, `WorldPointParser`, `QuestParser`, `SkillRequirementParser`, `VarRequirementParser`, …). Microbot still parses TSV inline in the `Transport` constructor. +- **Model classes**: `Destination`, `DestinationRequirements`, `ItemVariations`, `JewelleryBoxTier`, `transport/requirement/{ItemRequirement,TransportItems}`. +- **Pathfinder internals**: `NodeGraph`, `IntDeque`, `IntMinHeap`, `PathStep`, `PathfinderResult`, `PathTerminationReason`, `AbstractNodeKind`, `TransportAvailability`, `PrimitiveIntList`, and a standalone **`WildernessChecker`**. Microbot still uses the `Node`/`Pathfinder` design (with its own A*, bidirectional search, smoothing, packed-int `Node`). +- **`leagues/` package** (`LeagueModeState`, `LeagueRegion`, `LeagueRegionChecker`) and **`PendingTask`** (deferred post-login refresh). +- Resources moved under `src/main/resources/transports/`. + +**Implication:** a git merge is impossible (unrelated histories, different packages). Even *file-level* backports are now hard — upstream's logic lives in a different structure. Only **selective feature/data backports** are viable, and the Stage 1–3 **facade (`Rs2PathApi`)** is what makes them safe (consumers no longer see these internals). See `WEBWALKER_IMPROVEMENT_PLAN.md` "Facade migration". + +### Open-item status re-checked against real current upstream source + +| Item | Verdict vs `7e7e5bf94b` | +|---|---| +| **#2 wilderness boundaries** | ✅ **DONE / byte-identical.** Upstream `pathfinder/WildernessChecker.java` uses the exact same `WorldArea`s as Microbot `PathfinderConfig.java:41-46` (above-ground `2944,3525,448,448`; underground `2944,9918,518,458`; `LEVEL_20` 3680/10075; `LEVEL_30` 3760/10155; same `NOT_WILDERNESS_*`). No action. | +| **#3 POH** | ⚠️ **Real gap, concrete now.** Upstream ships `resources/transports/teleportation_portals_poh.tsv` (**137 rows**: Annakarl, Ardougne, Ape Atoll Dungeon, … POH nexus/portal destinations). Microbot has **no** POH TSV — it routes POH programmatically via `util/poh/`. **Action:** verify `util/poh` covers this 137-row destination set (diff the upstream TSV against what `PohTransport`/`PohTeleports` produce), backfill gaps. | +| **#10 reachability prune**, **#12 SplitFlagMap LRU eviction** | ❌ **No upstream counterpart** — not present in upstream `PathfinderConfig`/`SplitFlagMap`. These are **Microbot-original** optimization ideas from the webwalker audit, *not* upstream backports. Treat as independent perf work, not re-baseline items. | +| **#30 one-way transports** | ❓ Not clearly present upstream on re-check; deprioritize (no confirmed upstream source to backport from). | +| **#11 `PrimitiveIntList`** | Upstream has `PrimitiveIntList` for its *output* paths, but Microbot's `Node` is already packed-int; the only `List` left is the `getPath()` facade boundary (see `WEBWALKER_IMPROVEMENT_PLAN.md` #11). Not a behind-facade change. | + +### Recommended next Stage-4 target +**#3 POH coverage** is the one concrete, real upstream gap: diff `skretzo/master:src/main/resources/transports/teleportation_portals_poh.tsv` against Microbot's programmatic POH set and backfill. It's data-level (low engine risk) and testable. --- diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md index 7937f80f0a..2de756bc7b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md @@ -205,7 +205,7 @@ Read-only sweep of all **26** consumer files (`grep` for `microbot.shortestpath` - `3c` (`e6e7f0c1fc`): `Rs2Walker` itself (77 refs). Verified: `:client:compileJava` clean + 73 shortestpath tests green (Core 43, Tier1 regression 18, PathSmoother 6, TransportType 4, +2). - Remaining `ShortestPathPlugin` references repo-wide are plugin **identity** only (`MicrobotPluginChoice`'s `.class`, `Microbot`'s `getSimpleName()` string check) — intentionally not routed through the facade. **100% of plugin-state access now goes through `Rs2PathApi`.** 4. ⬜ **NEXT** — **Backport behind the facade** — resume the Tier 1–5 items (wilderness widths #2, `PrimitiveIntList` #11, POH coverage #3, etc.) changing only internals; consumers untouched. -5. ⬜ **(Optional) re-baseline** against latest `Skretzo/shortest-path` — the pinned comparison is `07fca57`; no upstream remote is configured yet. +5. ✅ **DONE (re-baseline)** — added the `skretzo` remote, fetched, and re-baselined against upstream HEAD `7e7e5bf94b` (122 commits + major refactor past `07fca57`). Findings in `UPSTREAM_COMPARISON.md` "Re-baseline 2026-07-20": #2 wilderness byte-identical to upstream `WildernessChecker` (DONE); **#3 POH is the one concrete real gap** (upstream ships `teleportation_portals_poh.tsv`, 137 rows; Microbot routes POH programmatically — verify `util/poh` coverage); #10/#12 have no upstream counterpart (Microbot-original). Upstream is now architecturally distinct — only selective feature/data backports are viable, which the facade enables. ### Guardrails - **No walker edits** until the facade exists and the contract is frozen. From bae1a7515edb1c5f309e00e427fdb1083489a874 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 22:12:56 +0100 Subject: [PATCH 15/48] Stage 4 (#3): backfill 12 missing POH portal-chamber destinations Diffed Microbot's programmatic POH model against upstream's teleportation_portals_poh.tsv (137 rows / 50 dests) and the game's 42 ObjectID.POH_PORTAL_MAG_* portal-chamber destinations. PohPortal covered 28; added the 12 missing ones: Barbarian Outpost, Fishing Guild, Port Khazard, Marim, Civitas illa Fortis, Ourania, Cemetery, Dareeyak, Trollheim, Lassar, Ice Plateau, Paddewwa (PohPortal 28 -> 40). Each uses the authoritative arrival tile from the upstream data set and the MAG/MARBLE/TEAK object-id families (compiler-verified to exist; League variants omitted). They flow into the transport graph automatically: PohPortal.findPortalsInPoh() (BY_OBJECT_ID built from values()) -> PohPanel.portalPanel -> new PohTransport(...), so the walker now detects and routes through these portals when built in a POH. Verified: :client:compileJava clean; no duplicate enum constants; shortestpath regression suite green. Tracker #3 marked DONE in WEBWALKER_IMPROVEMENT_PLAN.md and UPSTREAM_COMPARISON.md. Co-Authored-By: Claude Opus 4.8 --- .../shortestpath/UPSTREAM_COMPARISON.md | 2 +- .../WEBWALKER_IMPROVEMENT_PLAN.md | 2 +- .../microbot/util/poh/data/PohPortal.java | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md index 575a06c601..5c0c0454ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md @@ -26,7 +26,7 @@ Current upstream is no longer a monolith. New/renamed since `07fca57`: | Item | Verdict vs `7e7e5bf94b` | |---|---| | **#2 wilderness boundaries** | ✅ **DONE / byte-identical.** Upstream `pathfinder/WildernessChecker.java` uses the exact same `WorldArea`s as Microbot `PathfinderConfig.java:41-46` (above-ground `2944,3525,448,448`; underground `2944,9918,518,458`; `LEVEL_20` 3680/10075; `LEVEL_30` 3760/10155; same `NOT_WILDERNESS_*`). No action. | -| **#3 POH** | ⚠️ **Real gap, concrete now.** Upstream ships `resources/transports/teleportation_portals_poh.tsv` (**137 rows**: Annakarl, Ardougne, Ape Atoll Dungeon, … POH nexus/portal destinations). Microbot has **no** POH TSV — it routes POH programmatically via `util/poh/`. **Action:** verify `util/poh` covers this 137-row destination set (diff the upstream TSV against what `PohTransport`/`PohTeleports` produce), backfill gaps. | +| **#3 POH** | ✅ **DONE (2026-07-20).** Diffed upstream `teleportation_portals_poh.tsv` (137 rows / 50 dests) and the game's 42 `POH_PORTAL_MAG_*` portal-chamber destinations against Microbot's `PohPortal` enum. 12 were missing — Barbarian Outpost, Fishing Guild, Port Khazard, Marim, Civitas illa Fortis, Ourania, Cemetery, Dareeyak, Trollheim, Lassar, Ice Plateau, Paddewwa — and were **backfilled** with upstream arrival tiles + compiler-verified MAG/MARBLE/TEAK object ids (`PohPortal` 28→40). They flow into the transport graph automatically via `findPortalsInPoh()` → `PohPanel` → `PohTransport`. Compiles clean; shortestpath regression suite green. | | **#10 reachability prune**, **#12 SplitFlagMap LRU eviction** | ❌ **No upstream counterpart** — not present in upstream `PathfinderConfig`/`SplitFlagMap`. These are **Microbot-original** optimization ideas from the webwalker audit, *not* upstream backports. Treat as independent perf work, not re-baseline items. | | **#30 one-way transports** | ❓ Not clearly present upstream on re-check; deprioritize (no confirmed upstream source to backport from). | | **#11 `PrimitiveIntList`** | Upstream has `PrimitiveIntList` for its *output* paths, but Microbot's `Node` is already packed-int; the only `List` left is the `getPath()` facade boundary (see `WEBWALKER_IMPROVEMENT_PLAN.md` #11). Not a behind-facade change. | diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md index 2de756bc7b..127ede14e2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/WEBWALKER_IMPROVEMENT_PLAN.md @@ -23,7 +23,7 @@ Small patches, big payoff. Most are known but still unlanded. |---|---|---|---|---| | 1 | DONE | `PrimitiveIntHashMap.rehash()` data loss — `return;` → `continue;` | `PrimitiveIntHashMap.java:210` | S | | 2 | DONE | Wilderness boundaries — **re-verified 2026-07-20 against upstream values**: `PathfinderConfig.java:41-46` now uses above-ground start Y=3525, level-20 Y=3680, level-30 Y=3760, underground 518×458, level-20 Y=10075, level-30 Y=10155 (all match `UPSTREAM_COMPARISON.md`), named `LEVEL_20`/`LEVEL_30`, wired via `isInLevel20/30Wilderness`. Chebyshev mod-6400 also landed. | `Pathfinder.java`, `PathfinderConfig.java` | M | -| 3 | NEEDS-VERIFY | `teleportation_poh.tsv` absent **by design** — local routes POH programmatically via `util/poh/` (`PohTransport`/`PohTeleports`), not a TSV. (`teleportation_portals.tsv`, 101 rows, is a *different* `TELEPORTATION_PORTAL` type: Castle Wars / god-wars portals, not POH.) Correct action is **not** "backport the TSV" but "confirm `util/poh` covers upstream's POH destination set". *Reclassified 2026-07-20.* | `util/poh/` | M | +| 3 | DONE | POH is routed programmatically via `util/poh/` (not a TSV). Coverage diffed against upstream `teleportation_portals_poh.tsv` (137 rows / 50 dests) and against the game's 42 `ObjectID.POH_PORTAL_MAG_*` portal-chamber destinations. `PohPortal` was missing 12 (Barbarian Outpost, Fishing Guild, Port Khazard, Marim, Civitas illa Fortis, Ourania, Cemetery, Dareeyak, Trollheim, Lassar, Ice Plateau, Paddewwa) — **backfilled 2026-07-20** with upstream arrival tiles + compiler-verified MAG/MARBLE/TEAK object ids (`PohPortal` 28→40). They auto-flow into the transport graph via `PohPortal.findPortalsInPoh()` → `PohPanel` → `PohTransport`. | `util/poh/data/PohPortal.java` | M | | 4 | DONE | `growBucket()` integer overflow — `Math.min(len, MAX/2-4)*2` | `PrimitiveIntHashMap.java:147` | S | | 5 | DONE | Missing `onGameStateChanged` refresh — quest/varbit goes stale after re-login | `ShortestPathPlugin.java:488` | S | diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/PohPortal.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/PohPortal.java index 6868eb0d1f..3968cd8ea2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/PohPortal.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/PohPortal.java @@ -107,6 +107,34 @@ public enum PohPortal implements PohTeleport { WEISS("Weiss", TeleportLocationData.WEISS_ICY_BASALT.getLocation(), ObjectID.POH_PORTAL_MAG_WEISS, ObjectID.POH_PORTAL_MARBLE_WEISS, ObjectID.POH_PORTAL_TEAK_WEISS, ObjectID.POH_PORTAL_LEAGUE_5_WEISS), + + // Backfilled 2026-07-20 from upstream Skretzo/shortest-path teleportation_portals_poh.tsv + // (destination = authoritative arrival tile from that data set). MAG/MARBLE/TEAK object-id + // families verified present; League variants omitted intentionally. + BARBARIAN_OUTPOST("Barbarian Outpost", new WorldPoint(2543, 3569, 0), + ObjectID.POH_PORTAL_MAG_BARBARIAN, ObjectID.POH_PORTAL_MARBLE_BARBARIAN, ObjectID.POH_PORTAL_TEAK_BARBARIAN), + FISHING_GUILD("Fishing Guild", new WorldPoint(2613, 3391, 0), + ObjectID.POH_PORTAL_MAG_FISHINGGUILD, ObjectID.POH_PORTAL_MARBLE_FISHINGGUILD, ObjectID.POH_PORTAL_TEAK_FISHINGGUILD), + PORT_KHAZARD("Port Khazard", new WorldPoint(2636, 3167, 0), + ObjectID.POH_PORTAL_MAG_KHAZARD, ObjectID.POH_PORTAL_MARBLE_KHAZARD, ObjectID.POH_PORTAL_TEAK_KHAZARD), + MARIM("Marim", new WorldPoint(2797, 2798, 1), + ObjectID.POH_PORTAL_MAG_MARIM, ObjectID.POH_PORTAL_MARBLE_MARIM, ObjectID.POH_PORTAL_TEAK_MARIM), + CIVITAS_ILLA_FORTIS("Civitas illa Fortis", new WorldPoint(1681, 3133, 0), + ObjectID.POH_PORTAL_MAG_FORTIS, ObjectID.POH_PORTAL_MARBLE_FORTIS, ObjectID.POH_PORTAL_TEAK_FORTIS), + OURANIA("Ourania", new WorldPoint(2468, 3246, 0), + ObjectID.POH_PORTAL_MAG_OURANIA, ObjectID.POH_PORTAL_MARBLE_OURANIA, ObjectID.POH_PORTAL_TEAK_OURANIA), + CEMETERY("Cemetery", new WorldPoint(2981, 3764, 0), + ObjectID.POH_PORTAL_MAG_CEMETERY, ObjectID.POH_PORTAL_MARBLE_CEMETERY, ObjectID.POH_PORTAL_TEAK_CEMETERY), + DAREEYAK("Dareeyak", new WorldPoint(2968, 3696, 0), + ObjectID.POH_PORTAL_MAG_DAREEYAK, ObjectID.POH_PORTAL_MARBLE_DAREEYAK, ObjectID.POH_PORTAL_TEAK_DAREEYAK), + TROLLHEIM("Trollheim", new WorldPoint(2890, 3679, 0), + ObjectID.POH_PORTAL_MAG_TROLLHEIM, ObjectID.POH_PORTAL_MARBLE_TROLLHEIM, ObjectID.POH_PORTAL_TEAK_TROLLHEIM), + LASSAR("Lassar", new WorldPoint(3004, 3470, 0), + ObjectID.POH_PORTAL_MAG_LASSAR, ObjectID.POH_PORTAL_MARBLE_LASSAR, ObjectID.POH_PORTAL_TEAK_LASSAR), + ICE_PLATEAU("Ice Plateau", new WorldPoint(2975, 3938, 0), + ObjectID.POH_PORTAL_MAG_ICEPLATEAU, ObjectID.POH_PORTAL_MARBLE_ICEPLATEAU, ObjectID.POH_PORTAL_TEAK_ICEPLATEAU), + PADDEWWA("Paddewwa", new WorldPoint(3097, 9881, 0), + ObjectID.POH_PORTAL_MAG_PADDEWWA, ObjectID.POH_PORTAL_MARBLE_PADDEWWA, ObjectID.POH_PORTAL_TEAK_PADDEWWA), ; PohPortal(String displayName, WorldPoint destination, Integer... objectIds) { From bae5126b273eab379f55120d923f0e4a5d5028bc Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 22:45:41 +0100 Subject: [PATCH 16/48] Document transports.tsv content diff vs upstream 7e7e5bf94b Recorded in UPSTREAM_COMPARISON.md the file-level and content-level diff of transport data against current upstream: - File-level: the 4 upstream-only TSVs are handled (POH portals/boxes programmatically, quetzal whistle inline, home teleports partial); Microbot adds blocked_edges/dangerous_tiles/npcs/restrictions. - transports.tsv content: present in both (4949 vs 5168 rows). By origin->dest identity, 778 upstream-only pairs vs 553 Microbot-only. Only 14 named; 764 anonymous route objects (mostly Climb/Ladder/ Stairs). 713 of 737 upstream-only origins are brand-new tiles -> a real coverage gap, not coordinate drift. - Flagged bulk import as risky (action-column schema mismatch + collision-map coverage), recommended scoped per-region sync starting with the 14 named routes. Docs only. Co-Authored-By: Claude Opus 4.8 --- .../microbot/shortestpath/UPSTREAM_COMPARISON.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md index 5c0c0454ea..91327e9909 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md @@ -31,8 +31,22 @@ Current upstream is no longer a monolith. New/renamed since `07fca57`: | **#30 one-way transports** | ❓ Not clearly present upstream on re-check; deprioritize (no confirmed upstream source to backport from). | | **#11 `PrimitiveIntList`** | Upstream has `PrimitiveIntList` for its *output* paths, but Microbot's `Node` is already packed-int; the only `List` left is the `getPath()` facade boundary (see `WEBWALKER_IMPROVEMENT_PLAN.md` #11). Not a behind-facade change. | +### Transport data files: upstream vs Microbot (2026-07-20) + +Microbot loads 22 TSVs (see `Transport.java`). File-level diff vs `skretzo/master:src/main/resources/transports/`: + +- **Upstream-only files** — `teleportation_portals_poh.tsv` (✅ now programmatic, see #3), `teleportation_boxes.tsv` (✅ POH mounted items — `Mounted{Glory,Xerics,Digsite,Mythical}`), `quetzal_whistle.tsv` (✅ inline in `teleportation_items.tsv`), `teleportation_spells_home.tsv` (⚠️ Microbot has 2 home rows in `teleportation_spells.tsv` vs upstream's 16 variants). +- **Microbot-only files** (intentional): `blocked_edges.tsv`, `dangerous_tiles.tsv`, `npcs.tsv`, `restrictions.tsv`. + +**`transports.tsv` content diff** (present in both; upstream 5168 rows / Microbot 4949): compared by origin→destination identity. + +- Upstream 5140 distinct O→D pairs vs Microbot 4915. **778 upstream-only**, 553 Microbot-only. +- Of the 778: only **14 named** transports; **764 anonymous route objects** (372 Climb, 137 Ladder, 123 Stairs, 43 Staircase, gates/doors/caves…). +- **Not drift:** 737 distinct origins in the 778, of which only 24 overlap a Microbot origin — **713 are genuinely new origin tiles**. Concentrated central 2500–2999 (399), Varlamore/Kebos 1500–1999 (133), Misthalin 3000–3499 (131). +- **Verdict:** real coverage gap (new route objects + new areas Microbot's baseline predates), but **bulk import is risky**: upstream's space-separated multi-word action column doesn't map trivially to Microbot's `;`-separated `Currency`/`isMembers` schema, and importing into areas the bundled `collision-map.zip` predates can mislead the walker. Recommended as a scoped, validated per-region sync — not a blind paste. The 14 named ones (Mount Quidamortem/Shayzien cart routes, Varrock↔Civitas illa Fortis, Watermill/Mines/Cellar network) are the low-risk starting subset. + ### Recommended next Stage-4 target -**#3 POH coverage** is the one concrete, real upstream gap: diff `skretzo/master:src/main/resources/transports/teleportation_portals_poh.tsv` against Microbot's programmatic POH set and backfill. It's data-level (low engine risk) and testable. +**#3 POH coverage** is the one concrete, real upstream gap: diff `skretzo/master:src/main/resources/transports/teleportation_portals_poh.tsv` against Microbot's programmatic POH set and backfill. It's data-level (low engine risk) and testable. *(Done 2026-07-20 — see the #3 row above.)* --- From f8b113810f044f32277ee8c2f15753e4fabed765 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 22:52:01 +0100 Subject: [PATCH 17/48] Update collision map from upstream (skretzo/master 7e7e5bf94b) Replace bundled collision-map.zip with the current upstream build: 2724 regions (was 2663; +61 new regions covering Varlamore/Kebos and other recent content). Format verified compatible before swap: identical x_y region-entry naming, identical packPosition, and identical per-tile bit layout (FLAG_COUNT=2, same z/y/x index arithmetic) - upstream only refactored BitSet -> long[] internally, the on-disk byte encoding is unchanged, so Microbot's BitSet-based FlagMap decodes it correctly. Validated: shortestpath suite green (73 tests, incl. ShortestPathCoreTest 43 + Tier1 regression 18 doing real cross-region pathfinding; 0 fail). Co-Authored-By: Claude Opus 4.8 --- .../microbot/shortestpath/collision-map.zip | Bin 1164284 -> 1197109 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/collision-map.zip b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/collision-map.zip index 309dfd58171a6d2ce377ad7a20391b7b6996105e..c4448fdd82a0fb7fa94a9333b4bd05e4595600e8 100644 GIT binary patch delta 339265 zcmZsDcOcc@|3CNQ+M9%oieyyw$SQ@BXb_SeqRcYmq9l9fm1Gn$%dAVb2w81Wp^$9Z z`+lF-z25IW@89o_hd<7F-sc&w^W5iH57Byl_XLB!4w{0UjEsz$%mp=rRDMVEVB+@} zIRKFF-_hOZqtIG!$H;?GhE@P>(2lVPEo6zBF+C;4Hh&34M%IrZBcmkaC6kshmzFa) zPeX?G09pW!yAb7xLeG=WAj|^5B7e7$0|1c{V5~uF0OKMRDjtjq5Cd@URj3S6Xb))S zo~Pr*q(d_R`9sObhSQ&?QzI8T4})fh)v&OV!-Oe_gGwoyD@tz-Y7RdD;D!Pz#mUj! zz$fqvngcmFK~II5hmiq^D&*qAyMc@O+#yLuG#S|x9T^!FOkGCOTvA4Hiwzz~0mzvp z8aAxc*F($!(T4gvPwQ7+yd%(Vl&LXC5y>y)UTGs9gtA)O`(UtsS9p5P?<_xt$Uy1a z85Yzp`~GN~oTV#cvS56nI@+>!Zz}yjoggPO@@HL6@>`(qYkG^F%T(VEo+o?G`r>Xm zD!;%){lI!=x&%Gv3+6r%0R|%lTO~i~VlM^}2W+)RIQI-qZ24u690@0FY6~4V@5q<_ zeKE{CzdTj)$?4FWr|(bybmu^F-StMvx0jR3&$JiORbB7nJL@*N5}8bQL7JcZ(=VIz zj8jH0*yQ_i1|*k9a(Ww$J2d5Dr|T!QE6)9)Qtx5W@>NLaNL0A}{S?^&@x>2hn|E7| zE1=vhu`AB;w=NBday8OerP8Sxu5zaL{@nXes-DRX{Bl^QwFHv6l_4JZ+>%fDnY~Jnd=&Xl9-^1iZy{OY}SJ*E%bVuW5 zH}iZ(bcYN6-1~IyV3$XlB<5C`z1~gNnkLoWHy#W|+y=)IIGDc* zxYiGzC{DXqg|T_p6yPhE6vefAsk&LGJZz$w7yaS*tkKY*GH1_FsL;UOip4yReFa6)_R2??ay!8A)4lGl+1o zJ5#UNn+ckgun2CxSBVaK&y^T|sQ2xQlX7?X=q*@l+zgD#GzQEhGXu%*^nqV zIA1B|Rpbz_PC2Zxl=Wai*vpGSnosh_FZqAf1ucjXj(X254aj00U`qqYo6E~=Nzn(8 zA^=jqgl0n|%;}lYmk9#dN6mxr133i{x`c#OfXlvv{$p&wVOyl-B+aFzwz$XwDS$w_ z15sC^<`e>5Vp?To9(n&Sdg(*v(nQ(aRxn{qG$lfTz&f{-$yfR>Z6PgdE<@B7CBPbh zyW&8nOOCdO$?c@3;lbR3W&m+=qQK!~YS$z2zXp?n!4$S8#{{GR;^gw*Qy&z%^Z!|l zjN4LElq7Oq0nP;6@S-Clrx=BixBg5vOTt8`(dmAR&NgKW`pep6WCK+x(+B@O4ul+{gW11a@2Z4Y_G8+}I$t_eWpgtaRl2j?qn?(f=*FDY(Jb z8=f6^DGaO4#1}^S)%x90;oTjz#eFCDOo;FuRhn4#D@~TGEDk+>!?~ z_9IuG&)9a(QM1Cz>z66#-pZZ$Do(BH`Q5)d_<4)bS2}IMOyfEerJ~OVVr&;Zw3mD> zqGgo1uT+I^DjL0wF}B(5zo7Db|2(-MBKR)Zd1K-sZQqfA{LVfl1<~b!z>0z&Yp(Uj zqG!%gv+QVptl8)@7_8{*94{ay?Y%oRneEO{lOfkAR)=F|lbx~1d~eXD*fCG{wQd~; z=3;DTh?MirPbS9lBC)&A-{&=7JiF%6sA+MwsDJwHiCzVvoBP_e8|Gx(T`)O-6S*+t^YNCMaT!02 z5zRQme9|r~PtjX3+I^wcvTpa2M};mVa~w8JOUzbynPJ%1OFi*w*9lpx*D@`-;%mD< zYBNMiTe1Aw|D0*yq%pVK__s1aj*o*+2D}3Io@mxa8M_W24VR>|9SSL{e-P5NI3Vik z^Xj2$h*+Oql%ASXP`tM5JM?Wwc_ZgFu9iVF)ofcCdZzw!WZ{(N;5hQ~kJIplyNpXq{g$fz-F%6K zSCrSz;-gtNU8DVj<1do4c8k%?d7W0qK4@z#NKE_X<@yXC*H{`fQgZIGPlZkG+2~s3 z$vUx&JeQ-jd$7`LJaLbun!EcaOD;u>?D}+Jd`YMEvslxq5(L{pF4KShMX5GciFJn?UPk=CF*-WmH+ddh4o6fJqM(&L|m9FpZtSqDzWk? zZ1_}ap{KSpC+RF-)XdA}ug6X$U(k?i_I}D*@rSp|{uck$FVk6$fpd zox2S2*RHhpOYQemMzAIgCnqfp)SCVKBD%11)3(?PjH2Jx$^VsQV-Tz+mBcm=5W#BD z0b3rD>^~aC0R#=OrLCsa8ECOrTh>+btMos%9pbe(Hr#KgHS8(N_aTx815sGfrC-x(^w3?(`QRvv)Pi{hdrDab?SvP3m;5M~I#8Lp$s zQ0Qn-O%jU?JeW>s2H^A-8H^~=RM5;4z{tTsROfA=Cjmsw?+W}E^-6LTLG3w^^sn3@ zb9tg}O9Vau+%Z%1IdU`;Y9{`f7!Rfo7ywG&ifNOhPXqIftKdwZ16lx%{~9`!LMRyc zzI>Z=|0>LT2~-?GuS+VL%M#691<(R;qFxMlh|`X__1CmZZZR05gjj(^{y2__7FZOJ zJZ~8(b48-IAA(5$aGc@{dr?A5U@iZvOr_+u^=>iH0=8C+2E%}`d;kkbG66X04>Z!` zXa{IspMrISz}x^hzG*ZETIeB6;_jjHvg>d{?vnOLTH0KmXhlYV761o?4M|F7@I|Ks zm+(?xJ^?)dsgMk=$$U!H7xFo`NziJOZA$@lw%APt4Eds66-3+`KI-mvM zSidj~kfRCFPizV`*e}T~v$-7v5xf)yf+O(dx49by?D=Qd^X-s9mN+Uia3bKpR?`3x z_oq36-P^pxXYT71fcIj$5fJL~K~;+}sid}euuCQ3&jxMNh2}!fqM=px!AFCyxIC}= zzq%6=RYzA4Wiy$P97%H-jzmsE-hhn z|4n~4+o@Ng%b&7xo&QX%KeLK^>o>DtuoTP&R*AlBJAK7@}vW;0*|AF!lgY9eR&joGwSpuTHVhU zK5x!q89dJ&ypr%#pFXZ++0l!>(=F91L8IFwUGuU5qbB&+oAcYX6Js)*^hQUSEKi@+dS92a zsGfrDp*r4og5y@oa(VUSUCiN))aOB`-=m%rHVu5xoDnnid4}I@Ao!8Sk>-J>fz=&&|w|}83pF=gn zz!+&zvIJmHE)3s-CG!e zD^@evH4iiI;Fs=CHO|OW8{9nSriZQkg1qT#c1rP%d7jAY;vrSH9)C~eaO|nfcVQgy zJvW_pDwn6G1=W9lu`D3!v@gv2lIyd?RWfh8Q|^Q7LJNKsVF&FxDW-FN)=&6iJNM$R z7Kud<|0zG?8uN8lvsmT3?Ohk)z4Sp`n2P%+^720g`z^gF!bzyGrS34f?Ef;Bev#^} z-b9#IScJmKo`LS+i2G+FeFcN8Hk2G0yAxk8s`X1Z`!zAoufT zzl?g;5|{NK&(xik5&>#6zmqo2611_aB5fksH*RdGYd0Hq1blu;W6Aevfv(cO|6GS} zSoRIm>NM=(+N9}WDtWmtJp(R#HWA@v&!w@eH75AfKe>*ZRR78{A)#b(y7`$on6N}z zk{2Osu1Hkt7I4T3_}_z$C7Vppb>z|FYQ{?+w!ba@m?Mz&XQZbuo$lR)i}hDZ?*zGv zu2A?@1V4GpFt2|V_dwy<4xcehi{;n&;#(3L0v5+qPU`wC$ls+1=I)N+=s408{zAIa z%<%&ANyaRiA(q~r{wn1zY?`-iK+y5yjV?jxb>y??V};$LIvZsgy{lMnt!K%1`~~-; zJ58i7&0Kmf&hzbY>uv4BE^RjRf%!@M(r{mdnhm?62)=bc)|x>E$@%+%3U;H>_gA5zC(#62_YD zuTqKYbwQpzIcEB&Ps>2`G&bT4?z*|6euL&(_tR_2yHz;&_?*;wlR}?dRZX*>(ml~% zr8J>BVmhWw{cR*q{#(C@N*Rq@g78#)mf0!8qFn2Nx-?g$@$RA5;95(LH7^YA!hS!= zWm#2w#?^rF;NJb7Ay~X@NSDUh*?>E3P83HJyk@@AyiytV?Rv4pm^~i*`}ZdHZ{B>gL<4Clv1;dR(7&TG4dIr^8xf{QLJLI!x+dd7}2>J2@7=wV*v! z;VmC8n#iR^`#U8Sn^r%WZ@sTPG@ZdxX4)8bJR*E9T}a9#q0|JM?~`7`U*@jo@Fz1E zeY(4$=KHEo;Uh1d;>>sGwcl8#+RXcdA@P+Rj4MZ1?{tQ+_85x3^k3>Z{J_!PtZw#~ z@FjeCbxgbbn!`E1rHUL(-3QK}icQz=^^V+l-l%r%j!nk}?x?u9Z;!7cuTncteyr>J zC|xmZL@m2Sk(9jYkzi(ppI*V1wu>+yyn0-~GxF89+b;UIfHfe z`8wJ_b3OTw-IYC^DJ2Tmj9-|rD(ZK>*~yOtErjQxq}|!}^$kle_%JBP9pu}gqq)C1 zuF+k*>vc|D&`oy<9rc(uHc4uJSV`Frt9m_k2W2DXN*|Zyt+(4g%D-~Ez#~N_>fuhU z4=l=Jbdi};zR&+GFIC;|(lHm(T4-lPuC+86Cpoq7QkLmfuNR%P#T?Hccv}6u``r)) zwl!>Gvu(Zg&xOl&K|ROTL-W~x^8YKOA^&Rw5#10<8j`zL4bll9x_b~4Aa7rRlS%Ua zk=a)?jY87!>lI9%P2XSUT3XIrmgvdv1_l6x@)iBEFhLs}S1*na056Z5lpB$i`X}t! z&M)`mVIH8+u`n8w78NIh{Fb};9vA_T*l|oA8gdxO;V+aB5Amr?+WaILWnz?gDK^=?L-~X4$*# z|3i|AIFDKw5rCU-U>HE5X<;Jd->BJo%ttWl0OD>D{QdPf@Bm2uKEfYQqbGD0 zn12m#Fk%5GVuQpS(s2qzf8!!B2jH$a(Tb5{^?>%kpKF&tf%3e&?Qp=PrHI4^Kuo~@ zYEQD~2}iE-9B04NA0eSvl<~Sk{T_Gp#RDgD#>~pqg$fNac@^q*8aR{-y8Y&6J~ApQ zeNi-~JVDyU#W@zOpiTWq__|$w&YM7uPE+hpGku#2*WJ_|$@BHo;qaX)U-Ip%-R z_ncE!Ta1KL=C$&PZnU6|)5?0|v3E3H?#2Fz*d;NiL>!%>QNRE_(xW*e|&oFDLrSXiM|3G=$3Bw5JtIXB89 zj3LD{Z;bEJuMre!Jr-?USYZa{`B4Exf-}yu5*;;~%e*5<6niiblldK}x`BBK07>O#Jw`^oT{cxCm9uPtQf1g=(w7=%krO1+Ac(&Dr3w0cDG zGa!ZO6vI!s>oK~40x1W$axXSCwkSBKp!Y?-!AkPI_d8c#qRpDC?lV+EzSLH)J=SoW zXLV}%ScJF<@k4Ite zsp5`Kxr)(zTW9^|bc-H(`>XC_LgY)5Z!Wj)Z6TMN`aH1uBbQ&HAn>XUMDvCpzqvh=e-ZN_pOlwFU zwsD}I6L=r%?R+Y34l&JFMNr0-pmYEPrNe=+D$&TH=g4Q` zqk?!axzGdHQb$6Bs0#D-&5cUXfM!%gPfS+PT!t8o?*u&pKz5|jexe~Lz@zx0Kdp#h zF$D*<4*CfAkDi%4cf^tH4D)86?dY8sF_XuG?$q$97)PtHmyFhLGB_vhj*Gv0$L1Ub z_Raz)_mz3m$r^nZl~uaE@)~sCCnd_-qNJVo*sEwW?6$(hO&}>t9XI>i(NEre*fTb8 zGYrMwtG_FElh1J?4lC-?@jHSupnA7pru*)=>}*Guz_S}5=&08jLUjz49JQ(?(;5sK zseSF&zZ7dBl6%J*L#eLOnrR`7BC9TJHf(wNAv&4-PfU-5t?6IZ<&g0V<)$<|sHam- zS0W+fnpt)x$1++3b5=II;0h_s(rJ76^%Gd=W8Pt#|Y^~v4e ze(?(nvC>)nkc&7Mo-u?`{_IMjD8|3L%XB79TW>LW{iR;-!(#M6f`5aKK#0X zVTi53^6&e82|Z#v)g^dJ*!x%>4RYr9#6(rk50Q_A?{i+96%m%gO6H3t9?T!QJ`yh; zl1L@_$EPdklAw{FctLK6+)~E@-;11xO}XEn=azH#(&|O}4i@fL*i~Yf;Z{G@v2DTc-2=UMl=BygiDH5#mBYVEd){Bl=qmX>-$!fI zo~}0KEH?D1VNUiO%}*>tUp>!*4^U`znRI{z%bw2^p*Qqvs}>v z18%6(gu9Z}>UxKah0L=-JgukZdiJX{mM-2>T1NkS>Cd#iDjtmqRk6c>HocQ%d?i3n`Sx3*@4>in8OMuFOQS-{ZoG}WANe(o)g9Yy zU0waVd6V_SJicCXZd4*U+^@*v#M!5-fhO)Bo%3a}FMX9uFnvvr*HSF@3m3fm);8i` z);2mV%M>%d6z-ab?UA3b6E8ZowBL7h_F(de9l}3i`f>!2wvaQrz3PE?Dz+x(br4q$=nRAO#=}KgdVX5|GH2Jk5jQghl}I_bZS>=Bt&Y zO#pZEpWiE(%Mjho7ofudIQf2tXDIYBn1(ks_`Pbt0e~b^Q|hA$etD-E+Sc9R&%&}GQG{e9>CS=WJCCy2P{spiF;3()B*eQf4 zfL4t{3A+nC*l<#2T1IX=Gu;C71>len26=KJaiBfqE#r@crM)B-5u_!}<%!`x8}J1n zWeapkLWF|DMeXu0ql8>F>FNoD5pu+nLy9Q0y-mdv?gjM7PdwM#sU-{)F2lYgP&W92gU4#pMQZBY$uyZNk0}K1>kT` zQL5xZTtF<(HBn#-)B0y#P(LSro*5VmfXFgq0)*i6nobKA9CQ7P6cU%x#25oU_|`|y zbEXVOLuD0tcMP)rpP&`6mC2_%j`kGV157+$Ka*$piwSHQDQS)ZasU$YnR4IOX)vvT z^t(E=0ucWS>V7N-Fpw&yzL^XgBLjQBy*epkKsE+5Cg4Acq$950f#(GC9Xuby0X81x z=7C-BRi`YE_y-8Z_BA%EGbU9B3w(Tk#ayG=f^Mi(@|4~I??}b4_WH?WF8On7OIKN` zTUD+wXB1Xq^T+V{CKmY?QMNUADnte1C&R}$L(C>QMO?hp}h1nhCJms%WcJq1It%< z57ZQq?fhJQ#F62HPsq-y;YVuOGF}|Wa^}%@S6JsVkEUM8q2AEl_@X;@q%~ag(jmj{ zqBGxxHgdnJ=VFy4FXr4jnaMMyqA-yX9y)%(Y@t8PTq4PQ(Z}lI=fe@G@Oxyp%S$gUx+JjHj=A)K>qM{nP^{ z8_OKUw|flsOucMmosZr3?rPSFple?xB@~fN{S@c>pZQXUv1vDkI96Vl2>K7%EbcyZdAsbuqKe%kk2S?2ki($j`UPdvq?{LOm%p3$4)7G;c~$GcTO-3z>? zEAjnu?rDjTkG4*iwXX`9M!z-_-1!tkGx{_ql_l+?CQs4J!AP1?)wr&&D_$QOujhMm zq#d<7?buu&r`Wh@Jtbt^Qg-Q}t3g7j?=R0j%_FYdW&Zq1JeQKa?$2O3xTOpx+v^)& z-;q(rowN=5q5kUCmp_e@U*79kH#eJY_P;9Ae7)3;TaM&Vd$zvMxAw#8r`0I@U*!RA z5S>Ru6zq(oD%KnvX26y*-MVH{!vXSs8$<$t8{lBDLZowcE&q$Fpl<6d8 ziBil2!~opRBAPUmP!bUDKeD`X4TukH=Pbdj6Sd1vpatNTwJ;&5tqPmORO0(=P$jLT zjE0oVKUdwXfEa*N;-#!7NBhCd|D2)c!90a#0FLb}Js!2C3r3Tm`7<;Fw#vTz59rUJ zp$LfRFHmjQ-bhtHqS;sgv!OT9LlX$I+}2BQ$xeo-FQ37t0B{wGsAQBdq1bxjPwS~+ zpd}<72r5Au%reQw+=FoexWximn9hDMQt$8_q_hho^Z|%t5(0zfA0{DIe~l?CvwdlX zlo>&aZe!SS71@;bC?SF`m4)KCbspxZx@{|@%@v4~Bso)Cy3f&z{GyN!kjo{c+UF4F zNh;pT95PoVD$vs~6#$afNX~_O7>mk731Q#|^j>e~5lH`oi16u_fI^!wK5c!xhpsIG28ZRD0-Q?&8~a z9Oh2EKUM+E0l38_T48db`>@WV&o0&wE&*(xVJNM^Y&uj*%aHNB~1ken?eRZT0ryvCWh~)qbB2B!dkq5m1 z7@9U4|C zx=ikuf<SbmR(Y_*}vo^X{AL`zfR+TbzpI_B}KI zS#7AiA@fq+MU=f)>d|R=WpZQZU%R|6FYep8K-WK=zn+eL-1PZZ)lbpybx*rq&biB{ zNjmDPS~(1crgZP+9}gR{etJrkd&dF1@7JnJn}t<9FTSZ`orD(74D6_uzS5!nyzaJ- zE>g)B=g}UiP}F1b`^JE%i?H?L-liUlL-+CmV&!)ifzzr+p_U?-*7pI|i+-O4c}3 z&7oiS*}GxO`n|Ed-*DM^{JyEimDoPDYPBxoB`?1`^A2~FZoI^jl6q={fiZj2Q{2zN zKg-=tK^e=&hOpQIXiF^~cX zr+NpHKaG(^Lv;Yzl!J&x5V`<30eMO%6#4`-$C9Hs5T+bjD$EJ!18fPymhxkNQNo%F zBZPvoB%D)1%s@P++ws(xF8!-55pC~;_}Ld20B}>CG)pKUU~anic7B{QsGkcYwG5$z zB9Q}WFyeiot&+rxD(ABTFj@@hiVXPdk|eP(2gZPHy-$HeKcn1@h9o}Haf6;0L(10^ zC(Z!F9_f$#;|r|*xw0c~u0RZSdSPz?1Wxg7GJ#ld224?7uIrHmTSv0VGT=FoZYq&n zg#WtfPw#a&eNbl(Xx2TiMfr|5Hs>X8K6_}@kq`2tEP)iG4ELxjgD|a^Fy$`ZrdPC+wg`!x$zkK_zCTKT zhapT;zl;8(eB%X|^ikOmsifBF4n=SI-69g$q_g>o{t`_$3$4d;x%rdBxF4|_3Ntmc z`jU@OQd~WDuj93y#C%pWYw&61U(FQ#vJzsB^q&*6ns&^`^o9+xBIh;QczwbS)0ypS z|H-geV)*XMvmz-|X&j4qc;RN?;}7vW%+86_@G7Yew)r)))kN&lTami1yoRp*c3^hG z_bT>up`F@@1xA8?bToIz`WGtp+tLi&t9MW9@zK+Bt5#lgH&mLtP_m%-xdE#;BJkjd z(odzIUU#0awn`|6PU!BKI;GdrTRbfq7+o{> zTc@P`KXY`yT-B1#wC^ooJ^0!8d|G32$;4H8E3DK*Ps!r$Jv*%ApH}vcFZ#djJNzjp zz+Z=IHHChFUuadQO!r5-8{dkh&1a3%b@(~uvKy{vL)47!^S{EzU1==6%THM*;^F_- zrA9EAro5UAZ8zckZ|fI0(Il^hB%<2~8WC`2j6!FC;q&L_!TbR+1H`9uPZE+Oh-Eg| zHV$Y65FDBv$b)P;GxQ-Kcj)86@IntDUf+N{KD}=j`YLMX-c@oQOgOXyo=1@jqJ#)l zP1!YrWj=7u4w7;jQc~N_Y7LMA?&VSmV6#5H9W|z0IN-$DSc(tCMDw+u$y69WesGh; zH^DH%%%Hu1V?%!IX=cdjdJSs9F8NaO?;PAm&xLOFg+s^A2aU#ZA7CJ`Q zkV@gAelL&L$@lQNwMMo+W{TVf-}Z?tdh!Nm?m=BB$jelb?zmsraO$>DH+nc)Y+{Oc zVS`+3q34JVP1nckFXT=X>8?-?yZZ{t8$T~(HVdbtjAL@D5OKsHCC2NIL$2;ZG^ORr z>5a3G*1S;Bi8F3~ar30rtw(zkBcpPgLa_X1k%}x8N7m350n%r~OIVj~*3e>)3yOO? zH=fmed-8Gq$)#eNQwNSVKd+)^_u~1@p7mOFZK0U6Mld*5SEG5AYVvvF)1TB@nlIyw zKYPz~zlt#vaYILH{YHIdb}e%|p~Mz{JJRiBm(g{PUo|5qO@Dotv^ySm{-+yWKcQu2 z1xt4?&|s7)RA28+`h}0dQdjJxj_uc4DWSNQwD(>?c8RV-Z^=OQkl>7){6d72>J5pV zhmI%DsKf>)rIVRRg`Q31kC$OAWzo@lf9Q!Bzk^=??fn5?9jzy;r7*2Vyf=M5vN`|R z*_6e);o6qOZa9p-VlVlreDXE-9?A}MFgkJ_8~5Rootv%Sv#~ff$>qn<$7}5S`I^ly zryTN$cqq)G=`2w@*w;2L)gX5Eo9rl)%Ke;3zZ32}nbk7pHlM3B&Z#c&B}JEAc$Xyp z+47^Ru>Z?lwPy>C7km_*el2-tL(=-;kXX%!_bbYx^kFTy=>1Ib%)LBZfu2J&2l=e` za+D@u!yibz@h8K+II$~M&gfuEzQUy!_M5tWS7%lqdVN<^#+gTM8kxi(52J-fnrhLA zLey*5k5OMMBP~ubJS!Z@zQ%>UmGWW)YaEJSTpQkjX9z6IpT6&wqGiheZo~ilU{+e~ ztJkLxIyY?Vviq-LvVA7F`iuLVF&#fN=kbe$Uo}cN zgbkRpz?*H@HlJ{n;1DsABW1a8Ie2s}IT}14B>6DJNF*zjq5HA5f?ea7e^!8~jbp@x31<9LkxRu-QV2r`t!1G`PkJ)<4Aum| zao5wWlcVp#JQ&)*U#Wv;0KsqIK#sN1n4lw|>)CVglUkq)fV_Q9c>oPM3^@`)$-zL3 zfUBVoKy)`CG&AM>8Zt-7Vs5KjNeDiP)dz1N1>h*BDOAbP5NHt+36L`(1_q?iYKsy2 z2y}uk_D`oG{1iYOhzc(Hw07ygC9PXu1wP z00I-@!=kP0lQ~SE29A-=(N)SdHd3M~5g;^8P%?CAvCNS3B`a7A}tV?kD-e~qoLq~#5U6M zVxX?GRomIRj6(8d*%9Z{kh-C_~86g!%)^G%W`MF^LPshkpwYvhayA%q%&Y;UKt>%20$0 zIK)pa1f&4mm=ePeav@!yeJR$_Qv|d#+eQ&`Tf{urS)c{r?nR^CkfVcO%o8slz%PYn z0AhBZnhQr^2`^T+qVZTsxXevTZf5`qVC&2XL#%5WcAj4$8NT!zaBsKLP4NDcB%6DI z7J&5pCV#$_VR7n*14GKN5Ujl@mJq6NNH?YIffJX%Uy#y8F&K}YknD;Lnqf@6kFhoAGPX(qm>y@nG_3B6m&vO&AQTwm12 zR^H~>l2@m)3%9caBwqCITZa7whz zTUb8PC-@|N)D=&+-$QJME7W%xsCxMfMaf^1&lhlhXgaLG7{f8{B|l1TXb^C!on|fZ zdO+vRfLk{orrH}`zn3v?S>w+8p{OHbPQrOOvfFaWxrvoG{lonYa?>tPWY&6d&R6!+rr@LA|2gL7 znCtlblk;73ID_&}*JHgzgv&|A#@ zo>0ttp{VA16f?8q*OA-1$;!zrGh28=#MFOEtDSCCife03pb=Es$9qCj=cowp8v~Z- zQ55>!S6!<0xuX5pn+&Vp#Z%I^9olgdo%Zsw!1=w!V~-E$KHkOmG;GOhrou62Hj~$! zU$IasJmE4!_zNlNeFpbis#Ag!=&q^Y<7lm4G29&4H zoi#7W__h=_8B8^mzFWKKiA6k@*b!7xgSxkbmoV1MaE0-$P4K;i4-x0qajj*3o9qWq zJxyEm6qa6z-g|a9=eSeja7Q_Ne%l$H&w4kzH#_%inw7ctE4FxgHtSM$KXEj1sPNjn zZ`_?x>cUjMQaX14HIjUj|I1a2#@bV+AFwLMrMmbvbeHUgGm??`&Q#HXCQmXxX`Rk( zadQOA-mwa?`sdpDSI(u2J6b+2VfSvPj$s#<&f`mK?I!Wg|JrtfLF%uC>*#+OBu->U z9hDLKHgwhUL+TR;;tIh1;72zSpPHZX2CYfd7zJRQ0YqDo08(pw+e7R)$o&FIxkxK) zKb+|XJ^+OI3IjXxrWmEOb#u_)v5_GMl+iLNPA61OiMC}sVL(H{*g#ImN+W{oko6}$ zfM*15fUSXP2u~V2jHGBakwZ&pPRw`c0}xD!-YfC~^h@ewUI6V>oWXOj@8P{-=UScsP%K z3|;DF;2+Gu0DvvK>QP4HD+DiXOrPzlI9CDcl#H3E5aFr;DOu17EA5?WIf8eS?9a)aCEt^__DU@JAa^-$|n9enF{Xa(S$>d;o`trtOkI?(I} zoB)ZZ(BH5GYlGWQFQHFzJGRU?Buq$YRAC?`;6LTXl=$M)uMRQa>B<^A@${H<#>pS# zUZ^KSy7!Z$cAsgz$K@4yJ^y5uhwTYb!PJbaB03#+g6_T2<=*FsM$13kXd1y!O>hZU zo{S{JhTL%|6)jS@ep7^}FClf5iXbhKi{WMHi7 zww%x{pOPqMe@VWOP$GO>d2I5n7}Ccjo zOA^tL14DXxU`$fF3mI^w5k-W0skpZk%8?+*j+es^066O)+CwP9Yq70z6VY2CW#Ng; z2uJozEI1(BhZTG(E+jmbo)N7N<5Vs{*9Bk(K)x@~pGHSQtA!}csTEoQxFAsmA@Z#< z4Xfs5>y*EQQxfzHF){Z8XaUHDDO#K`1TdyZ>HLrZkQ#&YK{(yuR7;X>Gyfabup{e- zXfFyu(Zuw{jxh}1U#z8}+Cg-}Np2ruHS7p=7;5jofhyPnM|( zs_7eP@>0_O6c-bK7J!o-hTs5g0AHw+l93l<3C#c;{PPiR6j~gb*Ww|zVuxk`ZdU@P zl0t|O;y5u?E&lxv2BZ|W|2+VyB!#33Bm}s1Na$ZuxD~w7u=;R7*!Hi+ zfnp}oXABEefbjr{CNyzdisj06aOFuV1s8suI*fcPkiTgKyZsrK4Zx*ZVd}_TV@&qUtR!`8lpRse36p3#p&$Q|amMk(Eu_1Ct7q97Ghl7KM)G0C8;6=ns}!1tQ2 zOrTV;Bmsf{sImPDcl$vx6`E#0`PP2}nu&zPkYo(U8bt%~A0dFRU<19{51awWS2n6t zG!3-Uxvak7+*kuG0B0ve%}Ks> zb3kC<=O=IvEtmR=}C&w&)(gVNSx7!^R=6*x4Ac_7rVx6cQh)E&tEKokcW+$zLb01Vo8ydEn+ zZ-Cl*FFNppf_MA9C=UITA{iwFZ(~gJVx&b5(4g~Jn>7sgE0Y!b|phOmJ>)@ zJ;d|Mfh-lA@~s^Ne~nZk9*30@@E?C|GO^2%=K^zct+VH#tZS&@yu~|lv$Rhdy~#|w z&z`Jn-lSQmU>C;)Qd!N*T@mPBry1M-EBDxF?f~aF4aLh@&x zh)X#ef9DQ`N!O3+l`4MexxQrM(KSZ}k7Bz~0c^hp+YGZ<-PkaVrU{`Qj-Tivi-edWb@Aez`)%4L8)f;}+GH1wRoMUa)ns3>e zJ057Nc6feBl`l%|;oP(G1;)n?4T64D*YB=&PR8VYPbf2QkN*B{!OY+@vQCkq&cWN% z;J@Y}_v{(%p3kopJo&iU3OsZ#wPmqk{Up_xq|>5%8~Q_k%}geruHUqAX;?`d+r8H; z`TU)$Y88Rsb5E?<9(K3(&uJW4D^sh^m!m1C(JEJcY=7=y@bLQF`?`mvl4<)no^jlK zu;hLr?hM~u=T|Cj(w{h-G7!hs!98i{PjRhryEs2z4wmlO{k8jH9_N?Ao0+QIM?%hF zjZeq8Zz?Ty2c0s$_eaNug*)flWZX%8!-kHxFS`=mK8aKqI~sBL7_(b7oH@hZ;(PmJ zxWXHLzM%(V>favUI-pgIEGed{hBReqiapFZjd`Q?Yqs~q-r9>&Ka5amwM;*TIQf6^ zO`M4ByQrO+fU}tXU?kC2m6v`wHgElyt8gB+u{mqqH}}L`=g#St!Ki)^1kK&52*S+4ntyYCXIt z27Be;Q(ot^{{9=C)8=L}h}(X=`-yo|G1b*|v{b&b&bxkh<9>xI`_1F2Z`*ISW7CXY z&WVP&n$4X#FkHK@*!v7anf%C6m514br~G!RJ!#rJdnwa8ck@$!GIO>4=FaXN9gZ;< z3h@^P<@NE-3!7%Uon^6jihnKjma&U@0y<~g*p)m%f%{JQmvOwAprHSX;MtHfnUwli zInWr@IGLp9V6X5b)mD}-L1?mrzl&Di_?217LZEr8? zzA(*s$IxJqo>bCz+Rzx&4}B>RH;@x1*l(+vg#3RckvBWi>JE zOtp()r*}P5a`GWB&y&9|SxUUv?NDG;!Cmesor|Hunkn znDepw(RM9ldVc(7EwhT!>9fDvUJpOg6ia6Lk#|vKE%I*uK+p}*hm#>o*CdAZua*RuP z0sDGg?Ex;w=g>2gly~cw@w2qNAFQhEd(uR0m&~6jTwQqk-gNmqqtDE5gBNJ&^NI3@ zo_qG8h6Yl9T(dI^7gMS}nYH@kk)+n}S;gnw{UBi{t(6q>$tP_bW^0$T_VySLpKW;E zgvu^_o|U)y*S$)@KmIz3cUM7d2dJ1B|MUO8wr&tX`rA}gYj;;a9E!Z{i;)W3Nr)jh z6aeHU9St}3sqAqnd%u&{+EU>zkHDxzFlUd<0QT{~!<6@L^iR5U_g-U^oqvx{KcgpG zVtIq!Dd%TK1Xr`mI`G_n(DbVQw}2T@rGWI$Gm>&EVaHp_?r{%_c!5H*I3%Orx#k zYkwbkSXvW;J)SZbBYDH*R$mXAPkz8v<9s>A#@MEYvZHuJZ+2`sllYGns;-MgVxBSk zC4Ecwml+kEzumlavF+ClzXU!;k?0-r74b1jc6N7kdml^FxR|kiosSj%v>E7KY4UV+ zv$f#KYJ4uQ+3S?Icg#n3ZhUx{Wb#>)`&V|PqvmqQBcnX*z2vmX#ahLQ7g>c8y`|*J zh3DYum& z+U9vLTe)g8mT)ob9b5XsfKhsl3>O&%!OJzaQ~vss)gc*687wSTS1R+4oKzdqKL7Eo z>a-j7bD3Mg&80cAfQaei!upxK=U>?wpcAMy&N072GAKN9rD`Ry7^7ms?$)d+aJbt@`1nh)Rxo_ibyYfj3J3 z$JSQ{MAf`+OM`SbC@B(3cZ1T1AfX6?C`xzBg0z50u7H$MN{1{+NrRM>NC?u>-Sy4} z&*Sg;zaOqI=ggTidv@lYJFgMf`r4BDhP~v$>U#0}8L5!|Q<47MuUs`5>9U3Gw|lxB zQ@q_6J^T{q29L+dNWSJTe z22F@hO1+y&oLBy;MwaG$}6Z`tqF{e6zFtXp%DQ9ki` zVS7gAX}QEqKGXev`e8By=h7#2k*U!8hnV&@2CnA59r@!W*E_V@pgx_Bjgzo~0Ud?! z@z-S)Hf5ieFNZB(+x=ohouK*hy8(mU2?kbe38dj=z4k3*vqQT1w(}3IY{w@$Pg^B3 zS7cUyn{ZN}1w9g&G!brCFNHYmm&HHZBKEb_HZ*)UTbeXWToh67`h+2X8;=|EmsbD~ zeL}VIK_1j4u=W95anasbNdg=#GXd?H9QdJ8C<0C0tv0;(BL=!Wo2 z_P{N{Qg90Zev1Z*JB-Q74o`A+Gt1Yv2V2oHDiIc_|0v;vN^*t*gOUcuavj$Z4Pgs@ z-2uiXEf^61LhojWn;cND4;BZ&MKOp9CjoUC6%5So@avIj6ji z=gwA1Uwn)7zYgzAG#zp1Q%HVSyqtZXJA1KDHXVnNfY2&8?HN%;%@3CewF>t+Ij-8B z-{Q|E_n*2=bnSPqUEWxxq3`R+z*K0v+dy-?9D$>VMmrN6F8n)q;!n&oe!goZm)+MP zH&{kD{1mHKd257AImOFVQD6MMTD~3Prh+TEX%lm0-%K{y@g}F|Hk~@ZNlx_hy`bqy6fm`OHk&;m6Z1+fxqm(2 zNJGg^h56d8&uOVV3BbYi1oMpK%{+{#z0~wV+0z?U5A3 z)n!*W_L%UdETFx(MYhbgN!fTfAcC`!kM~`1N8~djUZVFy-!6*ke5>Y4=dsi7PPyQh z{MNITYg-QzL@iXGhabBB(%yLr8{k~R5s7|5tS#(bro~)UW#jz}68!k-oQz6ksED_S z=*=bF3E_jCq%Vnzw#p?h*`5iKsf*jSLlnBZH#N1&6D>!&%1ch3DjoTF_sMJSjxx5{ zcNSlgvcBS{(Bl7Qa)dU$G5_dCbVFkuHUlkHgEHPC+41K)uFN<}4dg;U$??QsMhz|c z+BX?n+6lJC-HNyr3h51n2}eAGj(n3HgVkwMerhKkyeJ_!Q7JEOa^6_>&YKLUoq-fl zs~exL@zoMDVGXtKrY3j%qe_kxUz7NHvBu(Zp{b;jTWag}y*T;Uh^ zJj+YF7g`CM#`KO&FX3Qsbu3#T)C)I~`n?=b7OA>KqAPJdbLg$%lgp<4XEB>HpQpS%J_z{Rq5I=s=19AUp>`pV0g{NN4%tSl2_9UUVc zTwd=1?)?#P830P!i;=_u5^9X82b1vSfsp+Qyb^E`1*GhSi26ItMg#xyZA3b+jwB`p zRCbII=O51x5Vh=x;MIQ%1>wOfq`+L52h_+);>r#K4g5Oxg@Z0{yV= zBDp~H!f@aQ{Q$rcSuk@j5JX*gBEa8)BI<&7PYIP1A-Ka%54!QI5|*|F-B6>XHTY$y z#Q8n2NdQ3Q>Ii6Hld%}~7>HaTnF@4qA|T%VP);j2-?RX-UgE;tDi6UThggltfg-nu z;SnFz%WlUeskFsVO>;iW67Aq04B0~?xSLM=zRY%dk528w3v%X2!Y5JkxSE!kkKQq< zIWJ{l++U0>FFQXe!?)oIRw}7beO|Hk$oYw3mEC39Z&*xCbW&kty`dRI)gP#nBwuI+ z*S{i^o|~SIsy97trJcVjGfe>@WZvFSh$p_KK{rRwu$|hqvvD3XqPxP8mwNlw+uI(D zyDLGS>m3Xp-RkQ&wda?}OE$e<_+&J#c095dTaJ&K`{7~loB64{REwI&N6H6-?O+`L zC3S6*w7=m8bLt5dU!~}XcR1+Dg{kqGl){0h3J3V_39yFWh2vr8%)CkngoKwqe&i z+6#0nMP%V+2I=Nl^I|+zVH8F&GR0GI$Ml&;xQm z%Giw+>i_wmBme?r`F)Zq@&6S z5Waq-xSRq52Y_bO5ngL()Ez@kFz;@Irx0HU{wa~t_rhy^eG5$<4N*;j z4-c=hfB^y^_73?G?07`sXtyI+1@VMTkL1U3;q_6n5zn zEdeSiLEs{J62;aEyR3q>hJnaRP}>Bb_9836W)tf<1_nHIUDXW29T%bNv1U9=G>mX? z8NOK&p~^5?z?cA#+Po`xZQBn_ba*_a5WE^uAR=_({7wZ;0brCRm$}doVHzg#FJ17q z#i$e$kduz`-6w*!05A(T91wbeC!WhH0Z$o7I)^8o=a?y>qe0-Tk9$r#iuj-hFVyTs z#AcEIj|FH8$A8>mEiol_jUeA)ooDdM7YmErn-579nJ;k_9*HsjCfsPXwooDnibe~Y z)%3u;MWO6=gJ`OUH04-5?DW@&%;e#vv)df253r?vQC)`wO=0l9oj~s=!EVQY$vmYk z+}9O%*u8ZUE&bVpUXcq7e?r7+f8 zkAx z>TLG*$F!UfghFxqs8lI`_>H?yQO+x|nNxpG{u|02ZnAc;jOg(4OMH+I{NL1;#bFK)BQHqnmW6|feqkDda#>V$OTrwS<{DB|D$`6XcPe2$TJ3b;uU#2!PN)#OT-084o+l4`&=Cfyg znlHmvNw^O^=U;WX?GRdi@SW1l<|dGzB>i#rB5gWZeRkt~2K~mT`<#nz16l974dzeB zbnp4)2`p<(x+hx~eaV%o;&IbCllkIwy`+#__oGs6_YLfy=uJ6SnE!}ybsSm^59*O9 zKB!}^W&g120adqP4ImLb>!!M2qMlG=i}l#$(feEi9mXR2;gTEC_a;(y2AyddMOR;C zYrp)+d6Kd0fh*i?`*AHMt=VK|>aUVDxJFDb2wVdK;9~>8qy;fQpu-8Fp&M;rm-q$# zL;x68I{q9QLRP_PUWo*eYx8emg#oBZpc+y@bnbz!0HAhK*m>-?!Cx#7TPFA)-u!=P zsBeL$0ML-{m^TsSqyIff0e)5iGP?NRkU14Q$TBdN?UZMX0<(u5wQT@S4HS_BYKMVQ zTcLkMhl?IS3<3s@4B(*z5K`QM*uL?RbtjrK=;!x^59H=WmfTA)L;zUU>&vF-h+QAa zv5eerV!&MhWJiE8%J|FG5!HGi$@(w!>VFDA0fiKtMhd2^jy;0L4&t}}LxKaBvEU#W zRCxO$s0-Kn;hSb`($qhDW?9Wt6(YP4Yb5?pnoF#=cq2Q=#Wv>exaZsqR@23D0+ipV z8vH0QQ~;nBQZ_=rqFj(&rDfU81;Je*@Bf>6#{riQPH7^;6Mlju2W z)QxW9kuTV;)~Efn?5zTk&I)$5zzPi`8NAdzj{b0Z>(bn91MKfNAGUviS-C9je$x1G zg*!*~ZDcAru~}~mJyXj(SC|9)UeHgQklNe5>&%dBg~|z@OSgO9kmrOl^YrG}vs!A6 zux{oM%`qI2c}>3@Vqx@5>5I_*y2!E!2o0`P)9J*j*B7H7+zO!h;$( z>ShU=0s8vS0_MXfEQj3lhtZg&^11{~zY)HcBJvYHUh(!O`r|fU`Qrj{7yzVUfZf`E#EbOxm=X9dRVp5XTtGYg| zQ>DBw!44nd7I_QFD`z8kq+ArA*qXX*tF}tSu|f{@@g}K8V>fC;Dj!lA;E6#V@b@Zw zNR#(QJBAt^sZBaE9C!@}Rzx$Y+mNgtmU`s>oNDq6eYw4outSwD=~jJgIHAZZ**La3 zZQz9#k2fu`@DOvZFpS#&vddUHtdTHtpk&HmNNuaQX90&NUE|q;ZQ@V!N?gI_42tq% zs|`yxc9_Nkt8YDG!dr7?lC|HbXB*qa1T{^#&E;Di-&+Zvv^m4;C%LI{#OzvjLMG09wU!`6@(#QFgVU^81c)!si&f zMgGb3Zk#_2{!F9FMjyu%3s14{rQ@)MB-LV-J{qFgON#mpc$mHaJlK%`IB6vz*gxt- z%-*Q7zTla3zKyvdYw&JV@@K1EigbYc^2t;Em3D}J_H?G6OHllK@%vk$O1OT1nz^`W zwkD&lH0jA>26VAQcDnHyKffm+_HqspQ*6d{a1-WoNIUQf9vGndVp&Hja+%)V(TZ~~ zveMF|Xo>)0HSnt2`{#?xZ|>f#qb-dU3+Ex)X*<*_k*wcs$-^?Ap*O+gui0F^rdh+@k6XQ);C0l2>zuOo(WyBSmo{hMF=5eHymfOGqWYGu79!nIg0vd^SY} zz8dSjOKZujxOZaan_l>NPgYzJv*nMP!nwPBwLl?HBPW~F+E;(>#ZZvl8Kq;{^ovTv zyFA&m{%$7|)BFb^FB=$FE$VsbiXGJJYVO{DvXi8{rDObPlh*OxNJSC*nfKB!PFH#@x+(t38EXkjcx=`|Nz5H{ch?cUiAz zsbdbdI`Y(~Rpf7ceax({pPZG*?{3^GASLE|JEKY`?Gv(4uCHqsn)$-~;bTtT4g2IH z!HOBu-EJ`_w8pWIQ-w>hk*0ZePOV zXAMQd+Z4A(2w+at-57hm&|T&Ujq_`|k}vOHzAlxqcinWID{`Qrze;H_jUYa8MBsCy zx=U5>jM04|wW<`zwmI>{U0v@t(z(a<3O{lmT$W!K6X;s13Nf^0q_no1w|kj!Z=Pok zx8%T5(6VdP->~bgRu})mU_F@zWq-f&BEuDJY2SMPppDXTvZk9k^3k>8_yWTr-*oG| zlRiUdTK6|7i`sRy*X}SS^M&BN5b1=JT3$VuYWI9?*!E^M2vSV3);}ICEkPjoRH8ef zd9YT$OSNO{YXj%oS5`Ff*Ns9b5*QXNY{`^Jw|p$-26Z3u7#0oPDhzWaD={AB=G>dY zoc0|lyf0y%nPS4Ddn1IKapK!*DCR@eU!6OL>nu5rJ}j^HzZErdTk1BKW{zq1PE>qF zt7#khRIvJWEP4?#%ly&UaP#W$n_tHYYW!cE=~tPlEEn986MIs^CB_`5QUmX4%Im6B zDKcOAJlCATaIZsrgBSu*iW#c~k}xP(4sQ8RVcn0IY%=`wKe67IdCaC|)lJ+75v?z$Fiy>jjld`WiHb z<8K`s$f#9lz5Re3Mcbr!PHOy>Y0|5CZJ}x*r7W2hOJD0>4*H*^b?M(DdWT~Z!lZ6Zb>-y&q0qQGrcK?;n&~&}EQvNl5mhIA zW)KRR$+ox?J39$;_tXYV$7l49wkNTTeycXcG>YI!XyI?>CZIehrFN3d|IMeN>!;r{Kd%CwnMvy-2q+nFsSr8CO@ z*KgLc;Ygoio_slXKIwY-tPGDx(C<#5>!uZ?>yi_{O z3ZF^Qj)qF@puE05r$;@#e8cJ@?~l>PaWt#&3}2;uviY_j7|iuDhB#F7?U9e{Fw`ye zt^s4h9Zj;~%q!tJM$71uw!+N(<{c!h<(1`?8*ld_atuwCXqjXL*l82e7in%_JRoZx zfS|p|ZbuJ4DiNM(vH~=rVfZoj0dp~LmBPBWd8U(JSJ4vV-!>Qr6F8sT|frRq!DuecL{C7&n*1jHrdbF^}j*uwR;k2&hE)FMq5bqphN$&S!ciI{ADg4vxN&J$ica;eJLS^1Mn z2ZiL>Nb1O;an=4|?)E+u3&IE@oCMja?#+=t$$wLm_kI8O296xdH zyyrbH9yR=tyS+Lz+Tb?*oy(}bg$&8+1A$Ew?hIk#o=1wUQDPc_DG$l>30Q@39z3fnx%G&%YnRf48vQwu zlWHRt`@7(w0uQz7TBkpG65|aWQcTVX*IleOnHqy8Ow=8hKC=XUjJ<~4Dvxu2hjN0V z0Mq(u3EwB(Yxe|$A#_)65ZT&?MNNM-C-6~NrTlT1++a^|^G9AMRz&BUhMHKrkA~Vy zPW;g;*|!*#bcfgMl|sVgdA&qC*-GuN`sBo9Wpb68ckMRS=6^R}(dyH%VO6!}pueug zSYP2|8(Hq?oayvOY*#c}^XsTxR_<%rWBucw+e&UlzfTksIE)5m2-RN13cMu~R z+L)Hf%w7qq!Pl#mGCiNOkDt~i#EJS>xWXq(l?SfS2e@!WdEfx+AwNpEUYK+^r?|E3 z2f!jSs&J4l01}W1Wf6gFSCpAi4(2QXEH@Ot4Fkanj{R`P@)?-lvnUx1KUfGUvoESB z;EX?Ie&2%)*&Jx z9dN%O6Jam5Eku1+sOXr}YWsk<3Veyy$75R*T!PRk|djk#E zojE9aM`MHDgYA}qY$G8NCJqgaUFCS$s$;n{g~pplv+QyE>fS}`wU9kizqFt1{`n1| z^erSA{v@N=`jYWPI)8-oZTNEzgfbsdQ>@E8xzhhb7K*!LPZ72K$kTPPg7z_G8v2W$ z%MR2&O64iW_38yO`(I}w2Dh9}+N4DK5CkksP+yOM#ICpL`oA16<29_2Bj$|K*Hb|weDxJ zc`z!2&hLRqi?G^&XPh5dDwPS^0>C#WEu~8wCoFh@JKX6Tbhx9Oey!)duN$TPdd@kc zKAqvvod-x^;FoSPznK&Mx^<1{cG^n2-m-kJe)_#Psy9Un}%aeCRi54uDLpuf)Z+L6llt?*=O$#hC!p=th%9LwvOV zv+_X=KXTYO2*JGxl7=QBhI(AyH|7Eu35O;qPkq$8-G_`-oW$&=^gxd3$0(I^a969 zia!Jjq@D_@@@lE3{t?xP*Ys5#NL3X^o0r3ROTqHk-B_^n6+~T2LD{{}H9zp=mNIGT zoe>+-M!$s1V=@_Iwlv*=e=yoe7;O7^L%CWO%&7Wp@qbrp395Nc*v>V$d@&rnH~LVo zmF7}Xt^yH1CfBW_Ypz+mKM**%oVplgVn~YxIH{+AGrz}qGRmYr5de^lrGSh++~pA7J|T!R%vu*=C^g-B2q(-~*yTYffA)U`-9 z9R6fP+x1%6NpQ(YWn`H0wPOAqTT%|Es2`eE&xa;l8avBxXEfNP45!u6{l@ZU33wR( zbY|0t^Wpt(%Ok$pe7^Tsd&J^C1iYOkA5za{brpW!J+`zi^~X8KrQ}&_QS6`ng42l- zDfKd9OYZBbI=pm{(svI}M>flZb|U61IQKkab7f{L@8`81#r0^nLtA#upY6Z>oDkt?C3yKVSdB&u{FEL@r++AO!!74|8C2C;a+^{;o20_bs`!D^FU2KdTZ;w2w?|L}%eC9gwEzUwGhgB22QwnI;xmJE4 zbiA@HYOnbotKj}$8gnpMP*>2wf~o;a0RV3Akwckl2rffS(J_S(i$4;RE3fOX#SbS( zM6TM4#Sd5zX`$_B4x_=r%a0^5MjzjP4de*!Z1qW&1ZJtH0M;h;SLZ09FNGbRQf z!kK*$F{A(?H@u{A z`aR|JwK*Jvx3xQ27LXiuXV*OK`0n@3&j!r~s~c-^n$*q%*pv)g8Te`Mir2WmjsL7? zQnOo)FSc{vF3WE|S~TUcN59#X^Y#=EqmapOw})_SaJZXRuprY>@#V+lQhSn~i=|7v z%cj?=d2A0ko~aq%l9!e|@^*9cV)jthOH{`!EcDr#TjrCjwN|^(&9kGzBr>KUgZs&SUhUpm zI&X1U>$NfUla4*!IH*sB&yz$wp@}%mxrJFlVD_Nrflk8PZ$>``yC|C;N@qRqPTMp% zUf4*g)3T%U<-7dO6f$%#{A1GFuei7l0efneL>N+Q{AWKrPe$}OE%oh5Es3_-wM91+ zZ;yRYYBA7wGNF{LaNeb&P)@^Irkh4i-x(VJGCDbcbogl5b!~pSMR3IJi+zT8HpdFX z?U|;m)uh0%;?db5l-tb&~NlIHC{RRt8!ZrthlH$uwl!9RRRF5Wg*H&6qafmU{XTs zNkAHjGq?qSTtM)uzIIbUmXrmq0>G9{@o~@)oZmmPRiog>H##s*5Gw_q0fp3yP;5y5 zT`Aphz3`RNS|6{}`twd6>^rtdZG7f$DY>vG?EyQ6?JZUDETvXy&9`UbB<$0Ld3S_; zUSAyEULq!RtG&49YsU@yfVA4!#Sf z!7VZ=%bS*w8CHSdar?}vz~ z#PhkVsjzn$e@T9Ru=q=Xopqg^dOOa}QlgELd0}kjWuWYP5|J5P$SRU^V+z%@_5nU$@XM-+EpW zK$O5*YQ<}Z16r~F zL)0M*tYD<;=?8cz0Fr!535*cVQA&thL~>x90LXQS4A@@Wq5`)7khi$NV@ReFpuovuB0=@&8R!83p5jge(~ZOoLc_2I!<@Vg zdJhBl0AOe;*x=9zPz3#d1HT|hjO_k@Dx=}mtgog(=EX%CO~Dkd0vfvt=%FZVFW?&Z zi3b-}KM1KKzwmAFHUJpK3@)IN$^~6qX#gek$KWym!qi~D3VP5?&JPm=PrIZ1An?Qu zq{Vg$J`wlXM%;V4}Q9Cn1N8$hWf zFx6Ug0yHF<>wQpwZwz_>fNtEstcIwML*zXnXICD0DFEV6L~zDN|H5EZ2fZJHF~X%S z;#g&5TT{>v0K$xe)3_rt0UG|CQEP(s7k?T5KXl#=pg92a=~Y5Y#1RtzO)`KF9QpbG z$_qg1Wf(Nz=Of7QQRTerV4MKRnF#XVpbgYOt(pL@06)@)9Dagbk23G;#Z7HBp zrdW#XV8$DNTwKQN1ar#@_1OR!t{76wLs@vpWD9mW&{kgdJH}P;0WSUfC!rit7o_|k zOP2yx10m$ZKv4c(&jO}UvvG>t5RHAGr+*fH1vo5588Sl%(3JUU{XNZyM(;{JP< z|8pA1#X7lOcUc(?V+$yieQIDP=Yk&(0RKU#&vOcH)kp(rQU`7UKqsUx$6y$NFHrv( zF9J;gz@JJEMbLw%gHE_&fPe3Q>}R;wFB&es zF1&v5!Z{4^tx!i6AZN(M*8u}%#}EZKJEFnxxxgy`V9U|iP3VZ~`tT6&H~E9h0I-4( zEa1M72CWgtaU=f|VQ>=w`G3P-4$p){u?1cX0r3_%H8_H|>Hm`&1J8a!95aAS8kq)t z0wDTi2Ud#l2X*EMLZJBnll%y*3Z!g9nJzHVacoXZ#4kC{0m{jB&;tOJDHp#Kkww*B z@VkK!$OFEMNd?MDk)AzN78SDi#$XqV0v*mf7mMq}@DJ@A7(Y#{q7xeg&M&3@oD7_c zc<)TUHErBgC@5&TAg>_D;)322xa(wi zFO6)Lx>b1MmpGTMD0-w<@T>|&{FWK|;`>13)#7{ln3CpaA8jpdKDDZTI+lp1@PR*D)Ty!T-|`L>DMwPHdow>xXy+3wtPp`z#sqINnorPR746?N+# zC%Wp%I|puQjVgxWuYXysl3E$W%64z#xqkaI9V$c8NA+BxCE6y_LZyjlYdpKA!hnw9 zk$QNE-8bfSZ%xzN1Y1qE6U`>0HZc)8vO%p8VGVn@^ZY_vVactlO@@e1uCbVhf#8-Pi z_r^Pp&E4k{Z+m~(PfHE)9o@{0I&K&FB84~YYu zyY3n)-VU4E$aU6^@=8c-TO;2MtE79!4~NHGCb%v3=}gr(iT30FJaU=)@=@|m+y27# zu4bK2K$OK&Q*Ux((PqJ)ChMVW!NeN&#QU$Tt6jI$&cxgz>=`8`7G^q?McI8jtRHk& zDawjHa7fUVwr?Ik9(Xw3B8zW--gD2pZ*J+m_kP0s19h#l8^>8ERLAOv-erFpzS;ll zqhte1r)nDrH4HHG0HDQ-fZc3;n?MCYg~UJw1jGoCJphRP;4T%u5{3YHh~y`*f|h zSmRL0K&EkWjz2A zql*+|)P@U=GsmKVnO(#2LW6+3JmbEUwm3;36(&%bzaWnjRU(cmU->^PF=5i0Rhi*y zec6bcmDgw_l~?w24tsZokk#4_yr=j$xi!^UPL=3tQa;!nsz(JvHK4=LPQ3f z$TnJT%lou<%By^~>!pHN8*T4OmQ|~AQs{^&eZO&4GVQRZ%YFX%vD;%D78^qGH*5^= zaCVg5aIs>frJ~6tGJTS~>;e-y&*UTiE~KmP`i7c#jw0l8h8fJ>%h;B8xR z>@k$n4GoaDmUnz4><~BLCwAxSJ+#V^Z$!;5`Jc?cU!sw@G|TUl%SJSYt<4{#;7oQY z+*7#(gAMP}axv4)1eWz@7o0YMgQ++B{%A?06T*wniX6rJ$NyMc2eIr>krmi6Nqije z3Yy*YrDv|ip)F&~y;KU}Y9&t4Vc2lG-)9;b{83<&K%Jqt9*Wk zMzNHdt?e*U4yLv#0kqw=G6*y?aAo zFR5!1#m`#alyG$*{@q*Mu4?K0`CmNeML;14=7bZ?}iObLi?DnB=Pz+8MWt)Uy>hj=mT@ z>Ed7fVAZ2jr7UIIaac23i~d#LiD}Z#h^C(5Ng#IvQ?3h<;(d^Z*t-fKgVV#KZ>0v$F88lB>Q&~;3Dz$EpcVwc}b9FDR z=*Ia)xehi6>;m36Xnq?IulPWo0YH1&@TU=F5dIVY6p93ZdjLrF2%Z7lkPnW-*#lPr zV6*vnE$9fJB!Un^*kZ151 z{2&(HO}r#D4xnQjGnbvI(gDf*md^QMr>BncP*0Afb~rwQRhD>(rL5G~MqHrfFh zKIjSnK4{8V&JH~c6p1kdP84_!0BI$`Yoq@g)d6&6|9b!w@|VL^%o2ORx^|&r4%!ph zBG07hIs<_xR?sg1Z0(HD0RvHnXr=`;PXTZl02ZKyC4_dtYefIQlt#eo46PRheV`o7 z(2;Viegw0p7v@#+yFgRBuz27UB1kjlD(DvgMwNqUgN`s^)?Wd>q?=s8Sl<9Y9soIR zc;{w1Ks62mPXNFIbg*%e9Hj7LZlG75fl|hcKLxI7a{#T}*yr*F_6T@!6$m54O*44m zHtM9S70?d=Omv%Y8=V~8uAqX5eD3l=u!c*?ZS{) zQ^CK5Ano?$2F7O_XbXV&L(9PhL?rG?F2My~Gb$d3_*Lw{&2D@{kgrtkuh#-!I*Lj8 z!uQ_MiE|%rq{qIYr^k5(`Uime)nHPTwbCbHB2L!&QFud5_b&qpUP*y0Zjc7;0brK< zXtrqV@PZ$6>;`9e>Vhqbw*wUXh$D@W51=gowC^pEk;%y931s_esBvQd$K$+@2Cubq z=5&k{PO8mr$nIkPFcD8u6#{OBDHhL~5p?t6S{#q6hSL5HfuHrFbu zoV+|8(SlRunU%iE#OYwhyH8{9!ag)TvI`Imn=^jzytcJnqE+ZC218S@yHrh`S^iBt znC9ItNMf}ce_56Rl$qoAI1b$mq5P#|f9JaHZNgZZI%0=r?88w99}AhRHzuEdvdo{Z zCr*EDYnqtT418|QoEg{C&m3XB<+j}WE-i3kTx;ivad6@NEl>Y`ukLHxw0>n|ovZYfC?TpZVla=26v3_4~euz9!G_yCm4+=_XyNH!~Z% z>yU}}-H)sXs@!4Ou&$ru#p#@ORVuzdUFoDhA>{@elp&c&lpW5_cx&Z*&0{c6l28sO zkaUl#?TrKfJpjz>0QUtNh6`A3MqI!pmkcfgAf|H^7ZC(et^55dAp_1LxB~#)zDoEV zQSRs%1=#74#vsZ>MlM}=<%Y(qe}xGADkU`F6&4M`#WWgm^HK{?SvgVD5oF!`uZsyr zHH<%rfdQ5%6cjXEyy9X_g3j0xwPT*5KsxY(K>y9IDg3NCz3EtG#xfeQWKL84}%vh9{zTMt< zmXW(Tnl<>m&DZaB$Ef}i{llHvZ0VcPkF~tx zX$r2e6T%629^9MptEZre%i^$wAZ4~MN)d`yl4-aYYRW!N7Wz3V6jBkBberkaY& z6V1`F3F_6DLMR>+v^uaswC_l8Bx*{{`&%e}iKaH08__u$R_~zhyStcY^^0ax4?^qT zNB`o^VQ42s8sVI;x;Ew>7bN~L?^NVjeYeGVPIIpr-dYxK%r=X=Sn-m)Q>+P8OJkor zH!rilzZL@@qx>zij>EUd)l|es`AyBAOisEe3{{upcWWvZr9#Z^Lu3!XI@i2)hz}H7 zBhan!^p0!RJ=OU%EII5bCA!8OuC}vsKt3e6c*B080BWhHU2s0Z{W_(~**tZ1VFVhR zGb$xiCS|+hRkiDs^86^@bJRz={B&h$a#LZfsNk^3%;=XZPl(h*C!voYRI9n7KIcCu zb+}xayudh+CDrc%%#2#z-E>E9$#cMrCOZ56c$Y(x%0M<>hr2d5Bs{mFB#01hloD?7GY;=S(Ao!%4C50~vZ z<0jAD9Y0y!ST8xx>X40R{?}}TSBs(cZfMvYBEpL^2*Bo7g4+B5oh$HmKzV*kftC9Z zEEPny6*vqLDdE$>6o%tJ-j42Q6wfkVXB}Ls#+Xv)B0HV0q;IlIf{;+DFc3=aPQsZdS^3{`E=i_7JN(AJaM0IjOtkt8aZE zEE0J(AJy$sB|n>Vb77!i8Yg;5kIvj%Z?;y(e5g;9@x`yc_2WtRqX$#{-u1p2EXJEd z4&0nh$15*%Jkpw(x3VZ7d~YH(UH>5`H~45=v&%Y?)xe;pN$piavJiUg`Ew+eiD z00apE#B%O8>F2N?uv<2#TR0TskFQ~M+(|lr|Ga3k;adku;H^M~!c&~f(sW!du5NnW z1a8$i{i*7At8yqh49iGHi|N*3_QP&0d4a+6`dfx>3xcu}$90LK_*e9aaBs#lkz2fN z?}2qC#zSlp>vV5;GV^Ex9#U~@=xcWjEW5fT?av04gbm~Wr+))9+m5tnA8&apD3 zHNS1XAKIdSmtE~vOtA;MVUa)??M@m4pgaPse}1VSnAKA(XQRu$9XVs(y*oBkvvsud zcs~N-d5c*>ylZzpCqund?!3M9$t;&ubwd%+>@gX4myB-T4L%O$u4sh?hTyvSD%`t! znsvYL7`(w+k<2+YDWYB<{Kbbq-v>?uUvd*W=-L!1I;7jbUcwkGWAJNy`VDP8ckRfY znnx$;PcaPUZJ{WcZ57TJTQM-2vfnlnhB=O3AzI|p%4F}d;?jQ;SQriLOH;M@3`ail z?9hG3udP=`N$EQiv;MXkTd-SjPE^{|VIYEROShfAad~2)H5WITC#QEyRm$INh>5Bp zTw&7VTajnBAZDS(>j>}H*!Qai>Qc1&94N?sk=?jSCz_AtukFE0@bJUYgGf)kxTspv zFOrZxZM^EDB_9PhR+q;o#UWy_L6Jb>K>DcEHTk2Lr0#(^OR=?Y^Qa`TV|H`@EY!25 zv2`|mbIe%SNF3ZXv-?a`cm1dIyE`<5#D%e0HbSFbO2*2@&xSoVyFrG;I=vO`Wo3SG zZ2brC?A5Mv4u=e;xaFyk>~1xx@Lj)Gd|7-1;uq!fHqYEpT&BeDb`{5+`-&9oUwcoT zIULWbhNkx^o?toquLWa0*ziSvzywpgC$J9fsf>sX(Bg_nWQd-`8*AC?jHzl}y)W5W z=ThqM%RKVOTKTw}r@%En@fEk_cYGS*u+KLVequrkYCSHRl?fG2OgQM z|-;;q8~wTj5|Yfv#Tb+9-Akb1}?a8sKa=i;mt5J>+gn9lwb zNLVM!OiE&)Bn!8sf zsMbmSK;+)32c#9D;zt*eB7}k^4|@1j4KgStKo0=0^J;Wb2{gu%}$Z3g^X@V!q&@Zt#O3yWW8ACC$~!f^RJ8oLm9plftf4Sp=;C-8S7 zQjJ9~j(kMfw+MX}uNGg7JsULd`@yp24x0L*62HMmKou(-fS~}uu9KlfqXQ;=K(fpV zytNlmCmvS3H|Xq`po`{Qi2_RC0Zw!A;>e_DGr9S9sgW=Ut`{R#^w)|AB{1ZEgwF(tp!XCpL4#OuT1iddE-0Zb6>8Ael z{rI)xkR-1%r8HIp*}o!7r>NA0(R1?yS*3Y|7p565r0()vq?Uhj|%-Rux}yNi+|!*PBg_PdZJK=wF4=-I+p1-`s?-6YTwgJ zzsCpOL98DA5yTuM`5PrZ@3~(M8|OU8dA_u2%xgcxUL8dp^GU*X%gx^4)LNeBkWuGT zJq1P4Z_*lrnw!hcmuiE87D~<1R_R6drgE-8zQ(jTGf&P01YqbK96Wn5p#5k#>g_7A zZBdnaeR?K(XK`yhWWlp3ZShRa+=J={j=inyYBAB{+Q`CHPF)V~8Ks$_?X)jzIP>$Z zgPlFE)bk)e%x#KdThlrXOR@F@|5ZRuQh zqAkWL|4PARkR1OzK78F9_ner@CL})@JUH$|S9|4dH)r=2{Su^2%pr4ppT`e&Tusvy zG^6bj!P++HoHayTZ!!Z-lBJPe44Enty`?S3==CGQ{`<1csp?o#o~MC=5dYDtecR?% z3LToo`Jb6M%!b6?oQ-YOB2%vf>y_2y3E!%x+O;nVeQxaFvQ%#|dZuzu-sPyL>!E~* z)JxkOL7wGD?VUpCd;OX+_6b&`8nx{V@s&4zaH`F0bsEqodxK^0T=eC9 z-ksI@j^c-OyI-8^?iZChL>!rpzPz3q{7pHE_>)2IeYs;@NUhyeOu)zWVXC8$BlfUH z3R(*@Z9>XvqogdD3^jgUnw?MRwrPRNVXa0dZqh;-nYyCv@1H6A++JJb-zS4$%h*hw z$N375akTB$-X?pG4^Pc-SeY-rl#i%4sHeDRW3xSe9zcD zCoNTPs~nT}u@rOT89MGvc4D9Kx_jht?+^I{rg7QlKidMxrw{c!T`zXqKB=!bqIMY&Za@0R9|_!% z@IXB9Vu7Pu{&ryHfva|oz&(ft$o&DJ(cm}?1OZQ20kDm`fS>_@<`rONBREf(z5z+u z0rV)>G!cq!(^z` z_mkT@pq*=fTCzyGOU>`iJiH{2=PCSDh~455Nk@D(<|qC`0-5BnZ$mGDU%gzS)zrs6FK69$a?+fhp7hPs=RLkdb|iLn zmQL(Xbn>1Cp)k7+X4L$~Hre*6D%?7eqJW;SJIg%D*Fg~%>Mwj$#wGkc%NNC?@) ziEJU8j3O(WWbgUA&hYtk-}m?D@p%68K9}oykL!Bvk$XYsmbe@*m(^!??8B+PD*>~@ zlg5H9>%q|jSek^cRx-Ogwivy4cZGi1eqw-=Maf?qkg>sORAtsym6UWY2 z4!fSMJy-nWMvYrrWw*+l9qFuN5T%W)^ob%%37;pEKf&Iw#iG~~QmdC*vJ5P5ao*=g5LWm>x)+N!| zv}ipU2sEf@AyP0u0AgFx!zM|w$hi>Zt=;@dV*3H(J~+Q85aEQ{HB|V_$@M=rH&5tm{$k?0RaC+hjkSTne&ua?*yR*lEt}A8Cbs2 z6>fyVSOBA(D@CV3ZUjcmq zfJ6UafyOEPK!yT^LqJ<<(By#<{09K)w4X~?D33z}_z3`YIx)c;sGWI2geb;EdTtK} z@l~jG8^Hnqa6=r30)!jb1dS46k7w^13I_l$rBt~?5^bQCvo+?-c0QK>JP;M+hxfg`!vV7i+0>o%ZqP_=OQb$U< zS2ajpB71ltVu{f)K`vk_0Mt~WV5(xQZ27S6FWw(8u4ChTV%SS`Vy4T88eYCBtoq`y?88h<(d*a|C59mA#>pd7sv78|2^EwA;r zinIWX?I6^0zRXm>Q`P*n3mwd*G&ipd#`yRLb;c1cXjO9m(z@L3FPI zUd&x8zs@?vWYxp=mhC1K;}NxR)q>{yw@n>{MUg$4Mq%E zBn(^3-x*G)J${x>zco@(mNihLG)fJAB>S@a$fz1F7sqLmt-h~`NLau7h4$orM`xys&gKtg(Vm>AyI#i}=~c^8 zktVc!ZY{McZCG0F)do;H1=yvd)0{o}TwCqxHQg@bl_wAI-F7Umnz^>G{Old`&M^^G zyK?_D%y4LqfAH}2vQ{5-&u54xu#$-s&LyYMe2?Uk+Cu7e%KC2&9f9R32RNMPbs>qEk$(q+< z^P2J$2_|V#GEG5dMaF9+Hf(kGGwq$ayg!X)KC;{)@@-R7(3;*Qfm&7#HC04hR`=ST zjUC}k_%1kmf&Sh{k4K<1ZZ;$KeGfUAjM3o|w}DUU@4wkeyqJ9V*~LA+pvqH~rEk1@ zso~SJ@XU{6*~O{Ymdu~WT!`cL6`FhBQ5yO_Kee$MEZ(w%J~AYAg|?GrG9Mq|@2;== zxnG^9UQO)(!o(1ynfA+Y{Z#Mig{f<#nUhm1r^7s=uhf~vc55add&xJOJITITZ_7xO z(`;T0(Hc;{WkDGnRa-w9bRqO^ZM1p!V}{l8K;q!`?a95#Bk0VE_P;!r3PGG+V4hn% z<^kmbK>3Vsf)ig$V*3pd=~ItBoS>MUB0{}(45O#+PM}U;dg6RNY3P;$5h&bK2+QNUrbmJxqiy=TtggJi! zU5U~4x*Whi0HBBy!cHMm;{A&X5F7zOOOP5ps6d4hY|(ZKKxbf8qYyKZ{0M^&C;ppp!9JW;e_x zM~}H3Hxk%YK88MhA^6INW%x_w*uyS?Z{d+xx+RNy1ttqG_}iurzm*G|1Zl=fu{c47 z@4Z?+ypZYir6_Pi!f8JMgqV8P4bLGSWqDHgO*9!~Zq-*uiAs^kvI&;9`S2ubQY|pwgVnZ>vcqRAw>vzZGUR`Mh zO2cg`0f1jN!E(anA_049{#wp3#a~SC z3dqMtX)*tX^-;l~ssy+&RxKh*WB~V~95o^T-~R)u#Gww#xde&Se4x)Ug`fx<pjOGwzphX-o$*)t5?gFZx-dy`4~F#T{1R<9Lv@* z@USuTpt~k%59&CHj$P|*)nDwcl_j& z9!l$m0`eh&UgJL&E$aeIU)M-X2w`0VE1hxnW3R&>B~m#&?oHUixEi2eO;>lC8t|si zSQOr~zr#wYawKx{OnnIY%~CG$APbgDf!X5$^ZV^1VfUa!}*%4+Y2oHRbr9~EHfIfOG|Q1ynv4@9bm`!(7an)>Wxzh)rgLCFAe@wA^oF*IZY3nBrj2& z>rL#5ON;ca1U-$kFQtyZFY~h2ZMr_Pm2PwKHj+$ztr9=Wb-LMOtgh3|GFo4*b2&OcPU%bzOkK3ATV zKk@xCVZHBqdNy)KeHfCe{rp7vXPmH~E&IM#QRGZ(z4qBa&N0rvEHDfls+Zl@rV!~L z=SmnN;Q|$Mj@C+$hYId8=y4EgMR~nW2NAcU~>aoknzjc@8bQz zJqd!7j^t2?o)RcU6$@C10OD@6rXqW*u1WpFUY)=^04VkfG(MOeHDIq4;3@z-f*Kna zf^536H%atJ=&wfx$_KjY$zLI5)G!hgf-A`M0(p86y7UrE1Av+wK?sFNK*G>DA-qk3 zU5AN`ej4!s`c*A>SOEBu4}LG!KaLmJ1yF+JpH6=W0f7tg1)_^(1?~WLeEtOxCFN11 z6a59?qsjR8n8=K#w|cZz&%xNP^Rgm<%%U^~ad3YC<=ipxD8&n*GLfRy&vX3?u_n|K ztZBrV>P7=TBBJgd(qRr_K2XAqCzuC;|B?VSV^KMf3hk{-#<}Z-(cfy{$Y0CAV|c!3 z`LSv@e$2&r_=S#gdItF<DD;;GY7kf{kPpz%3 z>yk+0Gam5@zZbCE3W&|>HlR#+`hlbK!mZrRKDZ2FLyy=!=QqmA1EH6nnQZDxo&M^< ztC4n+~yGtJQCC^jM?-k^P&+&c3^&y(NI z1@$BFF90Y(9T6aM(T9+K2JB@#^qIHX{ z!h(R}MscAEOnB%rMsWoSzmP3jPlUmp09(+xJ%|=2E<&V;6vkuL3I1f+R(hkzyQ-2SB~Y%V6r$PYDGGBLw}wRuiQ~WX48%b0C})%nimP$sMq* zqP_{*ZU!?aCt!fT#KAPiLWYd?=$;Idf!9`x_E-Yt551?(nU%q7>`M@2DP@%QhqBI{ z_s>NVcZ6#8-`0Ilga>Wi|Lg0bi$|n@@l4AGT_3@nrk&dxK{PPxlP!X$0)UT__krBF_8g-0pJ%oap*DszZt1QaSuxz6IsX$*-IVuD0SdR0MtAP zyY&0J?l*3Oc{uWp^9(wh)PnOP#~zi=CGyM=VH7N{6!f1FG^FpWI>>PF&aK zB4W_ms(>d~msk0QwNRA}2lw8=`1PEJCFbUz3GV!#KF$1N>#L<=zR#8R-Fa?66>>*l zk7}-No_^c%T0ef=+dGE2pxk}v?jt{$moERy<8|@P6T4=L9oVBN%sr zH(SG!LBXKb-rIUtwZ~^dYSCBzVN_I*3 zE0r1jUpqgqI`w@0vm-ixm*{u!!2)N^gs4-``scMd-6!(iCcdYE54$E0{|+(%!FaIe z3P9?53qCObDqpc!0ecM-3WO%(gOFp<9I(A-&p#dz9?=0FXi@5aKHk004vdP_wMXRs zBHtXY(uHJa5oL!_=O5qT)t!eFh#XL95MBHw7Ao*G@0clzv1LIw17SivY8aah(EHhyyn z^*(b)fs6B1zsXfi+Y=2)@w2JaV_HAOr^-B?pYuBdP1MVjgo{RY+Z zPjC2MPQWSG{3VwF#eqZyk)Ps_tG#Do?9Cu`wC%M1w!vb*=Kd-5sLecrMpUpo&pD>} zR@KG2VWC@3OV-V!clvJJX#e`H;!l#>-Ae68JyvrXgF}&Dp7HK8C6Q?1(!P|Y=cAC` z=ia(NEay@F-Qm=>gCTJsVyTLyRySau`q!;)OH8*Rv8zk`Tn5mIsX;DfzU7-_`=a_% zMibZj83l2rTid%JE~*@X)>W+GAEYh&+!y7Y@}sFX1I#G7UkNC9FMSK#T)6zjW4o!K zbCMufcFDp8pDr(hp-XSx*B)~FjMi9s^FyX^PX=ce>0D-_3ifsGyS;*>g|8JcE#8Yf zo$nY6{bOPAJuodF`Y^!iTcVjDH-owpQL{u-(V^Yp@C$3&SXo@v;rp-&2Ds_ck<-Ep z?B_NP72U7i^tBj^AMbnpTD_wF+j-0L;j>CB9qB5?bTS|3)(m4nj(fRY4?obZ{E9u#9speLa{C@^13 z!eefPfB05E*{xl`x)4$6NM8_w-k}79Ctwd>wfGBn~JU1iaG5MPVWD<-u8eiYB@s?i(H069HyG;J@kUkX#s*B0b*vnbmju za0>}GkCZoW%4LfBhLy@FPFSj%OmM>Z?>)m|&n^sX32h4G^q{q1UoJ9XOHFUMNL%Mb zyJ|kA#JuOcX#wrIFs&l37vNC06zfmMYe<>@Vp0G74gNiQoSdXX37&VjtVh5! z7uJwuerB)>FLB-zSEjZ3Y+>aOuTZ%_4r?!5kbXSqe@PQcXJO$(7vw`A7v|ps&FV2) zw%>SKswO6oHBO52U}Edl%O`x4K0hw9RDWL&(0cyUMMIGDRLtYq4^Ap}@!)*pY4~ef zWyX#9YokL<`OG0J8m7C?)Q6`ugunGTM66)4dUe}RK#Om)kJ`s8GV*a-vM@4aG!icH z$@Z|waZO|UKx=QN)9>33guk-C8Fh75bj+`u8>QOXC)o~#E;SRm^jh@BRbdpbD#A5 zfZ*T*TlIPzQ7{u871(D0ae~1*+;m`9M#$1Uv;*6{?_6jF+a1jzRsm}VKnl6McG%Qr z;$2^lnQ>{UA!7`_8SB3p#xjJ-f0`+6GbF4hpX|$)PLyEk z*YQw<{MuZmGXtRk{_Ch#s9&psU#nxZYPlapL@)Mv<{Uaw1ywQvC4~M*zzQ(agNP&$ zgdz!U9{^UPfC)nu9SB_n8ju9I3IHouB=&@Wpbc0Z2QVR2gZl@7PjNs#Ak+6@A0B}7 z`VkBUfOkE>OTvVzf_EVE*19PeEv_O3cSI3iluC0Q3`XF;j;5e4vY3|-2Z463^1Dp+ z!0)wzSE8Af39Pnw6>9-I5*r}~#Z%Q-zj1(@K+BIQ? zt2L@Hc+Knt#}U&MQB=5a6ThGOupj0bNKe(&k8hyndGV3c?TgMK-@3iLjhe#TWkx#X zJBY3QBxxhu$|8;$Qc0ag86DeYb!RI*wpe5JN+bWk%8vQ_-kZ1MT)3CgOfAUY5$M5pt@rr@Bdk;&Si{twE_ndU1TwlkhC>HVDNSG)gr-o@s zz0FzjQ^0@QcCF{x{Ilfix;=e9!ZdbjsqaP;wu6Z8l)nkT)#S|kGRvV!Zp$JivtBmV zKo+}4ARkIlO&@SYHXf3CGhE8kxbtBUDbZ?+IBEV!cI`kWWVZHJvF5~4EQeLZ(h;nt zS?FM9$!ncRhE>FLmnP=MTrv6SU;Y9-u$N!(I6V^qXBp$X@s-4R2dW-$91!@AtqcV< z))Q(UGbxg{S-UIQ&0^;fgnZdI#^q7zpk}A_q|7GDx*d8AzX|@@&vZt^88>}k9#R-O z_5BmKnH5!fm|qF(XIIy%&y583LR!w%oROr1wXPllvvLW$a*5y2@8k+sFR6!Zc;v_x z6;z3AOpCen4ij2(^ttwyuNCS}Ted+>o8>>QMZ*&nX)#cd{75t=L`&se;`P_JF%DZ_b76a@FwV`C)B)*-a4*mL)yFZ-* zg@+9;?|sarw_Lb0w2R@7T}Syv>Fi_A)29*MmwH&9SDkQ-U8a+%uavX2adjBTgGLRl zVF_3V((#wlep0v+={{PvfFbcQE&DKNhfkpNIhMjz=C$Qb>e@pe{0FksqgWoNJ#XL3 zs@2Oy7Ct({nBi)GkwFx9Mq5m0=*^<7Q;zb!UzvXYeMg4?*GFd%XU>V+{vD}cg|9)S zO8OYZ!u056D-Mgm9lwiy0zt$oTEiCX;Xc?iN z^*1x}KHnv&-&Y+9)Z_X+1l_tldZXTq(UD6qZ1vuw{~>SxdFwXjDgKGcO)IZ8Xu@=h zdR(Z3zik;l-Z1B zm+GtsZ!-6ZBr=y=>+X5^U{5N00h-GvrKu*{x?>GyHBCohB1z8ZkEoy>WIJ7xsRAD(~nkl5$nk@i_fU z_C)X-WO*BuFAdFgkjgfaLp{(1`Wf0>42SAs1AFl^z|LYs@u^`Zg;;q1nYio+e!3b4 ztY#&E>j1!w!>}A7$QUzZr$H2RECS~k0GSPrlv?L+KG5<8T6!JYO8_hbqLQc^Lc6cw zuM|lVF(Dx77FNs!GJsL0fh@2J0LnBV1?Y!L&*|?E^9Em!Y<{Nzq?8zavxE5 z`Io()9`;QUixSyi78x^&8ZZLZ0YJT1L9m2VAF%w>f~x@V*gkwkOfE!RUxa(Db|H9x zIdoPjq8K{r0cycm02l~KrH7ww5*A}2%XG2j6VSlYYKU zXcHOevW89vMTf}3ml%nkVnU+9?Oa#~QhzU40syYCj)RZtXlPT?k)sW!01^($C0@j1o4<4!pz1;DT^gf!AJ=} z>X9J`pm`w5!j=Gr0>JK#;Y4$R!luSQJ@#eMT(Igi+%5?rR+ttM7^x z0nz(-e90;JqPgWHO?j6m+PYTA)`~)Oe)X|zTCE*kcAW3-dUMc2Pk^C3UWL=tLoSL} z;%>nzep{McWux(NPemaO#=xEe6vs(cQ|9X1n@#0z5*+(gs>XD5*sRZEyALH~8Y;Pc zD;2O`3!S}O5Rxa4iP*)vDC-kGd1bwNz1g%$d$E?3-q(n(YXT2a8s>58ZGBw~=bCLA zj44g41mAS_dYL%~3}<#jx1|rXd7cp9o$%4#T(TV}I}YM@n%u&TI->Spgp%&8UJN+7 zq-vtMPEcp$$#0Q)^FqIhmT0J<+g>5ulgQ$u!iuyz!Z#Y)9;c ze$fUU-7i-=^OgliepT-$EAHHld8(u7zkFY?aZEMUPEPgW)zwl+82d7+P+N1dgp%e$D9yNO@E30501tmOS&EIhZ1>1%5UEeKqLZ=v*r_de7Q*j;}{rNd9P8zPYl8_Ie>hbFu}a`KQb6 z*9F}$-2`G3V&X@hH7T?>^I3_1YVx(lzIj?TMQZW8CZoLUbw;q}l6(FwYbdk$8_NM- zZp!A{baCEFQm1@K|T?#t-J?&1EDZj@w)5mwlf z?J!IBIrF}!jiJ!Q(o|!=U89L{kJm@O$Fh7lwok_I+=4z<*k%p&E{we7aA7RFf>CYx z-L!kzgz_8tvoppjpWyjcEg01v z&t;Lz3O*XAuq#!gWL{EeY_9dNd}Nw?26GI)pPWiuPW*7gN&8J)(PaplvP!yX?@I7;@RZj^Xbdj`JnWsCYHfg$pmNSWKM>wBnoAuayNzmL5 zDw7S>@6FkE{EEr7tx$qn9DXYN=Ptb9)Y`Oz*QDXY+!fd4`C$*jq?>ngGL~ZF6$TZ) z@JxM zw+Qe6K{RE)!v7pLrGiHT{XYd=Am_%`K5iBvZ_{=TQ4-^Hy_D;kSTL@%)VHw6WVK=z z&DOWDPM@O0(nv^s%*b-{()E#We(&1PKXiH@i>jZDRW#Vl}w=5 zb+2)8!A?7E!;ufgRw?o>D=CmA`_LFrPx+?QtB>ZxHF=gLD;%#s zWYOlLottm$aWGo@6MJnwLriFch=!t#1|gA<2_<`9S3O&aP5lTi4-H-%3Br}9M0(n7 z+|<3M9~LYprl*(2#U>$ABuABBGS_3{RWZcVczEqObpoSqOT8VKxW#OewRN=s+K3&e z#DAi6fyyjjzOMKrYPqn{(sC?tu}iX*A(D@1r7kmLM6{qmJaqg;4%ZIO1J^5)uJMX| z+8^R|q%vYSOjDCMUUixk3L7n#1PDnf*;@9xsyjW13oW_+MV(%RE;o?uPtGyPYy5n@ zF6C!u7{Z(HOr-fkvlGW0jkWU#d)XgOZVs3W-n>hpojK<#@;N9!bpJ0UB?x>;;G6i5 z`r=$%ASl{6OKyH7`Y-k;2Eyu4JWT`eGyoWH4#5XxbrT{b8zmn01^}009y>kBJdw7EI8ST z-H$oc$lL6$G+A23-F67VuW&U|Vv`Rl`O?u|98;S#OTIu`rZfQeA-T|ve^HT?pt0b- z{k39IB547ako)8zB|N$Z`n@-{po;cou$0OY)ve#FABsM#@+A>ZZoZ_WP+ZyO5L4<} zc@Y=3oAz+xm?ruWk3;Rjh9B=!@73+km(uv>e|q8xU#h1SubmEb`P!KvFpyO8Vt6x9 zo*jPEa!2CfXsL5)sxF~;8r6w6nM9~>L(0DTo0Lq9`Nk*h2?VxTyb+B& zv9k1xq3w}U!Y?s;ehS$pUv8^st#!F&nk`$UyS<<-VeKQC!TE0TzV|{E=5KQWrAV%t zlu|$G0+Gl$$NHxD4JtmVhijoiP!7INu+8M!M(bE?b7?$MH(qro&Ud*gs(QP(A{|Yp zYj~Wwiyq59Z;Nla5$pQklcx6iaKZq^#NiQDz>}!f_%^8+P8XK+xGLC|d8BGL*@rEH ze3OKV8UH(HkqNIf0%l?gM_D<1?sDHt%yj!&}b-bbAHEh z&`DHV!if_rgpiMU=*O5EcNv$kL`=jZUzH2u-v$3Xv?~$pejwba&41J;YZ^GTKOO1N zKl9Bupgzm6FTXoz`BQ7BdUsvYV8r-J>jU!n+EiEgq|{bDZD~(ei)}_X)Xa9R_2J0Z zoq?~~Pp`BNc!yDiazTxVGsOC#0!3NkeGEn7e7cPITvKVE{T;olBHl%XrFf(%#$3Z0 zYa4m;_RVvjGW;p*H*)?7;!o1m}jEvvOZii2O9?u?HWDs0VpU)1$w@_l#8if`;%i1!& zv`AZEES+Q~k$kJHeS1!Wk*wphOuQ^yNBP^IJ8cK-PvoY(CRh2b3KpL#bH#~;kzEq> zv?^_TUcFGbUGUJe$;NKLLyx66@jyH587GYb#FwIGN9ZAWZM;s&eBAG2(y!Xs4zC-< zYRg@gw5sD@9C2)F$j7bq63Gif>wZhde9gg|>%X`t@#*_ib6fmboCgW%a_(Kry2+`T zAPV*DypmQP+koQ9o|b2uTBoeGi9dgKOexAAem^KbF)A-%vfmVAUNv|&_I=>+gNBSv ze8rRXPfMny-3}v1B=^YHwMrKWkDyYdOvYa)Oyl_7Gdz=}UO z?EomEgkT-{X~1dow__X%h>tPO(DLi+fM!gi6L_wGa+7E+3r+a{hi2#_I}7?+tJUTf zCWq66E{D_TUF1;0mt7AQDeEs)y6r=$d`1#=*FQdzIK;T6587~rdM`_Ru`dlP%UDSyZXUs3GlG%NexU{b%o>2{4;RAOG@t-TXf^d%9i8`h3H zi`!i5;lS%5-spKfuL>vN-K|^K6pjZ!K-5N8qG|IOjA!R@oN#;d6dI*oaQ|$%kPUf< zeb_q9!u2+L^M=frb4s~m>o0kZ64!zv&XqfxL21kVgFS3e+;8bPOMafjt(URicvED( zBv{k`#8oKr`sauUPjzdMWh|%Tt(6NF&o#CKs!~$Rcy^9sb2X)j_Z|!RKhics$4D!5@j>n)Ti4q(Q}p%+lh7X`IqzicFTqy}ovz^2wj8!;&tSnP7Yx?i;uoBzp@EMV7=*NLJ8EIXeQxwTtkL4BE32ES*?}o`0qtCf_f7-^=_^HOJimMgzL%}u9d&O zI?v<>C)4OYU`cK`qFvn(TA#fCdT&|&=~~~2HRN~Jh*0$h54M3w@y~O+cMOXksV}e) zK$WcnLu8&Zx{u{wXV0V6TOqAY)BcfVzeAYypjiCo;}357P(I$?Cl3;M41sm^*FuS)OW3Dn7WmG0eHtvMO6({C=X+okBh>o5_4TxAxk4K9`TllNN7` zlYf+DYCbm@nR=05l;Hekf1|qYNTMtz!rqF5=^!fG&`TOp^P%u`$GTsEqGoA;j}%sS zydIUaJHp_lAoB0=#Xzv{<1yFru)hQoPzoQN^LTF2;%&jt#zf}Kr51vmxqToy0U*Vj z!9vn3WZ`UnGaw=UZ{h54Kmo4pfp8{tWjmO_HNsk?ceUVg#EovSY%kgX1}fK`Cs{-S z8iK%oOAYbekHnu-MV8VXjeUdFy7(J1hRk z@SDqbT4jN zl#Qv%^WdiNn20jHC0m!S36BPnqQxmOgWyo5_e7iT6U9a64)PS#BUP9#SQ_E~DQe15vM(m1n1l0iGyuZ) zGX2v9k&O8#S-(o|lg~_xG4h6xQAh0`3YAgxyrFPBBByl1U13=D`R=Tg6?(Ai;v;oO zRsZ`=RI2bKo=M+UWRvkbeU+Uv7zysGg(_6Bl8E8@38@haV>EpD zhnAJxqF>%MJ*QXhG1V{?0 z@4tt{1>~Rot1Tk>5dOpjM%2H$HE=;dXe7+e0EEaTfz1GbWGcwc3!JVKF&F=m$i@DV z$j>Vze%-*7qPx5+Y3rNdGi2@;yvkyaKSr0Z?2_AKXTo8jyS+ zg4+OqH>yFnFd-l$5Ah$=r07mce+A)jae-3k#tYJXEyW1SEHI!VOn$%^i8lF7gNXp* z`ae^_li!k5VnGmVMB9PDLG&8P!v#uuV#7M^h{+)t;OG1laKcu>e*(a}Q*a+@m26iF{G@Lka834vAM4E&M5QV9S0iEi+(WPA&rUMq& zWAF+dERc{afZMP|TRp)cmqY~u27?&@VBlR+!M;nAtRiD4jcNg@AOSxCzj$9MMBYMO=xR7 z((??=_Gr)Z|ED>Q%ALl?Orq2&aDD;H;QLiL<$BV%_no|cvvYpV=$l+D&63+^ekquK z$mB)*^p%emvG32sdC5x28R`!cFAWRixdK-p&eLp~&B4UsK}h4uM=@!ErWLKTYHqXao2qI!ql<72C*dJt z<0m2R1IsU|G#D`=mzNgl%mv)z@E!L^J6ThFuS~rl3kW8%g564(iyl^-If*WuQjdaY zu4>1Sz4;jfRhHbypuE@mX2jQ0(ZE6Ziy7fo$Yq81OKzMV`FK*wpOf0%$-d0Gzr-oY zCe?{!IuLd7|Dn`rC>wxTht0@1+02!ena0zH85a3{uGV`GQ99-MzL! zPPXwaop)N64lS+(v*L^{%x;|$>`tZ@25K{fW%_%+bfB%(-1KSg$eVsbcF-ucU8Nj>9W4eMXukn7l zHxG;~h}|yypu?B$9jX3F!RXGfO82syWEoEt^{r$9#`=midh`o^2bz4y}>2b zCV}LO!a6sJAlL{a2tEcIf(lTB_6$ehcmTlIXowDwJUxHz?)?rh2GLaqaXOGZ9c8Te z|MBzzIl`uE^KDx_vHDL2EqZx;-BKxS^c1XNIwc(xwLjA)P-r0}sG z?FNq%7{Y=x_FrXOkV#~fabxzjofQ2Dg^yBv^l9sxu(jU*{`q~R%4PaJHl5g`()PoQ5wNF!+OT5YjfryTLfb`>Z}X6QVhfcZz6s&eQYK(ZWrDB zD{qJj&@6gBB_b~HE`9+Z9X_JxO=!`Xv~j!H3fv$kz*uzDor?+(phPqQx&rJc==LY? z0eJ&J_1nQR$DzT5Xo9!Te+^i4?ttF_;9A#kMKF;O-}CPk17>%=G_nza<38julHsl51L}I7 zHb72*&4djBQQ5FlI?(rK5ljRCW2YxnM5gZ>VaQGVZ8sAG)ih8hufMFpw6Jvv2(T-G zS!@`A4-!;kKvZNvmMDg&Gh#JD{I%qfMc3TM?Wz zOb85!8Zkxxq=t-xZvcRjvJeevkSSScLxKeO5dbCgf$wa*Ets?_3s~=u^B8zgVH@RX zK4+iWA#Mr%4IrF_^RzcRe1mJZun&yFO~EC8wb# zsNuSsl%N*672iD(%5E_^{aRBcE&j;H%Vw)#0K3S0#Y(Fp63@{4 zE7><^?^*^E&Jx?*ea*opu@aMrc}T~knrmVQ9mn(~?w@%`9H6A>vg7%PZ>s*GZ?uDl zJmapHirOs^&zR|&Df;m##yZ8kCKIPuL88PJ22&XYOwGx({?5Sz;d0k&`!R{NJsPO^ z)24Kx!@r;p3OwcIkK}z`1xX0hY0YI6(1kByw=2E&EOKtA`tZ_o{aMa)_AYOEhs}(@ zJi6Cn&>v1gj^2XHDxtGf_%jO2BrynO>w%SJ_`Oz~NN4)OFJMrgUmJ z`0#OQc%WVhmk#K*!t>j!7V5?dILz(%SizuablLIf5fj|OiUJ3y4M|c##ze0_;p%4bkKDA zuy)~5u8@9y?*&C$I!wJ}o#Ogb{=)CrNo%Q|Tok*8b0?b;HHtX4az8QXx8|M+>~C52 z2K=rg>)yIL)A?L&lc3n!v7eE?)SQtI>h3AY!0;w0fL1@QbYrYQ*wNYcd-JZESou?u z0SnT)z!!qOCnO$>re{e7=eDt)`js5zOs9( zx8nP1w|gcz)vl$gs4nKEcdMir;0j&Tot1T=tqATL`1)>b^T($>9dXC&W}%~U?qkr^ z)2>5Lvm)qmg~Isp%hNf#3%!#x0ui6FS~4#EAh~WdQ^_`@*r?2|iMdwjDJ*2~ z{mHLF7(<}&0j6xj=o9<{2d%f|q_u7idpFfle+PSC=hwPe?^zqCADmk3{N?54T}Tm3 z0RSUi!wf^VuG&=k+Ib($@CZEvf<~gkT+V4^Vmh`PCWHsf@Hq;!vLgU90Kg}raQLy1 z#iKs>{~JJqpo{brN{x1ZMdSkV3NwrY`tsj|l{*XE{$zo0fED0{hv5(b{B)nO!@nKA{|Te5y|78lDsX14un z-D_Zl|1Ro-XeEexJahywqNoqDW08{=P#{^sssIS@78N|(i}W=XvNVwD(hX8-@Fhpl zu|Ocj4c*_X4~PW-@Zl;PAykQ7+m=^$U+mCw@6LJqM=M)6onpWU4K-^>-JuE+nqz!Tt z{L(oAKCCAA1pv7xYaH<(L*9a4JQ2Mj&<;YRmywGc+~QrEk6%2&s+H$e?ImE>ba&!HW9)=q64m7b(Kd6LAdQ`dI4vKe4c`j0eCnTnT9L&hzA7P*FquFL+0*&7B?e;+y~Y?w2QbmO(iCn{Dvy zIez^q+3Q2HIo90ZzOy}LVjB-r653N?GVv01%%(GN9Z#3l_w1~jbp8zM_u2Z!nHv5X z%kL+*GYi3^ox6%bt|__@8YXx$02p^1ejC!p1e>+zk_J2BpP?YZ@IQniIF1Ci zE+!Wu;zC>d$K&k3rbX1o>&f&XToaot)#4fM;2|CGf} zTO3frOu)nHhwV+p+W5J3IIIp=?G9NjqxeTo?iyU{E9SKn-$Z(}ZrTzMM)Z3)#cCe8 zKU%2AfNCijhe53(SLI?Eo}1`qDxEIxVlWo0uH!U+5DBjR@dAVQ^3N})Gk3y!8N0Xx zIBx4oslFNU^Y!;o(WiWRd$5ONJBkwb%22@Ic>JXPRjeajtF>oA6UiJ`xi6GO(>#AF z{gY21*5yOjvmR;)zo2xiM|o@&X$WtxSZt1G>)aPd3$uC`WP6)LnQvWh)oTfM)?*)`t2S}qawupHy;&b6Sl zxdZ{57p2)h+EgCq)NlUUc-pc?7qUmS$s`(jP08rvSsNx5! zCI`x78khk9(XpBVwnL6xg)E5?ejEH$0{#I2R&*P?3rVnvBMQ^U-f z@bK`?>n#JC$OT1^TE#y_nnYkLpZCQ>WYdbFL_svI{qMcp9a{?2Nb;cGh=l7RgO+zy z8iG6!7I#gCWD@VU13141COI@f@rT3+^*^oZW^E#|X^cnH?=84agji{Sdf4H}#6AXroVsQ<+#z<{)_(%}`6WF7oO zVAPwmm3V!|-DoFqcX)g=P1kX+)O60zvA2}Xfa2ZT{HNVH#Mr z6oD39Gc;}ZRU>Irc-f$N%4$pNW3?uU#VqCf8v95#7svfu z+BX&OIuE(H@Z;OL0Tdt%FunoK5-mO*!BvH@ zAj5Bp30diyf(a1|c1+an3Mj~Ddqq6>0|5N1CJr0HM?Qsx4vb$o_|EVNO&oSus=D?h zFI>FJ8D5TY1b;^6#`(&-;z|Hk;uy_rb?D}$4vmKv7767MVWf&`cXobRgDmlGUnR-mIlKa99Q%Q<$iDFJ;d4f=Ym0ql_y1?Rcn!FfCx4C|J z`f+-PY1?mxKjsm)1Tr@jSzQvPVFzAMRX^Cx#k&s4QoP_v&tV|!$#@yVgF9&YQmlRe z13y|kT3y;f%z*OSWp#@^Xt zUjFaYhrEN)uQfF;Th?fsRLJUQO&^(a8oh98-E)oz-Eo7kbhPc6lIV?h-GWWNi0aU$ z8Yr>-#iRVZB4e;2K>U%vl)$#rIw`IIqhD`tgO<23tHdRhCsHrV8yfBqaH(hHn>=s7 zQ++XFH-yZ?5o^_S+l@A+BEAhrGpI~YTBwgvmG;(Kt;O_Uanf(oje`#=ObX^yYIQVg zH;wQ5r?#`fG;`8PjH=vE*>~At**g0-IAYB{WN*x;&WF~nmLH5*2aO)>+{~R?^@*zy ze)-%~uF93OSOt^shgsncHe}+~qwr_N$?x7c!AQawA%iD^KGi%Q87|)(_w~x%)?6-j zk>%D<+>bP0!!BeW-N`P$e8qECZz^!qN?O>ma;9TEvhVI_Ob^#;TM{lq69+X{?Xmmr zL^S)Oi8cjRiKSn1T+BvVX==*i^+;y%h%mDrIB>~SWq6N5(H~G-&rHZKqCN)K#_rS8yn~K_*1V@b8cui1 ziQk+iuXUWB?%8m0hfn5$bZlIhu3LfF*upo&v{}u0% zv6{|=y1!C*qs4m-ut4y<2ghF>PzwM;<2^nbCW{EDh7LYzBNslR%09Uv&C23Evz-;1DkLfPhBh`_K(eYWC0F-uY7GT3%lss+w}N zVT66Tt^Ofi;VpUem2ts#aoL{~xU&y7G#n#(-?-lZo?RUKRn^t`LF%iw%#USAMROV$ zTpxdWzui+MEe212K)?huZTGvb5+o>0e`24TBwcvzbBs}cd;2428xSCF|GS=n_*M3y z0?iLCx)oeE*9S^+Zkp4OAA6^=r2iT!$!Sl-4%4wOJcv~HKG1ntZ@AfTbzAKa;g3V=l zkP*sk5;kPKu^4~CFM$6<64!UvJ>p8x>)JW4qmhSleD|z!2%sc;+E-1PTx|Gr=_NnY zcJcOVGmx=AsJy$|bxlowo#XA7Mv0Tu_iydu2Xi3lf-Q!YFZ#w-1y;%Xr9U0MH2!q9_I;99w|!3s2FaVe?XdAGXfb)u z!6d_egUXEAUK?}62+K`~e7{@&i2c?3{q3)O5^-h*iijJ?**ehM4HZ2 z+&`3pE^>36J|xzG9J@cJYl6K?@JeFJ<_{|={qV&nb>X8)PLT&90Q@9R2S(Mc*t8mJK!=M7%g?B zK>xVV14{pNDXzmL)j+uQIKWdUSjqs$Vn5Y~iuQ}vshJ(;JUl#B%!$RrCe2U{7LxY9 zKl~1EO8~nrflIvkdXhEe`a-dBwz^43keEOFjofAyL{L?tbKNuLa7_sQZ3=oac zA$vf8He`^tC=QxaR76#>7a&B^8Y98KX)BQuE7Fz^x4Hpl_&6vJ01v-`KaZk9qY^^@ zkif#hMaOVM*-u^|R|G>KR0o3c0B{XM+*1~C)sS{(LA?9#_4=P^>p`F>0OC^Kg(XZ> zN_u47L}v^1zw81oC=kNo5A6Y`AshSy0PbZ^*p8C!K|~-r+&r-40-PNOkp5vZhoIrW zX$s{yWqOFegNk3roeMM|HsC4%vMdGMEEj~CLdrn4ia?Xl1F8W)-ns-&Q^b}=ah}5z zfqfFaTfp-bFVwLj7t8HTM%*;y3HDrPfJ}0I)^PM{iP9Ok6hN|}V8eiy(|`w{w+6%r z4K~n#M1adAia3;TqX&36xSgO~0B5nbNWc^7tL2`50bAF3pdNmqbIr^sXeR)I#)0T3 z1jT13xCNMz=X`b~FY2E_c*N+?*(#uVfU_=&2T#`6#-V`Qih{2=18xDF-9lv*RR(=p z2_6D~SW(6WnR}GMKh!3GmJD4FDy}wCS@+)vMu1O&HWZ42Y5`EyvRHtk+;CW=E$FfH zK;$5%sK}W`_YEit0B=Z#2BFCOVFsWDgP;Wf@UI3SxCSzq)eB?LfcKy*03y^FM;wb4 zsUleadhfkGa(n>|J8~}up~v~qo4gSy41frlBn-jCzY7XiUfb6!gu{rT6u1w-O#nEk zi5m8FNsIM4nUTXMwS*AY3pn@ezlxt~IAvHEX zOC*%tN84$1eO}TC9(@bz(y}gAlUdiC4Z3eP%_9fH{*gH2TFMc%_iN64;ePcU`n13m zqXog69#x?;Nea!c>-?LC4FofxlQAShx?wD|AicH zYJNXh`OVT8=ePb=&uEf^u4q+44Uvual~I0}z2}=ia{DoLct+2>+dBp}hTpEuOiLZk z6+HI2Th<**%k*2{I*OT0FoXSOG>x3^VsqVrL9rw>PZBvr)%WUBou;RVH65&v$@r5} z2!!QVlvcBx?;qTY#LPVTO^UnjDfZ%+=;x#P7t6sGhN}aTZ6a+}A2;888 z8%81(rnbmE&G~LK>%)yu5GF7)etBa+p!lL6?mm=hV9c2%=Ql;t#c9=FdbbqNgf~eu;-p5U{f>5eSCm6Y3ss?h?NTbm7zP5KIbA>f)_y0> zvb54&Z*(Ck9eY}IMWNY@FcIgs2Vzljg@&dqE4Ovu*S5EdnpDB|d3~nYX&-f{YL(-LS|*1j>u+7Ml+iBR zhY|ZeBqzK}A&3RyO&wkL>7>4k6_V`zhHK&FR5$y>-M)E~$91g4+L`Q2#U=$2PU>wb zDPJ||+?Oq6w(BO#lrY~8|Wv&&%9XU(>3?}%nW8H|;WjC4ooXp?a^y}F6 zehzqhy!vkTOa5JXeuNOi+9vZfL0R6f@$@5@w=jbp!M8pa1;zcG-n<^@Z2g}2Gh6ZI zq|ACAuG$DI2_Ca#QInwpr(l&z+RMMW4=n;)an_j&jiEdw#AUThTn~COc5Ee!4)rUX zZa$`m=+ZAI4PZlT?L)>mWEbbCFWdRHhTD}~pDu+#mc36^9<{wc7OcN;WV7>@Wu>ST z#&DW;m(<7Vt&`!d*0fK(so@GDTu^sKOeQ;*}At z>8_bSDmQ8)8Hw4odZ3|I`5+x2@E0_cw9)67*rx zsU)3e{o+rPll5DMv9S=_rhq0+TK<|RStVbZrYr^-_B54rJTXLvKhUoC61f*N>Rqc> zBpm0Enr!3joN?lxOj}7{q+mDEy(%TYZtfo;Zb~0EKrQ0Z8DDYd^yPHCj~eW^ zO_2P%j?%<;cLZLq*DVPTZdOxYA(t6`cs>zg$3@p_(4ftmdS z<6c(gs20+;`-OJvkKMCXm=(wPPFbbY_KO3yZ&q08*3NuCaOGxvSOp6|wqCkZ%caCB zm~eVeYF#Ne;&i)eB~NbRnd0#*?q*k*TwEhocKy78(iv2tS97Z^t{S=6XkB+lxlTU7OV13JCh#mv4{_S$uCQ z0?Dxt2=o^q{*S=3dv>hi|h zJ%sUBGh7{|M#1n9ix2nf?Sm<@p?-QVoj-hCKE7fkL^2hB81JfmaN=FXI@30+KVN?@ zTQfeEM)7U2q|{_fYGEl3mqodhEY3hcj_UL zN@>;0RfOOK>BF00B!P9YL$rxyf&DRo1ZD9*0(DJZaaAu2c$;4CELiR5BerNwbANnl zu(C?Wn(?L6B5YaXcQq~5oqmpkuuuoLqMc&x+%JZ%ziM5*#X5)Q-(FgbhV$&4w{OWP3`#?NnZ>M5pM0r zsf}PF17YzR@jC3sWe7k*p# zw{yI*lH3+;drm27jyln=f*!pl<%E+@{<5FO#dHq~1+zw0?^8H&IA^+#rq)?AnE z_gi&2M7-2i6}rZaippo9l-WjIKvVT%Fg-D$r`@ z`d)5M{JyrDK}ChkNm(J(sQVEmi;B^`v9AUjOYdO(pG%DjG>9WMrYI#|Vy~#0!D5($y`#i6W(18nVN4?KWkbQWIS_K7)Wlu&6hkA za6jwu^B0f8o$3mI=uC@dRzBHftz@!)5cP-d=A8w&8{BlcH6%8shIUj~%T|SFvB!90 zfq`bN#I!;2-lL+Ay6O)3rdzJz%y>GoLU6;YZnsF3aF0u9XB=V2PM1Z!9ovFz6Vq)h zae04}&p6+KJFbv^@OppT`I(P1KAx7JkgRWuEmyI8+Bbd2;I?=Te>&^Wz9y=fK)YwL z`G^k^Q%5n)>>!5C;YH03S?+6;t+t%{>kIQ@GqUSOeUKT6k@t&^Z}Xe-T z;I7o>W)^61v&4ylbz{Z;T>4&_r$=cizrkASjARAC?_>}X{S$Y%s*{icVV6NTg2{pjN^*Mc zk~{-jz`gS=0B8fx43D*76$OCTrV;tD$b+KG6q(*gYi12tc#+z05P$`3qm%}d3jqFX z4q6O-1XlSa4RBC<39bSli0=_-LQq78Fkf)qxdJW&AinzIGGIclgI%QSln$2=Tm?8g zMm+~lQ_-$CQU)dC=kb=Gkz3sqR0BMe6s_ps`$ud07SscPz@o){jtK=jDLiWk^!`n7 z8Q@F?K>BJR6(Gd_ha(3naax=~jrbvW|8uK2l8tcIlJjP6IS~UcEf@!I<1)y(^5Xo% z$9G}hfTn|cSE{ioiO$B)0cZdK>ZA_^p?%>=BH-&&gR20DY7tx_2rACYOVi|CA<#vh zXx%kPS%r4`hyi5*5G+rK)gdg%OocBT4#{qTUSK;{x`GJJX9k&Xpu+$P_jL3zp}=+n zkLUv;PXed`0AA1siGqTlGH^EmkW&#|FZ_c5o;uVOT(w>VX^PLtN$KDp0B5a6bsHg2 z)tuc!8|~pAUxI`K1~E7nQF%&Qc=d*LK%36H4#*;6XZmEcn?7RB13Vk$uoAQhXvj~% zBLLtLV|di?x=kEql&eKn8=xUgfLj3Ywl*RURCNCTL+^lgH4_F!0nSFqMKD76@_g-( zbSb2&201-}SBBWxm-qwv1_0qtN#F=!0nR6e6wt|0U(n{N^U3v37QRAI7T_$(?y@Ce zFeWPCr?&ynNuUFMBBKjkLLdxq)G?uW$lmhxDGBRCT>jRhaL3UJnPQ*ad|6{W*<0apReu3CeuVN0NFIJgRc__~BO20>BYl^Ot< zAq`vxK)h(c1hhY7D5iGvpB`4=9sAEm7Kr+OcBD8D7n^E>|`i?Onzkuy!iQa0`vj&S?Ao-?Ug*yHWX;Y;7dnfHW`8c10YC_akMZ|DJf;CCz-VW zssZd%=w*)xlm$S(8ztNjfuqlY0X_>;mIpNVug?Pf-OwShsz9FtAau#_8ZlXs3g^>M z4r63kaec5|qV@@pMiD($$wB1+XEVn`AF2yMQ7wo{!3W3(_WS>T-LPX&qsAlrBeei%Wh3FQK>YIp={xdd(jz&(%f{ZUBBNu>va_}SY^6N!M&yx^^&x1>=Fx~F8)%CX=mXR{A*qgM zR5UyAL;&P4zEMN^^`kw>(Np;em{D8!&(p@nu%D+O+-X=nh)XtP>1 z7&wKX1^|RjHI^y_d1gGzkakx6H0WP|Gi5OHQ@l_67BBeMrvqykdTadwiUJ_Jg&JO& zjVX-M(Yp+TE#*ALO8hWx7%CdbjWsYdJ-~wj;P=-s`JuqAK5EqTAFuiXGg3?zWDZ21 z*{5HTiOaXoXBqhPXS*{x-wJ91s}^C2qGG#sYxtF9fnM4Iq)^ln`_Ibb1D*ze$Xvp$ z!$iqCj0d0*Xjun->i{zmHSt!s!FS{bg#i$xJou!TFc62tu(RH-e-*f0d?!W^2Ov_M zwSyIuMdE**UDN|E>d-g9cmrJ`DcCZCIr*D7w+dE%YF~eM|6OY)=@19vr zFcyi`y4!n~q>9~{-CfDYw6b@y2QjV=cHEDjOl7(^T>SWgm7+tf<6YbN(XK2ax~SQ4 zye~dunc{QPp?7ZIbrziwe6jf0Mw`NtTw$!6Uy7{Zh66flM zyJyg?J~QVoX5nOkKzT2(mRvd~!BJmHFB__H_wA&NwbnImn)XRcI52mrC*&5{PyE#%P5d8-t1QQIPX% z?M{w~B)fe9lM6kj>RzwyA+QhSn`uoSte>%qVkzUmBLB$z%uM5BrM;3^{lvkEKY88| z8eBbp&yq4->SdA7qYzu1DJ+;*K%~Oeg?auL5~cc=1aM1a`=yyE=-h(5?0W`(Y(RUi z(-8Gyz~1Q$$Jd`o%lp~V2w`Vhntvg8Gu{%MS$AS^Z2Q@K;PxcL{3}o&ebh4^vken> z_-q=VBjL^WLfw}$-i~5zZP}JU_WeZM?Nl_w!27~y>1O2iQ&r+qPZVI>V!?Hjr1&`|kB+gJIF7c7%-{KD ziw^I3;f=W*-NRJ+PVWCjcCbrm{zl~U)W9WbiM;GhqxL|@-Nl;M$&4pE{OfBL$7O0K z<*9B{udfSN(6}u3CDNcy;8(WKY+2qo*+J$9UnN+P)tJ2j7Cp%e{12GKe**#HI3;yx=yneU0Fk zKiv>Lzxa;&&Qi~V!_?iSo{OUx(9u1k2p^*&_gOjrQ@FglxTI=z4`rWsu(EXUCTwsM zGAVv~)%elnu?@STysV>ric|9+8+KKO%u+G8*1saWoW@+kdJ8K#bXQGBLS7v$?k#Sf z#)X%QuV)QeV&8l{x(JATcat)f@udoN5icQws*atiyh@$p}r zF0fy~gFFFC@_d)h_9T7`ftrBJ#4~_5?g&;*0QkLK{EG zffi7J$0a&Npe^_V68~Lld(@R{G)QsQcwvoE*4g53fA-RCVGX{)oyTWx`5a7TGs%xt z{f#Q}P3MbOuhYaWWE-&Fv`aAYU2vMh)jNt5iEVnv53Bzr!R!W8Gtg-kvx&A?JH%0| zp=(%t^k?{Pw%o|_R>k5_(S7H3GHDguJBr{D|A|IY0%sqyYWfuHQj)SGh9zf7+8W^Xpq;lsQU zmWNLe@2IFYjNsrmDaH=h!DFSg6{7vOD?a++Z(h&n;~_4@ zi?6i5?WQ5u>L#2O$KGB2R~c~&^!P~dI|)=GM{2Ocp|(w6JUtVhML~B1z)>!f4@>Z< zplRUqQ5PV+8o@09gm?j_Bqqxa*sTA176RfkS~5JRy&^>#RB~s=CSZoX3TgmA+-kxG z38ldi2|mva1kUr*&;=g6*Jqi}L1-}6ws?8+)CvQGwe}CT>T>di73pQ}0z=*5g3$EY*bBD?)4dPgHJ4zQ|4Tv4$r^>GOkp;n@54W8)fB1@Frc zm-F4c5$2NLC&4gb<-1@m%p^CZ8#^fMo;jR3^XzWGP@vM~s2S(UZ(hnQX$x|phk4lC z(OQ%;uepRqIas|mz0?nGW^?x)tV>2&JJg7`_M7`0Tz_DHW#91E>sv~n422JUc4@4u z^J}QbTMEeD&Es@?=qbQ%24Cx(=T#eEyMcXpJGX2Z_j4wJ`gn1M-|}4#$FGfd_u@(q z*5X$_ul(qw_eM0EB;1DNiQg^qd@dA+adoltesJVYW79V){UWNcQTz-3g(N4*c+Isk zl%?segIzbH;RunOch+yhwOIsq^S@Pko7V8pE~&@IO>1PH3_oX>eCn^ANI~xvpBF|Y zK<%-?a7dG~-fpp`a`pVd8&tWN#592o~J!?xCwST@GX2;-hx z47*(Xy0ks9-|k)(O*;-4GUwVE!d>)= z*d_7bUDL-p`q{81vQ<0V<@KtG!G5x>&#UI`q7`ckHF4a~vlO zjXJtg!A!XcABHukW2~_*_RhH4`U)S9O_<^Ao^Wg>R6IMqYjE4)-WWTi{K+(;a98o* zlZaEa)fB-&9_{WZ;ilNvf0%(;dxAdYANdI8M#D_?-R=NFiK0I1~- zstc~>;R06qGcdIP;N7^mE2!BkTVGUq@K?1!8-<>|fRBabWFgXD5?zA8fZD}S^ZjE9 zJI4}P=kY|RQH(L*`!oFmVE$YBnPAO@;=w3}E zC;4GtF6ZF=eCdcPr4e!%8SS4Wu~1YD|GJW7^Sm*4sLkn@&h?5XuP{cT908P-P};8y z1WXNozCb;%Ia9Mnr?+Nca@(#he3XSgwNH9l8|MVsNG{e)K94Pt-d zoKT`0*KmVn{!C0ZwMF65z_^9uh?YXah1_SfN4X{%)6>*G=Lq1q*!g!#e9Y-;*$>h# ztZO_FR{Bt2R=lRBT+2MtKU9{sr&~*La;o&YKo@r~m00ZJ5&z5NCe`2{geKm+-}t_l z`SS}r;Qky`z4@j;=S`VqFudwse)n=4#Vi?Bzt~Eng87pd;}6$wVvoY!dYD-#M&0+! zyvqU8l36)oUfD}Js-`aFCwM-%9_0Vy7Kz)<3#@H5PFqt}aeajTEO`i@Qi2?v*z)Z9 zRc;&7!dmmVlBYLx({~*fZr2EW`89T+RXLh5SXpz={*KyJrI^z9Q3U%c%-1ZkFt-$EF%W|!T zlEYtwxbM$J=bEI1Bx(u>1?seqr;L4icx6=@cm9SoOwGNw@Zs*Jx-BeCjvwLv`H3gd z`$Dm(r=7NPQIaXSOS+qEaw2ul#pGK8AqDa!C&@TpqV$Mho@8s zpUn+;xep=9KU(@OA3_Zl5aiWRwr_Br0c_mo;ubK0peLm#m}me9cn_fn1VxB{fU~#h zk1UH8mH7Yh+_(eE0-UMo2wq(XgP;;{T16}hGiC$OtzgFkGeB_Lz~ zN3`651^xkmuvo*YKMN>=vPhgM$x^{hfHR8(&_TkD34yiiT-*3hqfkL2qs#l}`+y1? zNlHg98c20FTKBmIRv0AybGjLcQ46`GaLLQqiG*@R-uVV|@YmnLZ2a_;>eQiMlgY_# zMui?fuCTSeH5Ga13y$fpS4`{HOEMSzX{R1P{>)^SP8(5ORhn?+r!p*=zLCps5X+4E z+u{BJe7TDvg!bZC?}Ltht?h+lr|l5&9zQ`lMzZwz;NfwMLs|IBnrCgNH~HpBiL9pS z<%UOe*^ecQF8wMJrMG{@p!lBZ_EK=OIdR@Z+D`4Ck`bGUuzOmpjQQ^jaz#5!hJrGb zCX)#`FwDO?whg?AvUg&DY40bne^N;0aaMbU|MCvU1&?QBmtafNlCBDMzsqLc+ z#~%i9;j?ybGR54>DV49VI5Mv^T-(5L z;uk=|+5d`0Q4~8yh-ey?3{Ub&x4SP-=#|A?Oldn0N zs!t=i;$*4agP0p?hmYN4zn7Aklod4JdQ2jgsr|`zP{8)L)IK{+w#FBO5+Q=Zy%Bnz zYqy8-W3bb^jtLMxiek?l-i7=QZP*=i4X}ZTm>-LVJd|mPDa3axf`xuN2y#C1m{(Ua zzTPox>3lQSL4GIw58K9G;8Vp_BJst~@154ZX;fop3%w^%YkqXcoBqWPF=uM9p6vZ;K` zVNeg-5+|4rvT?-l29qP$OQkF?J^fdn0^f z3qLUE>W)tH=jamO&>gJ|h`q|T>(mttOT?~_%%v4Dz8oiZyMcoWaA@iIEU%q3&%30L z&yndJ@5tzVk0}sguYK?^fbPl99Ui8ewU=d9Z*ASVPCMHr>JS3EZsDp~?7H#x`F8)a zhPjZ-GIpNaK`+R9vg-FUgnCkUyx-pVO%k7X+cFbo1u44VT_6gGwYtC-^`Xo45}7+l8Pe{d^!9Ls)R>Js1O8YO$JM7Y;Y zzhgw?_9X1$V&Z}8Q&<=Nj>xu5Ht)guy5xMKtNp&E-di0W&K2j32fayBAbQ7f*{UUxXFLui+ffq>qFxOJj6K z?ourolcxF{LwGp%sxCcUZxro;+flB@>-yAnf1#vVzpH*)`{QsdDtzQooixXTCFpiL z?m{9-Z@HMps>YXHnEu%5$VnBKvkvd+%BFGCuk^Z;XZ5>Jr!p$<*Jo5FXzE4w9NV94 z9>)0|+SQTFjAI+eo*|Ygq7XzFW;G9dqDuH%gK&UNY z5}n0Qmsted0JN{~x#0w*OhI}X95;gVFD2N801%g(@E0NYNahIEYvx;7@CnZg6fiVZ z=Ekw0;K!bjwKVGcLrAlHp#>)l|)3-Jvk0nWZcGknw;Az5_dkLae zq;iAxgfQc*JDJ`p31-?jnQB_aCx!z)#cw{~i^mwXVdC3kq;Kf`%4@Fu6F*pMcl73S zn#~{m-~5Aj*k21*^DtZyx=3m@YF?&|r_w$_HfG#yTv?x?H{(Dpu?OV;GcJxoUA=GKzPEw93|-cm`ds45Ew zyGG&mjW%fs-f!}AlY1Al5Uq}1xM=4MpNad9x;D>pJ^!9Dce6xhg8mB@si4aB%Po92 zyzxXQzubl;b9Ho%y!jdx*RN-hrgl;0dO+|a^Q)SUgE`|A*BCgW8foZjsULUVP@sE| z*LJPxu|DtZ8uLBjM@FAa^}cf6ZqnJnrKlV$aT54&EnI0NgrcZVhF82VEzZ-7L&1Qp zxr5lLB{}~=Zxr>L$l;>KGQ#ThqjF^c~8oBRnsbdmIrp+-M-WIaL{?K z+%LL|l;POo_eRbRZkFM1{FIqzm30d@^Qa1+tAvm(ZrKiHckXJ0v)uer(j(qABv1dj zPOjVN&f@gF=kLpg*F`iaW^hhV^f7S<{KUzaGtw^ng2|*U2i~DzcrGYw6hz&mbJe4< z;ghVHVKl+Q_c?}9tkj3q@e_qw#X-I&4TGdDA>_L%J168;`z=QfuuWyR&zq5_*PMis zs`d}l3y&uyKc8xgvsAhX1@BDS>!rRz)Si&1=ao4%Ee0bFEi3nSUx$8YQn%1TomREL=2gPBSR_zx^uC zb;_yg{@%Tb+Y-Ke$u%&U{NkyNareL=zhc#2BKdtV@hzqB>2VFf#0NkrvXZ6nue06- zbDyK+M%f4uud6_$0HmA=(m3(mIHPPl0ObJ?Twk$wA*k$AO6focB?2x3oKX;vVR!Dq zLCCxja1{Vmc>o;x3?>LFe`O%kSPDe<3^W%DIB1?%&J4;U@gE^}xl@_|#GwN!`c9sQ zMaid)5D8z#COzD`sNZTvGPV>f!Q(=X&UgAtc4C7}z;cZee!aOqNch9HP zTIm>6zdL~V1tb5RD?jm$?N+~CPTzIJ8i8|&TiBf_Up3}K5q~|$=A2iOI6Pc2g5h#k zd83|qDCXwaP$NuM#V@CMkqmWs3SeM9mpTxNo=Ff{75Ch}eA6aRFj-F9ZonrscPc>a zVA`wCW-+k&kZSiHL(I17D8;{vGaz;wP9fmFzoFzrXL3K9+KpsR!+U zgXffif0%kRphuASZ?8n>+gwt-R6q86mari8RpO#4K+rz&$pA6AQ#v??b4N))Nh8>&2RQ%rpsc^^i92g}X@g+(fu0irMwuiZzfMXcimwU!uA9D0ZJL_wXQ= zs2l!XmDefOJO8Anjfjuz6IpHDyQLUv){EY|K9*BPX49+ou%<@8d(SxQ9CaPY8ya)< z14Le=PU4s^;+nnnP)>{(NU=%0^RVctI1P)U?7$|`3+p*%y2A;iBAH=*xaOm_0Cd7tg8+Q4HQe5Nc1#ybOj}rLv!Z&{VQDlUn9}KYy>|rccuj;U_gXOfsBK5$N91G1h;iNTj#E zeWdC1gHZ$#E0c3e{C7!b=%SU6r+w`PgS(^8jJO06|WV1ysMzC5Q;)iXxq@pOu&~qT zuiiWpADL}oFcLpb5?x*OJ+y=e;Eb(o4qQws`)$gwsB0YWchF)FTmMVr2lzPfN=cx_ zJLe{jOA_K>qY@jU66cw?W8$1=H$2nueFk)r3?>jn8caHX!WO1P2nPrzw}~LborLP&bVzSZ%(1 zlQ}%KOrM~V4ai*G;>rL9UK&C0v8xz zzPH0w!XB4lx2+AtL=$$3Q)5zX>Mq+Rk+vN)Mb=9F4$uogJRPK)#*tJCVql`p8zSUFz@?&*)I>FI=jt8~)tU*fO;_+D#}KpS_UlMy_(ZUH{&8C#7Bd|H6BaBHrw z0G*BnSjh~z%S`Uk|E+@prpzy0-f^B`~`+H~vBEN0| zO$@-9ahlJV!1W)s&%beG-!9^2vTOjur{-S2n>E-FgV8J{5Qd8HjLU^i9{~2xi|~gX z5GN>5G{N)70ap_W+7ECxUXlAPpezC-=b46T6x;+jyNNW6>K6gB?73moy$JFI6U9>N zmLgs^1rI*gxFNGOo~fXzKn(y<8d{g&u6D#0C>~<`RbY)D0dEF?j82q>(xDl=02@78 zhlbkdBVRy$P_E9c`QQ!+D})R!gt`MQfWAhN3qc+<3ZgTc+`0M-c^qL$0G~i{HF_2S zzL_En3{_){I-W8VGB9CLi7j_2q3 z&>{E9XJ=1|vih!%t1Px@5rQEoI!fj~#(J(#JGV(1+l8_r6Xx-)#*iq#u4gYKEgd}9 zr6MVM-Pvx4wpoUhxw>4Ngz?yf$5LtMnclq_1+oB5*^Ff@+5y<7~?5vE6b4ktXtjMX>x@x4`oJOm3moJmZ;`i zl%S;iS64j`CNc8t`X>ZJOmsEFh)Q?URFf}%p1T{jw#fU8Dz@S(<1}o_{cz!B_Xk>8 zIYvvYDdJ&mvVvFfq2l9C9M{8Xao%RFKa~2}u-{1S_c)rdU!+6ZlE4)1`cQj#$WfQ@ zO|fZyY6SaM;z-xH`0J~WT4(N!xCV3lac8m^Bof>6y}=P9&CH$hq>V6!_gU%_e|tu6 zTeQDGX+~ZhR1T3Nbz1-uxry{{D&T z_{AYYp~0t%%7>!y9sbS>zOgwTOpgj;3Dr)9PTq?yuTl?XhJ5gWaVK_sD%be&bDlB- zhc9$lpiEmU^jFDKg4EL6gl!AUDV%R63Hn6+f{4GjU2YcZ%RTmLj^en@24RxAZry=T zdiR5dqgw;Fs7v5BQ9Og`kC(Ot$M3r7==?$W^z-QH6ySxG`gxm?DQ}t4;W&{&#gGPm z0(=Z8I*kD04~(z@6BX-WwGC)2&e{58?f9jrtANQthx<3b17(vl<$7^q1XlEu^Tib; z#yDGf&TVoty;!dx|7YkJ5N7cI8#?AS_i{4UEpVqWQ9Ox^7r?5J3@!s8 zT3!&iV4_;WiN&+c2;Ol8-4ehER`&Zuy0CjC;`~K)V&zDTHIy zy}#A*+$Mf+eUV1UQ^gs2(dnKAFK?%&>HjE;u{^|qD$#tC)x+#gWM7Z z?jI(g=K&C=!g!bvlx3;0j7j$k=y^EWSpl$c(8PT7_6`4?No<0{EO6>#LkXA4B9?+_ z-GW?UpqW{Hzm#dI)~&9ZRP_n-mHx|znL=$8QrP;pxHflg_b?w_N`5ZZVy4ynn4;tG zsb7nO@|XQgyvxp=v2@$qk80X@lS`vs6N|0(F~{u;V~&6F4Rp9w__5Q&bDY?LLbp%S z<)?h*@0ON(ArE+de%aj*7-LWE3%EPoXa}o&`RXxlik50(epZUL0KIgu`kmW<|PGX zD{tLHSK`t8IPC z!l+-X|Hc4yH0F>v;?P)Jr&vB#I>=PrKStLhqRnhXmgy@~x@wJPY8_Kxk13Up;kEZH zT>g}B>6>td@zcHjnxyp{8btx4csrmS`e)hl2jlIsHz1sS2jdL@F5`{I&0+>-X~eBQ zM%}-~D#3HH${iF1Kni9Q@N(q~520S5mS8(Tq|XDl0FbvX!hhIdxj>N*koX2}Rf1ap z2%~RUAchH`%E2GiffeSQnDn}ipo#^ASvG8Ex5J$xC^33`~zf*Js#idPR=khaSI zmA?}(lFqaeXjA2x9tV)pqGaUhaEHO)0pM*^#59HO^3s^l1JDSQeqg681>zt8+@~LU z1XBf7!?WG@uK`X&9$Jk78i97*RtL2p@t>{idrXz})NRuGrwa8K8gE~6^5zcUA*qMl z{f6;$e3~QA&RjX;;^UFPfMDnfdq7r5G^Fl3gzwHogJ?`((6c^#^17zhmB?Olspb%Y%coHYX~Zfa3G0eSr#Ba7=ygY|>sN@bB$AVBvdKV6cuJ_}$~Z7zHA&b! z74L)$LyF!*13DJn1rPSk^FA5;p@P)H8ixB-$woDvZjP*HI?5-uIk(YQrL|9IQIbLh z`{O^5?^0L3+kWSE&rV7$Ls}r=E`$+5@*wE#qwhz{-_py)35r@Il#)hwwrk=rohk-< zMBBz<_oudYr5#!+l|5`kYeYv?r=G*wxytsO*FF8>x4(!=ZZ5{ZwDO?Jt+X&(gt=KR zs#yAD{nGT{@Q{gbFC-n^C$^u@|F8?W`@RbDu|YMgW=jz<_I~^QIAiPu+Dq9D;VsUs z(w+BIvijkFJkw3KMmY9~-sR;>tR2fqe+yrf`+sbGWk8h8_cpL}Hz*?AQWDZ3(o%ww zk_w`f7&J>LA=0rliXtf~EGZ>j(nt$Pryw2g?6N$MzvuscxcG20J9Ed(nRCvZbDc9n zk`sTg9@*uFz3|9L`@u%&!1IIYnY35zr+SObhjTM90awBRH!9huS`T2*E2n{e$10JI z7;tZj_&=&2t~#8N)rS8#luZd{5<3&JVO;avtu=&JQ*CzNvNasp;<2uwftH_mbcU<> zjivozm-JjMJ)I-dk~D9-og-g=TAVz5C|sR;+#}_S(@tZf{$*R|xhQy;k|E?wKA~q{r1U)&rl+4$b3;1G%7rz z#I!r~Ohdu;MB-(l@(_)|S--;DhA`OaS?<7wtwPU2&&t?h+d=I}^nID$KV@%P&zfbc z4v)BsEA9l(cuJq?em%=QTVW^mT`ytT-ps9woldKlKB_rcBTTbaOTm6RJ)`>^8ue`D zPjs{QRsBD|-8KzVi_V}4HVn6{ju$Hqw4aU87KrDJ987Hn@Kq~5*m3LXY?btUMKRb`D zo-6GA`tEsF8KArqW!LR@nCP}86gsw@{^yd?rK_t9Rvg|h>I&`Uq3|%}knLjAuzH)N zA|-M0Y16Rc9Ddl?!PJ0m(ni~|?XP8z0=`y~+Ud`^{5Z46Q)0EdCGNJVE@*>$1B)$P zvU##A9SifW3I%Pli*#xycTdq*(r$Fi`aa&rp*(r;x9$ugvrK4it~ERZiV%XO52*~n zZoehM!$H+MgPXi13Poq<1P$$#@~`_LZib{VPI5b2nHh1^;~wMa!cWf-1rCRNIA=Tna_d- zC>|vjKHY!9IZ^gIe53**h=Hv2G8P81{7|)C;HP1j7#K(+dgBB{o92PL0DyUuVA8<2 zPSLlKwsb5sV=kPXTsX zO2mOwpDm`bDPfxA#Qzeg^=@MGuz}R7|3j%L_z$IG6&Mx(G3`dz2Y_^jQ-02HvIIJaxPrGVS0U z-ZeM>g|wjJloGKGiqH=a?Yp&tVvH?PNgf;=%dcJedQIzSJru7j^Hx(b#Wx*2OCwVX zvO7=19|%&}^(`c)YwQrLVI}QQ%D(G-rG_!v6CN#1quriB@RaJ8r;cOu z9e%2YZZ+NyCPwwXEHQ@ZUD6}N6LnWVa zeS7sW<_R_Y@`_={{O||d#QEW?{B-=2I?s$g)he`AW#@Ag_jKHt>1C*R^C9kv!>)E^ zPCyjnT3q_|Yzgt#IJ#e-hCE7~$t$Z4+v)LnTpM-v)BYW7i0;)cly7c-u6(Y#byCsk z$tcU~OX??rm(AKe9UszP<`8#^HPW?Z;O{*%Frt}vVL~^x`2EOY_2#kKQuJuc=&^Dn|{d? z3%{Q`Ey_r072UTgZg5Llw_{bKuY^9hGA6m{I#`+1aQY;R#Y1@>x9t4M~9$iL=6;w4t1Yg4W z8QDeJLpcqmFeDgslS={2xdzZX0KAI=s~DXPQIY8tc~XcaSSJ_$H$eG@QrI{_TL9QH z7A`%Ma>0O#$GBT%2R$qC-i!sQw7Empo653RfbD#fY!r77o!RY9`tQr)_qyJ9bm3Ew zSOuO+3uGRI%J$^d(w79iUbtp2XQa=}xAx_^^p3p9FlKhW#pSIQw@(RAeu?TC2B;s< zMBYs(s`#X_MwygOq1&OIwA#>QWX)5QtwP$L2%Rut&Qq_nXGy>;8{KqytL`l66lm#E zP5YIN{sqb9XKq(^UiEVvzk9kB-?460w&|l4Tl&JVz>Q|e&P|$x4uoH1sT3Y050NVI zzS#~52r0Xqy>Q+B>PsUbHDlFsc zW-~$2^vUG#w5@t*=vdJ3ee4)$6^QF1ZxbCmPZkpWs0;t)GT4qII%xh0qTu-D{+6QT zc4+d87#y^b*t&4&8(*;-Tj(PRnm3IYZ;@^?+2u-J`TiV^Uzf$LZ@e$Swqu<-_~;#R zjIXI{^b8gAq99Fo1V5=eYi}pIMxfJl?@bj&XlBK|;weojrIQE@qnM^(xPZjQ%UGg^ zbo==~y>U-?Q{OO2-&W1(u}{lb?4CSQzj65&ec`DQDSgGVo!K-+u*7C5$B&{Lv9G_S z)o8Am-y8Xsw2iJA$Now+O|tu}`QyzMjYpPZejnQKEAs5aqKFp1_s_Tg<|#Ghf5FeD z{N=K>K+qEhXoqRdj}Lb<1a=hHj<*(IPn#+<%idbS<|Z}`8@f&n)?Xd=jm0})F3*I| zGj`aUKA>67%J)~VRwqw2GAvmSj~h+#ZEHIz=yQ@flr4EuZkQ!{`WNpMhy#gUO8F-Y zq=X>#GA5!p71FH?BYjPPg99AO|2UPA6<|JI7Y$woJK@Fb1&&%&p8hgu3Qz)9!9Gvf ze%|JGfXMq@L~RJbv4RSwBnC|ZkREQaVJt~DZm=$JGar8z0nIOZ25c3mZH@#q2RKhC z>PR7!MAl%FPXX@a^L_B5<|tzCLh^qzQiDToH1IP3xB@j^5C+?IFvJsH`?xKzgr8)78tsl}j1$B`F07ADy(IVMK=#@tmNEOrD8p}VLJ4WXCy?>CRZDMm z6iXjOo80frht?`WUc_ZxE9&EPBmZ=F&PZ&I_hdZNO?~Q4W(7qHPEC*Wu8xhi!GK-(9+;iop-jUcioSDp#T{l5y-hrN%ogFdcYEkvzL+}s>3Bn& zI)p)G3M2gII@6c%&r+{%Si3mc<$q|P5ehfIFT|Z5*OCL>^)|d!_GgmdWQb(v@+++` z#E_jQsg@t78ECg=8D-vlmHvK>p629UXI-&CRQTJ6^@6DnJ zvlcnDS%8_0)+i-V&$`CQN*SQ-Vy9#5I1#U~!idRDiD{k0Whrit4Q6P1;>X9m9muJq zFX<=JKO{kkcqCXkdH9cs6O@^{o0$TFU6$ zxEw62e_`xSfm!Oa4^7jG2{R83L(T-|dhGaJLnMvRDEM-l@K(ks)XiIbVKWVQA=F$p zrjb0Kq}IOKLZ@%D5#)Jr?Q);isZKhT?P-3?p36vQSnmG(#u!Qvx0k8avxM$Q9kD0+ zPFL4wwa3VxrmCY!iL;@Lgm(rODKoK=04&HaM@hf>$XCvi9EgqC)+ z&R)aWV7yrUjnL}6ku9t+_T7Mm6910^&$xq1ny-yh{rL0v$CghR(T{D;xn6_Q>-~3A z7hup91;;Jwv)il%2YL%hHA2?G%IEONa011YeewZNl|5?FAc?_^;h{Y^*#d+uny@H!y{EP_Bs+y#tu;dVE6!4pE( zzdWM`iqirZ1OUcFLzsfB*i5GmsEgOYRRFlOIsqURK?KGeXnXP6g2iHo^3Q^ZAXFV4 zRFDi@Pan@89jU)fiUU<@94sGzG6}2%3}l@on$dwg1d;vmg)ImuX3jT+b}$+MQp7&4 z!f=AvfVUI*7-)OG;6DK8dr8Y#MUdq_&hHZsGzR!Dy~xvW zED*VQE;x!n6M%CW{|-3;E?8<-z`p>_{{?)Iuq|Hjrcp*AoPv*l7aam5Nbm~)q+tv701sYokj+^0_qGGlFV5}S9MBYje+3ri5_s7Aee&wF2&3&xxbNEf z`>mY5`l`ZV#cy--!@VUGMDY+%YQQ_TzW9-feR= zH#S~pi3eaT*h1;icw?{5pcymTYP6w$EDzQmSx`i)ELh*POw)RQR}roQlGHZB7WE&@ z>b%WL)}^g*CC|)QbYo@pc$KLX^24XcQn2t3rpl841B7*ZZP&Je=$x)aY`6Ml83LGm`$$AWMUXWuPTIo9Z5 zw$CSi)_-QZdB3|ot6J^!FG(rkHF*6j&F51LG3MuqBUZ~t^21sw8B5_e7btF@e);gk z%UGw?%><*q7W$5cL2sM(82iiN#|#$`-L#kW5hto9ASOA{Wu*^m(6Y|a#H)NWmoz4u z;jm-Z=CV1j>PLIX3^_)}r3yzi)AZnS;k2-#SJ$jcDm0#)PF*?LiQ1n0Gym|=^`7U! znx3_Fl2>DazVR6Of@$8o>*SiG9rf{FRO?WnOPF-&IcNQ2gcG_PWvRb)sqPB^@ygjz@h-&u?8CokVjq@h9tLvQQW(cGE0!<2MdeE2ZSB zt!CXl!u@G;SM<1KFqu-lnhQ#&@A}I;tbOG~{)fSu^4fC!%l428XV)5+_MJVdqs!&@ zE(PNA{30Jwr+asmws!0JG~L>zFUk-aACZPDC!KiJ+e^MxdVS=f3wx19t;QP;z6%2w zGb8v0Viv>;)URYE(sw%2xby&}oarYFai0TJflgU&Mp?RmAmPBKlnXX^Z ze!Y-zp?~*&puWP$R6t%fDR^N3NF57Vw*IyXF)uR3xmOH_is;->lm?9ekjs`G;c0nt zSIT(=2otf3BqG4ogF3FfaJ3+PKn&lp$B<`@n%iKVqs|&(PTK@`*}_0K4!-FD)xfYc zLdCrRhYc$0yc3KF0JCeupoLGQ;(f(HkmtbO$N_P zd{YR|7{Z1J#wdz5P)EcodR;jBK~0i#QPvBjGr)P8^$k&mbLH8z8feIuK{o(!pK44) z2$Cb6>=1;ejDlYPz;BsA09PJ@N7gMCsO^9A$QH)pU1JC7+9pk`A0~jsjWiA}ym_dC z^FKj100`zaZX`KVFP!Lt%I<%JrxqB2=nSwB+ynOm02esJz{F;M54v}H8SF(3mcbD! z#R~YYE*SAIHmB8k@(;Vm!D-)L2|yoT)!<|GCM};Sx*K+YSL*po;&lv08a{u>YksU$+&xz` zo%DXZyJUhk*iYHW<~bkAbOZ`qGVpz2;wJu+?|2}8*EzQ0?FQ4CrO{L7n*}6{B^Ix} zZE;idD(^k-UM5)8Zg1~Yi^DSmO^ts{dZNQb6lGArv>F(Wvv+|P^yAThRJV> zK|41iXJOCHeEYv0ahC_RhvR;9rltoBFI#9gxo#Y}8WB4%J+KHAG)tqB9ag6pfJ!z4KeS|fXAiSy0@6`RSS&sXdVL4G$z($0^P z*yg%$S@9m*4$gtGhaH@bgW$lS7*{vL>+9~@yAiuIw++UbV~gZ_Mw3Fs3|;F3s8&*G zzWgK<;V>*5N)}%s98zkqEsq19x(AX2CS!^}#UC4Xc;RD|S83TsZP z7ZZittJ(IhdwLhX!6E3X)>@0dxPz;eJ?;AA+G%2|nw6gq9RtzV;74}b5+R;qr7&ZA z@4H~kd1S_)|SIpMG#_b=xXB97`j_H7BwO#pbi2LUq%1R=5H zi}5cE=nD%Q=!|Sg-<4_(IOD7bKLLO}$-ym!AQDY17C{i&8*mi>24Wnpz|$77O)!uV zVIaB-_@)0x2SQ3XHsED22|e>p2jl|(+V;Sge7VZ1*1YmhfwdQ43YQ^3TEP?dZ=xIh6lVRT!a#W9EsMYCiTD zdiR8e-a_APe0w=G|6SSxA{>g-Vy)N84XK6CMh<>DSFD9P?-$xuir~Y>RmL9{t&3_% z`gl#v-OMg1=yJBo3SIlyp1oUra5y52;on_Jw)i@NO#HE>jMmRPZpP`>qtIvqo&27l zgn+w6dG6C*)?rC9CWrZU?um9?ZQN@LwZkmxE3m`sMbaK3Q(KdGsg@EIQys$HOtf?T^Gx^}D z=r7Y(6&u3G7Z}p(CSWkp2d$hD4Ba=6jjJjazSgl=<9JzXiQUqfjuXOr)sprRTa8XzCPg5M&L#zZ(0DWG zE8++L7$Vm%JYB+|Jpg?F7p~@c`CHn%AX>!=Tn2yxUdN9Z$c>eNn9&OYx^O}n6o4cT z^#!2(Sn)ybsf$ zF#tj@QT<>}NvOH$ix+Da-Y)$vyxq+IQ*!W6NTTmqZ>REXxF4u{%!x+y$m9!Qn{WF> zosa$@TH+Us%W1*Fe-}Fj0t8U}0xRYGy`U5y#X#CFm14-mC3m2fsc!T}` z5Lanni7pUsb_A~|q=!N59e62w;JqRh2f*!!B9Zw4egFX5ZG==pfp{~CoP5ex2HK9H zEK(6rwdP!93kFRQ_>VHYHXsO6R6s!9t=Bihr^y}rLW1ob`zo%czxaJQ%+G)6-sp4* zuiB~pn;;3*DbjuNsECMTwXOtQ!Xi7Xm!(!M#?BBUb1UCRY!XljI@@VAx^(HA9uj(T zj6}cP<~~{#z58<@$CBm~GG2g5OggLjRGmc}y7rv&^J5LY-InfwWO0V(n~er%bsWio z5Bi~zdo>#}3X`r+rcPf6_RUlWjxu#m(X>RZZ}&=t*8Sw+e^OS)pZrT<{oiFt37$IF z%ar&hOh*C~16~9#9RThifp-K!7U!ua1gV9M;K>2b!$VMuf!Nc&NnqBps$L9e*qxPey9>CWiAbFh#wP364Yve z>0n~^Ae|eC`2>4s4h}y5=9xlP-yToioVfef9t!g9QF~|)cs~G$kQh3+1Y!xh%_&^<-e0st>+c|z`_hd4fxwbMrpjCY1 z7LUP6?a{fxq%MtfKyM>2{f%tT_0Cjxu$FrugbsZ}_>)iNH!RI1Pj?~W< z<6B^tyu$l~pK&^+Vt8;>Qg$VG3~rZZ2xcw*#({{tti0IS<%YbNT9%yZk$>m|y4b^hV7YDO1sgAh3e|S3>iK5T&7)L3!XS((7GAM)=*zb!JKg1^| ziOW9QK_3{4U2?tVNXig`CG}8nOll5Kc0QS!<;oBAKCVRpbu&VbI}LBC4%Z9* zD%|SUmTyn`Mv^A?=h|)BtCl`#0)-z)w|^dk<&HaB>N&n!GUzhOCoCc2Jao+V=uKgbUB4r4?Oa!p;P>->qg<`DM`KC*WK7>s z$J!)*BMaKm^Y|0nBdZ!&RS^0|C(WvnT#Fa4#z1cUhxH}I;76CbY(qki@Wk!?yhjZ$ zZpc>pbqy@{sHGGw?l6ouF3fM=xOX@5Mp}@>n|4e{+{uB4D3fj|x^Ab;+{Y`Mb!ihP zU-y$8r6mvk3SvfBWJe@LA7Nm_YQ2cBK!ik`yR1;OTJQi{!Xk8bgqw-7te89-EO7+G zGeQa@<~B;uqx?*;WevhcNDx@Bh8|#ds|70=0Pf*|?Sjq*$a4S30z~r7316s?l%OpD z(g0*b#EAT#gJBTpcCH1Wf@_h|itP<(T6&o&!Vlb3;)UWUVkUY{c7_sqaFr6$})=!Nz$3Mg%w)dU@cU-+2MjVhCUd1AsSrVN+wUVS?VvSN4B#fp_#A#gPYy zy-*yytw53hz+(vs70@AwgzTwqAf~85#{e+&9?TIW7w&mkm~*Wf}v+i63t9->WBjo=3zx;6DJ{ z?M1x9wFgAG=*aWW@yne=&ETFGFU~)KdVKD^L3w&$a$gB4OV$oMG1vsatdaPU*`Np7 zUu?}F^9|)4rUP#c0AAsU4>F(-z8l$Bz+(IiE(5?VUg6SWKnTI*N-eNA4uiV}fRAfo z4WL6%w|(Ko{-2vioMJrv26))dC5aR04*>bN$Q`=%$J+X-vMgh99Y{IJ|mRSLD`QmJboNDXt;FHCENFAEH$cJ!Yw!bB{R%e zYl34x+C*AYGMTX`2dA&_E*2MTbUBFr$g-FB;M_O2SpXSCCrNOKKqST-o0C;PZ{(HG zTd|++)lqTZ(xX25_TC4*SDf3Qr<0u2<9qa0 z;X6!f8lM-f_{DBjnvKMAmm01nkvzQIiF=|D@7y>ZLF~0qgW-htxbDEQ><7cH7~A}t z*=I0|*QwXH;)%AC*X|!sY9%sl`wW$lo2J{eRw@QUn-});Z{1@|O{kB#|EQ>a+f}e9 zWlgHFs8xuYhPFcOnuP*<{6YMcrVM;?(FcZ*Wac}!lThOgB3(XRU&mb2Hy?hbd1=P=QlfGW|D97( zk-9u@{%q*Y1}FJ$82V7$ow8wO=C7OVo>ktIg(5`xQlc^3(=z>qE94;$(ux_>K9fXo z?@^_M{V9#*%dZiUdCIesy;|wMz7)3X9;PI_)!h?-t@R}d% z>Ws9+FT-~^pSy~oXQ{HSd8$Vb4+Ag7&PBYjHnYw#dZOWFzsXw~{isN<+&eh#$e`o6 z@ZjDAFZ5|;fRMd}XYafq<+@RZ_kG%sn817A74KfT&QQ-W%H}p!#Od^vN#p(*5v#tw z-H7lpMVbVfrkY)<{@bc(@}IRHZtNT6Q)tZglc5rs7D~>eo%A%hB(*SSww~CdK}HR; z&gcFCQDi)o(iXGLDTkhouKi8QZAzjP(P+P~w=`A4gIGOkVz;F9S#vDDnUoGr2i@`wMqngBtpg@Rw;rQ0F?;I z4!S_#KRZ=vbdf`Y0BJxE`cHiB$Rfzh)pw9^ZP%1y0sYvhEdGWdwbyQFtde)xOh2$N zD@=$KJ9!mF3lmNxwwdKsovqhCOTPvWE;~E6hZe-2bYWC>YIr<+$c6pMF8|s(&WX*$ zZ_f3kvJWK>!;&^{8QziH>)rnZ6uL}}5h3lfpY7+2ll>2-XG4O5tL&~{%z;rpU zZtGB&v5#i4{_;4x@#e8LR(^Eo+gSo?^XA;bc^LxX@uAS<2LXSn*1(+v<6Q@ufG~JL z0En#*MNkJ)2Tjl-Jf8G{Cx)ZkM8ZI;I9E;-L3;ogW)Q|IGKOFy4Ytn;I|a;=h2}VpzVh{N-1;T_B2p7tT5oW6g;1lNro&4L4zq^1}Sn5Q*IN%onQ8sn&nSXFVrec22BS<}mCD zMsa!9JZBu*{md6aS8lhb^LMxvM?9$=meNaF zo0A>uPvr&wz_O;_-~Mn!GMY_!Lf?@3a__tERlBmKZH<@xUALT;mgP6;Z^}Tef6vz_ zW4{YCSvmS1R6$gg8eHk-m=}^N-cLba*mS3>@AeE?p2AD^p>}evkK4A*GGrYeS=Ax} zvY)xyM+fg{I4xg+%`yw#T3T5?$}qwrnA93PwcQgg`YECKS(c$#S1?@NCjV38B*n8f z&45IRjArf2S0+UT%Tyk?AA(jYpt~xv^9!K`4XJigRi0L#JwDOeefHxZA3kYMmMs<5 zEnTZ&uvIM?`LT!|V*+(M)%ZCt&d6NuZQCp)E`tVdIp`~TMOZG{t`gEr)iAQ8ArB{xICJ!2?QqCNv zlMcV$2>hyil$!MHlQf- z$dP)Lz<=LzQL(G!G_Zkj-l`a&oTk94jlAxM0mIdF4G)+ysMMuo(^p#j_E~q6p6kQM z);`6!7agm<1|7L>(8+`wLXJaX&BKvH576|~tK9t8+WYRIXFfYN8@0?FHEO%`l5uP& z*v>m^a}O=_kWP7*H*X}gF4{=+v|3tLt%WVD`cU&GIlEs&(?0zT0Yx)5pE5TgWc74Sp>k#0xc~6YT%eW#O9v0xdwZ582rdC8_>a_vpmoZ-FX?5mxc#GU5IBoEG+fS-*7@96{h>v5gv4|8^(`z-E&qqs+)VOa4y*hA zZ+kj12CYTq!m1oy{YY6RD1}rtzxwQ6moFxP8B4|W)i&kViA=#)Zhv~{o?7nJigh5^ zX^}*#sIFVVDccTR<6F0Ui#Myevr|>*g11NH*%0bG@lE6~zvw#8*cwDX2}5X)OQS3+ znlC*CGsf{~?u0x=uqJCNF7f_vUl=;5#jB zt3SGO_jg(I5?Ov7*xNncvA6rKUaGjR+tqdqAKfWEL+p$AnCAvNKM!H28R?VL)#iOM&Lgy z8^OW{a%Wo7W`zT9Dz@JXe%E0pcj*#o(YLzV$ONo#6~ACoBwyP*% zW4q*Pvze9Ul>K&fk>RNLVDBBFcN5yKU+l$D>#;FeQ)NO}DA&MaZ2Gj6s99{j4=32P zEyzqtMJ+DgLZK%0_Yz0ijAFAa114$rk7rjKDB_!vHsP7INklhC(A#YvezxgqJEF$^9zHlw@>Fu9wijm#hA+u_G(IL4yHee$=>=EUz=_)U?a><{OsGp;%^c78e~RAKxK2}`(9^z#ke!Fb7XxIXVMJdo+QO-Kdl>} z*@_=$N_Qu?zVDhBy_?1@>Hk#c19ab8_t{$*);3EM$t;WQy@+i0muv(?M~U0*RwXy* zc4a!MehukdBU29uo|%fD;1y`)GNo1aveMK$*6d8|r~f47;aU47Ge>2!n2@G6Nr`X7 zW8SIXa!KTxW}#(~E2bnbuj5nL&3cTlMuUI+#x|PzRQWy_sufL&#Xj+H(DQ{hTIPNb zry5%~=UJ-zDS5cg=QoxsV*lb)`n6Y}S4iA=@mZ;9{|m7e-gy44!%Da>?O2~#W>C%Q zj_m9vQPH^c%zD<{(k0iGu#ObwfhJxy=hy+4_>3g2Wx1)wgsSz)%KRhlmaoR_Axl|r z?5OXpmQZ1j+GdVX=c=tJn-%O*trG7ph{~;z{A)O@p&(t@gt&S;ZRxMI2ja_79#B*c@qZ`w{pg;@ z;{qTtxQZa)PU}?#fli(|bo{Q*1<|QhjC&f+*F1hm)seetxf3y{KZ|%S6!-nP^|h8y zCD6^DxY`3HA&Io%#b8{~Em;?6XTs13S7vO8)A6+R1HPTF0@&%gWz5ftC?YLRz1+|Y z-}pKTC_Gz@P4ky2xV?XD6eBB7T833}-N&e*degT}sN^)HQ0hhERGpripcpC5lKwhg z!(7(207*aP-6Bf+cXfhxE{u*p;;b>Vt=y!oBKAb03NO8*w+_2^3azJyK{H`lesx#p z)pL?%S5XcMR6?;3v5eqPwQ{b%p(&I(PB+Y^;f* zDR%bnw7PrC_bIlzw!R9p42DjI$gGvvWmQByiFh5ahZ{f&Vw*!lvVdI^eZc`Fbm1}O0+S7a z|0@KauqacuOg*9rErOI)jX%_yy<>tO$){LXIadcgQ|iOY7wcmS>*o2{a2Aj+#4}s7 zJ9A4?0pm#d<5Sye^iT=K)FjwOE9pzBLOjgAMXH-=Znf5v)m~Md1v^npuVqX(qe5(J z9XZSg;f`9@axt%!TZ$AOuvXn|BPubEZv4QjLNg{&%PLBKRnQT;$Y@0~GXCuD7ss5!ERVT&BFhbLi^rt;im~$Ez7hG| zMkA4~o@Md4UWXx9P@kp8Hi+AV?^dT$x#1>;`ehC2@@t+C3wwg}$jK?`KjIL$U*6}) zTdwxQc^UnzGLu@Gw~Lb!mC5D{m+0`OFf- z2HAM0*Pih*s^gVJ*=3Cl!!HFAF$M~%aS!30{4*!K$#l1GNxT|gkM7WZY4_=yV-68i zZ7qVwX|O+;V9w;}&(Hxk^@tj{es^oNqE>zXJN>ZSphw}&w#B~-Twh6(m7Ubw%C=>r-Z~Y2=y=RsuKb+n?4aPGI`g=s zo)@mSV>s^k)H8Or2i~*cb{Sb!fjJ$Ly46n~I#7oB-OQ@^apK!EYW_5c$fxJ4g6_M5 zM>Jf=$%8hgl_tHRw?2PWKDN=6xOBJ~P9ag}mR1Cr7@=bmzD%Q(5wNe6q!F^IlVYrq7j041Ja@B|)Fd z^@gQLPWY~DkTm=CF}XwBzXXZ3ltkSLl-{XNv$X9E$yOj9{5hjcBOdpNVbaE=d;JEn z&fI<<)aoI8^H*NoVxAe- zCBm2~MR=~KKH$AxE}}^HqqXrmrN(5m2xrCdrfO(!8pHB#bS|E<#@V*=?-~;;-cu~A zxF6V48Ts|YQlGcqYs%)AB;Ka0KTuu1Y{$XzLJ7Jf?@!aK+V8D#R(?XGaik)$)})zo zQq|GyU1j_wGV~bsdwN?osmpt5V1H+4r%hReI->H~zD%}|sq$9`Qd1|At%F4Af~DbE zkl{Z3b~qWwwO%G`K}1?Meea1oT$JQ2vL{Wrd~8j0KGgGI%p!%%8(u$tr9e#9{s9YJ z1pQ=?(hTwYle1<#9`(LD*W|NO{lvp9d=`z=Y1Ow?KZ?s4 zW{14{F&*^t?KGxOYKJUoOf4HxW0AjFLZ`I`;;CA`$cQRA`z-JI4iiJGF*hi$ zSrezR+p475+weEs|B_vwnb1(x`uxUj%xmL=q84lL#$N~nf$yd_9j4GqkayE&>r)?U{KKq3*;}#+*HfJ0pOiPXeV2K<*H5FFaCyXy zFY4BE+c(xF;Y;28={4+_&sLZIQpFHQ)W!-gr~QD{&joxxR7lDLaGZU9YKJ;Gt|2)AnWQ;_B)1bzkppL~jwi4Fm`0|PYa7vbVA;GY2J;{yss6UdiFUmYeuRoiA?JJ_#>Bp@`_CJQhiYldC&Z^^;;Xd zlGG6!t8UI|}OLp%UN}!n4Er(R}>4w?+ znX4^-;@mpr#!IB3bJevPY&`SN>>gnZ{<+;IQuQ^kXhvCK0ZniYoUo>J^z;(BC9vK( zh;P-K`y&2zIJ0zr@a?Wn6rYE!b4E)v1AP)%6}xL$oY?U%XvIMrgK7)A(C=Hd!oMqY_#I zU#?hhwe9&M_vaGv&jx1-T!!Qe-Fl4Zvu9rU+WK&|`;puvx+%bZRZvx$)$y@s|2Ucl zo3md8Ya;RWuf~u?8bR%-gY>P!%g159iSbRI=xn1+UjFXW7bt_YULyME7XmyXH~9MM~Z_Gos>m$7I%1 zr5qMTUx}y1&scfAc-|7 zrSLE6ks&-ekC|_etm4MszyC%RTN!@4K>OX?6M?bTJ8ml-)PN}}{<*V-&pQM{NSi1rr#(=?2-=t`N z`h+UYt?Fpi30uqdcb=0|LwEB0yy~gkt%e8Q66{OFe>tVEy*gO_NA~C$c`IL2Su^Ph zyyq__VppK+gx$Y_^AQLD0EDoHA##JF+wKcNjz9<`fFj0KEQkh>V`uEZIi>?H1HhR$@FmdMut66M zxp!Yj1F7VRif|GIvB~Fxxf6^A02ekO_zZzO16{~1fVkWQ&;qVj~`)IlKXpAE4QO+Xcngb=$6Dm)9+o=@l3;*~b%k zE_ze zFR)naJ8gry*1ud?o(&!x?cKJ7$h4iIRiYhP9h%wep7%eXSrmV= zaRtA!-TTgnJdVsa!(^|!95XNGKXy;nRqvO_U*l5{ytR?yd!R;Gx#*O5cG`RAd;FVc z$8=1#TlkKh%M~N`A;eEhq;pqp=PDOHd7(Q!xckz5VDs&BlI3!5y!6QYeH?iCdP%UlXBN#I zTcuWi)2rGSiO;u$DR(dzrT!x7KnIggB~Os71WasVly(7Xt)jF*oO-a30pKDrSY7DI zux(@lF)HQ}r6is!HNeMh;(5i`mJRfDjEal8j;NJ-en?verZqsRE50l`1e`g+lH5Sf z28z1?EN%)|uN$!k8_2@=KUy3hHbrIs{Ot>8&jJGu=vt{Ef-EC0v?xRYv-1Iu!GHkp zHZu$mWqA*bSW69RwpoG80RNIzu_=Lm?vRT<&-!b)_=e@E_f4B5uQxQW2D~`EkFpOK0gWg^u&{!(#E^Z~B{lBTwG;?zf-$ zuz%eSZMt#UE}0koa#DooSE0uv_sH9?IB%-?k0e!5^D*P?#0HnGzvs8hALv$`Q~R;| z^rhpT!`?^UTW^E4;Qc2LtW%*3Q*JM-5>317nnYb_8SU>+3ZP$qx9Wo7kJiSOhF6z| z2cb`3W%OZ;kgBjwywtc{EC89|WF5=+A*yY4ztF;kqz%(Ym`T?Px@v-TL;8{JG`F(I z%ix$cCRz-EahE#n6@rFQEJyXn<8D}AE(`Tz5R%?~+`S7CPZA}PUtYZqou+ZUNAXdT zh0VTE#ur-rf_rDd{JUo7{G+1o@3U;{%fj*cr`WHT8d80NnRtSZNQn16%jMph7NxgS z&mP}C9H;ZkGWP1-(GwU9|9<-#sfDF1T7H7|Yll2?`Jy+itjss@a}U#JuGn1fA(Pw^ zEgCSt8Rmj9f1B^N0ujzTq8(^w)DX5Gm&mQQaDKD^%=82@A^ES@Lt@93YOf6#MsL2) zs9<F1t)@$Ir8r$S6PMsST-(@vs}@815Rws>9GZx#1CayaWSZZ)|dLS_OA& z>+hBONXku<-_wsUfZya}jEnH;(GMPx>-=mHcjSrTPObm7x19&;@RCblh5BN_5$aK6t;9fDr^vFE=0n1=J~^DZm6?sVns)8RbJ;L+oq-A4&nwz@WF;z?fl8UBV-7zf+3hif)GbN-- z@v;wj@7fN&Qie0BTCV0hcIoQYhyJX+Gp#8TFZ;6dOehLBJ=c3@)ke8sd!q3)%`Nbj zffzwIhJ8Lw_rfrwjAH8`8mgvPnE(Iidh4*Nn(uwsa}FWh(k-FV-6){6C|Go6Wf{PVhW_p6~DdoVBY(2ycROCnt~yflPixp%5m~USy26&nVPD*2n$*_Z zze*!pb-7C6td;cY9_!rl8vbOG8eijv^{-XK^KjEzwc{G!sC}3`!@<+){BFI;hMOwFU45A>%6@uQ<~fa7H8g1TYxE`T&DrUk2T-04Llgxt<8@O|-| z>H5+q?8%l~v#l#ra9El*YZ_e{)xLT)>rh?r`H`kuMfwN9-V-U)J8;dZ_5-P@c?uUE z!RwC;TEq75$WGhYI>kM_aU$$3Qe2z6Bf+%mNSNECuh7x3sviPxEqmzBXwu|SJ6O(3 z5FOX1rZWFAp+RDHTuZws0b1h{9=>^kLw z>#nF0>7n@Ns3UHsM%%UibrwPRDnC`OsRwIJ0n<8r!UAJo(J_N!As8Nj8hgm34BtS^4)eDXU#d<>W!7>DZd|p8WcpjgD z#qPU22@`%XSiAs`EAk*Y8+IFP7cR>%;ah;K040_(S`bwEL3Eu4<7weR$&`i`j0x~eRf6u;i~fl?Uq836nasrV!H<4xwcb&x z6Nq`ZrFw(?#zCtXi_9khF=qmoxhcmkQhE)-FcJfc`=;aYWWEtf7oqt`WD;CPeP?Br z%I|$JIbwFp-mzAMwm3JYufAh_v}JfYxo&~ucdR12jAJT(pWmLeUnKi5S3d5{_a(kr z4uGOL-j%#7R5rQg=Rtq>znML)#8vvj>0S~!`( z{)_t{v@%H^o_Cp1n3Kh>XkI_Svc1cZ=Fgn=8Wd5uX?wGF`7j7F}$p8QxRrJ`;FFS;q0Gkh4Qrg{;aBVn;HHov{LoP_R&}4*)o+B=C~0u zLdWw0US%FtE^NuK&cM8OID-eSXQ~Sm=SAs^o2iEt&1=2M3%A`3Pgw8WOHTAcSjOws z${WsRUL1#KJlDVapz!^}$HOmgFaI{SZ(H+sjtm(W<(Q0ZrXjs?c0Yv+J6HI>|id; zlnkg#gOMD6YG#7`C~Us}F_?KM{I3xRKNB0>?$9el-qND}f(z%<=nefz`8zXT=t&b9 z3+tm`!86TiU(V_1I@n)!8E1nKtTTKkDR?j8o#%F!zS&gW?!g|N^}zAa^g8?@lV698 zN{qZeL-E^jKlg+Y$YQHQ-Pbc6-(#&*7&oeks=XX|R!5I*9=7Dx8eV<`pS*cu5CVT( zPQa-_Twb3NE4J}+agJgzdeeGb5B@5!#4EzyZD`l6)`FBRI$;_>ut8u!o&r~Ek@>nxxX)w65q!w$T3=; z%e-~ru%g`7L!FjAS9i3pxJl;{I1Z3z=dj0kieGq(q)k5b%VtNJLx()$g~toB{lk2j z5l<2m-fN6+1WCI=;)H%BxE^r7{U%!maSTg+$oR2d&MZd1F43NHZG#^t|GJVJ2fXEt zDj!G6RUdMv{g&MaL!3#mJVG`h#cjb_t0E!0E?=WxTy2bijD?Q>>5RK7Mj#dFeZu&7 z91KY#;=k7mOwl z#%5uk=4+tjb7=uVNxb4v6EKH1vAaxhP*R4;Gt~it07|@SJ)m46psBW|d2#?~YK83+ z#aM`OcQ=8i07$MXl4R(=E-rW;0Umw@n1ujn7Z(iprx4oQASLS573IiHIt%4SWfDt= z1S7e@M;it`pi`oN=U)Wl`Nw7wqdwYAx`~F92-Xu(j$QaM406B=|F{7^JUKd06!ot) z>+{FW`z!Sp_>zo73C)BJfk?*F3MgSyaZJKE_Q8-E2{2d8Ll;rtoCXF?9dqdK1j?F> z98BX5E`bm3@$VupiIHy*llcNN3iPhkrJ3>dH7-$lYOLa?YS^Z^1|@JRql%=$PX zFahvM>i*zUBiI}O&jl^`k^tzvI~OWP!q`Tf>Tmi@QIJoA`RJ(p2ms{0-*|XXR4yAr zo&h)nvB_*mQwBme2n-iortl-BA;GxBzJZn!ngSrUC_qjeFtku^yno_8r=}I^o1tsBwA(y;J+X4o?n6}V7Un0_ z0}l^?W@U?(g~7Srfp_Kdj(d0VcfZo6(wOF(pg90i><=D2ga9y~8KqB`?a3pYmWXNK z*tpMsbp4t3=uQ;dbPJF55dP1={=65RC1<_>a|yLPNf5Q%UL4!_$%Si2}UPL-KD65!Jn}q0R__6J@3=a%G2{5gf!y(#;$V4Oh&j z?=`f;yyKnt;XMe`4Zb!4_l!v@k+-JOq^k0L9<|>qxZD1u{XP<5_X{yCywiQdD#&?U zF+axNTa>rq^~bxJYjyT?9n}qzNoHEvW!^fknwA!rXX#YW zv~9jXCpMX{ACcfAGe}}eaYxrGC7`;uQ~WuiZiy$W-TVQm|ESpZq2(1{`N8qNW+XlS zGg$}d!-g+JybXpaRLnkSu9kdM)J~97*;zUwWm?bP(3v%6DfRHP_f0(3{#i!TWRe*C zGuivIe__w+=t*k!kLK3v(JF_3WiOyeNKnM-q}WZwDHjRKZ4XCPX~3=%HmU+G^G~L> z=s%g-*o^=Gj!svQ_6C?hn`@0j@*|Z?tT>Amg34m#F7t{!S5RFk&q2Np@_;=hXAU&B zNHu(RH@oUuIJ?6A&TAermBl0kx8^#J-K-wE*U;0z$Ih%}wN}`QF*=W!Pi$RC;Zc(} zK6}$vumLs*Qw7{~qZzg4o?O1qom|OAL)VFTFH)4aP5D^ycv;aZTIIKNJY{Y9lbUVzP4;|7 z%4+9Su2_1~_+*qMAPYriVX7?Z@M~jQD3?9of%O3q)HG{_y$5C-JO2e1Puvl{1RtlulIyjb}G_ zKG#3`8QjY--u?K*$#dh{t0Fg|*4Oz4rC-CV{mX1Tzg_HJ_)7AIM6w(AJxM%plkXG9 zWS&#F6$kH>=6^i>{8}l^mEoBI=!1!ORGN=Dq)V>SREQUpM@6L4mfU#uE;0C|QNFC| z>N7EJ<8<%O2%!fQDqTtAR_A`6c=CQ6F8<)o_eLo<8k)_Vq9u7Zj87vum3{S7yA8YE z2QlM-qXvO5o2Hk=o*7c%#_wp^n=$9}eq|hr7r4myhHUPy&=V>%+S`6APjkzz{3 z!v(l7jXFng->m_AgcBPk0R<&kx*30NvHE-qk{ z7~z-S61fjX`z{#rsNFFrO2WFPv6c$jzNvCNYXd`BN^Q>o6)DzILasi;5rm-&;5D_t za&->K20*PyR0uyULRW4#(1Cas2^s3}V6{^V3Y7+cd6>801^~p+C)^%%8QIMMkcWE8 z=>f{f=#ilTumud!=_@X<11<)O763Az3-2QgUH6pG2Leo><_T5zgnCqDS04cjX0Ze| z0HCD7bkz!O1i-A8pfUJ)_)=A9zy9LFi^vfu$2W*-vUGc zoJQwzP~?Kq%+!qd3g8a_sHdZgzDrHYB@aHFEzuAR#b|RH;R1FcHY#vxSu%_eb^TkB zjagp*uE<7{Q$tGo^W%WEbAok$2m{AE#=HddU?_?(q(&0tBZLc7b{iGwPq4lJt4kDn z3dUME6}wA=-^c~3)Q#j4JkNRnu?JWS5+nypW5i;qUXl1qgs(9KGNH+!Chq?b$iPIw zcd0Q2KOYBp5CG(aDFGQ2&8K3uk=W1&9{4nO1Qq7MMk}*HV-)^(J9s8AwiD!IP`A{U zRNkj8f9v!_xM*$eQE2^2!FgzbT3z5Vg=?WT`$ju?pR5K^&9+Y0%^bV~I*rSDDsOF% zacBwo-O@5fILHq6;SaeOmz8?(w>zxH+784wuhsFWteVf&z{tFFAkLd4Zba<@7VRbW zW_lBZ(W?QpUD`R)eYof68uBdS(~DY0mOPG)IIh3U8N1)n`;*}E5pEQ#5Lxr4Ny=CICgq((E_*3u1)Noj zq$--(qvQ9Go7~k(FGE};rH+~;_7YIb_$Zri-J-}2%_lN$cw8m_^z3~CC6ms;%YyIK z-+(NpCB9sb;9 z$5KK$?n1YRewe_?AN|-#xPTCpmx?Q6nb1-A)*G=KK{e}LFmynZx_65SzAj!FB}qt< za`Hf8Q<|9A<@$JipY3_lcnT878ds*V9Ypp|o*Y`{83y|sh6}EI{ritq(@Hz^Ny4@y z?62)Utac3cqP}b3xuYlFp;Rcu_5j{FpIP-5H*ELYxI@x6c!&gYO0$7S;m@CU7o@LC zOn;7KcqO;NY!{rqX$?He{xID<^Tgvr?hz?v*<3-t4pOrCIww=3Wc+9^$ zhOIM4)sjnpOccZKFK<11?k%NZkrEUC%c@*gP|!FA(eONVw(3j2;AXl}=U_~^eyLSn z)lDVs*v;I*lM|2cvoAw5s;)Gpm`vgFW9GIeYKc<>SgF!TqEGwkOVgX zAUGO{y z-}`l6tAdC31XlqN0jeZ%XjYog zS&%e|Wu-xnurIUtlCT2MUgirf6Fx4ma{!RWUvMKKT!2)^sCIproF5p1r?vv%jKL-s zhyd9D$e}TqDir<_wB?M?B{l$UZxCP%N7Ru~7|+BP&=!UNtkBCbAoOs9yyZlPP>zB& zU!V!c(v#14R9HEuFLRH9nTRQmfz%CGV*2-1GQVs+#8x6_3#60=Dy=TX z8q36xl8E6`!uRJ_ejcs5NSujLiFxMulJnY)j?RQaw+nW&kOD1lg)BZG z`31e6W$^gMK2CLm|A=$Pqiir&~(l>5|Y-Y;%zI&e~Car%ClZ**$lhgHwUP2xNJ=GHhG4|J6| ze+2YNN&D%|)x#6#Tc0b!e%|Ht58f4Uvv-N-U)mFX99K@Bd~ct0YB#)K`BKEf;ztaeYB}g$Kx67dXk!#B4QOX|Gie;K@M@vud)W?U*iB;X&EaFq8x9Kuhtg68^AnO8u6N1t>sovQC>j!u5`DN^{M1vJNMiXHgaB?ie*h69*TQOADLUkCd4FUKJ*LiaiWFN_QHYAg$8IUeW`0120c;lR-J z;H>pvuYpZBL@L#v^@hMv=`*s_wD7w?1D}%QqPQb4YmPDyfx>@hTWq~8l@2&@9jSSZ zl0CyCvckoyL&x{XbMuBBk^f1Mq&&6OmC$##+)?SOg)DL^VC~b@;1h z{#EBi$*B4E{_6@x>YfENzou7L*c}VY%8G~Xtc=}06F1;2^4rlc$kp}|k)zRN($5Ov za3>u|!Mq_$r2Vv+WEB5ub6-#!Q>1zO;%7~zKmr_Je9zu(`1ZwVb(&amooDxM`%8D@ zT_|c?xDV40Y9)i*eRlz2CfDoQ!;<>rg6-KI`_%=D7|~a5w+##IGNu)pIlS9{=Uv1j zlziY_vW%e})ph0160=rgz6sJ`!?gODI9igE|UZp#NzWWP(@x-_Bu%KV9S z0u6!0pGY#E+YLrdQt|x1E>G;zd1qG~B&K zoF=;BcPs)K{=AnJ5{q$u=zXJqvTz^C;oR&)%B3~yEgke`^|qQezPjHL<>$~ODayR= z7}h$CCpQVEs+RXn0VRTpy$X?%vDf@}9wS^kcJagBu`bvTS1q$Qx!N8Z+z-|mzcz$D zzFe{#&KM&S+Ext5PkMXroX(#4nG@cR(yxAL**}lyz{hzaxU@@Pb)o9IV^8v4TpOQR4Y{8X0xCid?@tC)*VrYDfgoc-T-iEyz?RbrD!>r-c& zY&V-)sgvBTkk2M;jj1Nr;^%dDP4?2BP^RAJSvdMj*`P|><(z@BLJ#I30Mf)6=LY8Z z@S|@}=RW>aWj>ir|^C`+c04sPMkPLt{ zet@3};Re+ZMot&sB~Ag!#;4Iz)cKeg3-Q$T&^(EEh^dkA!~+%yHYpaFh(|09MSF5y z2mlk{1c(Me<_X~HK+ut)f&c=$V4ye$07)C#9|TTQ!MIRPBSZK}glSM%2zc)f3GmR^ z%P5_B4uL0$_n6BCJmFg-9$X<{j-eRq&~-2WWIQH;E&{b@SrZ61Dq`Hx_WQgy=s^(lfR0E2KP^_pAA!aIXbbT@ zF0nuQ#hA^@f{=gx8o)xtdK8*Lj{r#V5d3ZkY!`Hi%Id~OeM*2V0L)$jWrKb&2d*xx z4T@pa1@R8V6%O!2VM803LqEMZ@F%%cz=Qtx=w`59UDR@! zre6UYB1doo0Okg3AnfN7uor{CRRH7(_zx6)#93!OxZDXY10dGxNygB1IUV7ENBFcN zXDuA+hl+k77^%S3(}65c1yVq{KorV|g_|(v1Nh9pPfrpBK|0K!#~#XvtZ;{Zg}|JE z2>C29GGjq^07%m;;u;7S84!US`uLd+{Hh#SzZy7m2b(zm6TBh-GUzOc2oy#KM4&k~ zvAL_O;I9Cfw@e0qL`Sr+^I{%!1AzV`90&Bmxt{!X1@y9wjRK-L9x;2e79aDNrN_4H+Dz6+h zPN2T#VfAA)HA?(lq)*^ADT$VcpWuRyZh>D4IKEMFbfwMXpyCJFBOTy=@h7*BWl z)6%=U*Q%H7+bUK1GJ^vtqs~Y771Rf%(tD)4*L!Lc>Bc7f%3!s2H?iO2igG4o*tkOZ zK&njqsq}bIxEIGuKRTXwQ@o1@*QZJDEi_V06|(hcn^5$#xn0D&MZT?T*;29skF~vh zSE-5Wy@9v**XP5Loh1&_tsQ5S^tZ@sih50M-;#UzOWl@3z7X*)(|)$|(WMQ+v0tv; zc2{2EaDN#~B)3~s%F+H#W$yU#WwR0&S+rRFB7JG&DO-N^cPNuHkJN-}_;3OW73D1ufQr`-ho7>?40a(S3aU{@l%vHU*Y~ zMxT?#sjBmN3v-e?Q#&~kJ39u9sw3X|rCal{+Agf|m+6gCX8y1d4%9vUa-BAzk#@=4 zb}T-jBJF#w^Ra8^yRf^nK6n%NugG6#IV+z*K}h+&*)*@&`p4ajsI#h;mW_80D!bu7 zCrs|~1|5ZHg%%Tv2Au5r2IGBvkmItZGIo z?V0urV@zju%FDl*jK+j)Hwt)u*w-|#Y2cgq@&+l>U`A?fz1UG{UV@9J zt|XD_RQOUcj}e*c6L?C=Uh)-UOOm@?bxjsK|llnDE2&JE~?^xj1v9;JfBVEgz{s9sK0@ziAR+Q*LC^-$0-O zRPGVh6#$YUus+|@o%)N9cqUv>&{Tx9$u}0vE*x-}FP=7xMLQmt zn}H??0P_<7JwLfn(SAp-Z}<3sgnxGQz|6*YU@CwF0OZxHMAx9OU@*};x&cvX4UhnU zSnI~U%S8#E!QQBVP6SB!jD1|-&6dJQmc;F8#oG)m~gxo6Ec-_-a{v7tiLp1NW)KuXl+TYqU@ z1!s>`!#BLFovl&XJ0i~x+TeR$os&jjMs#kJt}p4%o*mO7|DbSvWWdMwY)9{-Sys+F zLD>&Fq{Uv`73uQKO!cK?6?ybP-yYP*hn+TCEBs6%V{k@a1Ap~I!Qb=jqe0a^y6rmpcPT48u$RO!egGiM8z z6UC4a#Fg&>w$HvXy8y&c(GOP7W`*UyOM{Rys(d?C-&o1+&xyFV|<^eQ=5qrj=E3+`*y zC;DaU(Y?jcVPx%Mx*9F~z{ptcPvU~CQUak>YyaEC*SD3TezmA{->h7aDkHwyw40I# zkCW8aFPYoz`6XwZFSGKngMF>SojH3ihSKrf2hT?>Yn87{K949{3Bd&vHNOW24hDoT z?_|H|IWIh!(?_Bcntrvz=xUaAP%PAdfOcw?qsvXcoYV!T>Vh}*jtd$&{0@_$my7ADJ%cMt+BdcM9wm^xvAE# zh(MjKrlE^ob@CezUTI#lMRbWKt+f&6dO6M29IiKu)4=J7a_oQc>Gf%-RY=4Y0)WEy|K(0PM zD+z^ZfXfP`V0vqU%K!*7Qm7Jo(pNPD+wpYLca`D_z|25fetvKU>J!iw0C9sKwu2_p zUVTMOgIIfmkB5Jnw1RfNs(~AHn8CbN12+I5oS1R8U|`#h=%NH&Qi7`hD2+mgAf$ql zqMd8wsAH;5oomoIf(uYCXE1qd=0&YhjOeG@29TU%qhtsm1_1e{03Q&dqsr9&pXXU& zEHiAK8ivkX475G@_@%BED3HlhD+9>I?Ay-+xd6xtBghbx3w$V}&HSiaH^DQ!I?YQ0 zp;(ORg#CKRxff?`Auw+6hE)jQ13wEy03gQ^#Q0DyU@QNh!X8jThpmb`C8tJzIn=MU z_vhcBCgu!7!L73rP&7N%br;~a_^T8MOJWIJ=|(qX6e>|{hNmA2but1*sh)a2`n*U+ zAY89O+w?}Yr;Fg_Td{#^U~*$${s(w+07O?Oj2bXYldMCzUVt0)UozyDgBzByUjP-W z#B4rl!3_XN#0bd`C>JWO%zN>Gn;txe%BlYmXm^ZbHWjo5K<_X>u_j^k++!M87M-73U2Y+ir9dZE!e**vkT1Er`0|_0R2XypJlT+t5SVB%? zksv4hbfZB4+N1CvOR*pplMtd>)D_fdHhWIjd}dJj(Xip$tnM_i!bubFmzsj?BvHJ9 zH9_H5p2?J#;W>`@nJTyR;1nxRtJsMp4;dd7&F8wX!=rr1ehxX-BpX8xtJPiN?xo$E z!o~Yz`LU5OF_hHg_`UxxsV|x@@*wnOHC-9V;xYXuD*XFrJX?jsZc*?mvzo5$GBJNo zZ(r>EO;h(Atoaye>YJ>u=sFIjFV z@O#x-%u~QyC(U~M^=)tjs67VNngXlldbLE|TWrNQPjZSchTE7Fnk@R7*)kjxxt!-W z{b+7a$V14}9Lx)MXuvP`dlFc}zvvQ)+m-#ChudE+Os7%-_bhSnH~I~?c$|3H%qYcJ zV!Ix$Ndxt)l=wQ{ec4R!ush~&Xm%NkBvU;Sg3XWN;`NV&iHzFS-<3_UtmaKgvA9pq z-#1`5cQSasGXN@Sujrkm8uI?kQ1p52kQx8yP4M5b{)o+l+n3#Pns0r{8GoZOByM9m zH4`jWpg-Sr@0dDRa@a3lN+-o?ll3@_`X=gDTlLx8jRZqSYn^f`qmkuWxMDuiq>Px> z&A58T-K9I!!~C{fQIF{456zRh(jH4EXq7qlf=M_rr zU`02kqXzDG4ilHLj54NWrkeVn@W93*;1jON!462?Z^D;rg*i#k&@|Tea{>sdc=O_92C^Jwa%z! z{qlWsD>j&qCAcOEk$RA=<++B)jnF+MNP|HNh|J_K8)!!iH5(jy@~j{`uqE zP^&~$dZ35qlc!ZU^d%YmzIcbmnQWgRZSwr}0rIRPtF{FSM*rq*Ha0 zWw$f@%gI_QePHdhA}7_Wx=XjVi1BaqiGst||24irMyL^dyE!8W=*FGXY!i^1fmw7) z@xa5E0+qHfkHY|$aHSzOp=LPPw!>XCW+%d}U!5?vZ(1%Wi_*Wkrb)eYvn2M9QD%Hv z-X+2Z5lXhkj$BdP-qA~u1Mb{I4$G>M3VeLEdz)>)o~8(M&H~lTMJ-mMucf5k| zH>LkAQ(Bre@(jtf{QIPoRogUW-m)?3O+nIiYBZTu0!Ddc6hgyOG_pbOzkVvws`7lk zW(bd16nmL`9S6?b$gBGG+zVrZu9rnM^p>Mt1sZ0)sq5Cqp9Z@6C?3!HiTn5#svgZy z6nVeU`z~_Qd@F6 zTm!t2@gbtam-ww-16eoUbUt3d`>;ZkQOBY3c`w$pxn7r#7~c9$dn;z)m|z*sh*SDj zVE$O2FZ`P4ruWhopW_5Ujh$O-{47=CuNI3@&wSl(JA?2ryExI#gDx@hrnztE$hYslOXJt5O}quHE39}Ac3 zY|+~Iy>EycJ_DCdDM`aqu;cloeDb)jD93wmv-GE_;&zX+@Mo#LSHvvkhtW(+k86I4 z6l~i(tQa+-`m$-<@TqM<{_P`N*Y}YWk)~R{7Suhzeg+)>EUlj2xuDfw{y2Hj>wPxc z7>q|VR?-GCJQ!|r%`<1mkyoPrS)0PP?2q_kR%4l_u?s1CLVx92qO#ko7Oww7f?<1V zFMz-W*6nth-9Gz)v>VEe8sb|E)Q4**+X9>xikhF`U}j;gPX-Kc)DTCWMM4NMdp_G~ z5DTsbmjRGr(-4pk23Bjtl^|gHVb^7(Wf0T{!hH{jetVILeGiB}0hR?ywAjCg*jND> z07x|=2o)3^mNxnTw8}709{@<-4 zlLFgPbdcEN)!8@b1LOL*ZcgB9SSXRP1b>*Is{w=Ks;_Gp+hp(LyVzlHzYeR_!~A0AEC?(nMHB6 zMi;m<;zxoT07^RDL3CRleBJ+Y7okj7Opm7tb!g+*7P|KODI@+%a63RW$J485tH1qg zsRD}47WLbpMi3|?JY{hH%j##K&BezXKE8PwH2hb8n}e4?zaVBzxB}4tm>2x#L=}uO zuLi>o0OM~)h4#^`NSH;+3)}~Qz7L)a-bktqv5^c0!8{mt=ur&@fiT8k-UDq>_>XD2 z+*7a702nX2hVG2^1X%0f(v-El^$jo}+RkBR>n%xTv*-a+mbKAPEzk=&$p6Ypk=>t% zVsz|%b2w+y(kGtPhu1xa+B@1F!q04c<&2O+{R3w(IPQ~)6EzWJc2Z5NZD2lU24AUq z0(neBbl}et@-fNjKq9(Sw5#pq^H=6uk8o`o7t(x_ z3$sdfhV-I_7hftG6pBCm=E2i4+RkJBx#>pu=iCNq$M$<&B#$M>hMTANSg4Nz?Si9n zE0WB%$td?euee#b(hp#y=?co^RkOD39lN9IbErNZ)b*iXj+c>vsgrlZ+Nvu?1Ax!WA+MzrpyKZ_=BBCvZC6O>0G%DZ^20VM;}O;V$YU-gIe?7fU)pO@@&Ov;mIk#E7muK8DA*PRiy;x z`d^xh3$_EUrc{7k-f2c{T?IiA46WuU05vkA<`Sr2`JYrLKQI;zE`kEv(-h*T7xAOf z6cND?iHpl%6s`cv1U)lQwIP_1eo7JH?o5OaMIRZ;Y7HJG7(6@xN|n$e?^&Y`8q^2k z2MfWb)*Ac`0C7-AT)_>LkC9|~t)VXy5Q+)l!4tt{0Hj3%zBeY=<>Hf}iwaiQ1JP)go$zVt)oHM6=P5A= zR{S%6FgEd-2VmTxhzhrG*|TXhNAzH#E7-6uhFA-0@6A;bgEKgUKq;~l17qo!U+;4WGvvN1GAbb5f1)VPPp}tP8Ofx znt8e!w`5r)@f|C8&Al4BeID=!r;nd_D;F{*SG

+{7iRjvCmx^Y?It$a;;RU%aQSKrJl2^MI-+%sXLeBE}aM zu3xU5@M76h73Gwd;hL2i~Kt{vkhAeLzd~>b}*9;Q}}g-IX^R}>Ok|z z9*Q@f?aEyS5qU+BmVJ%Ex?VOB*R!T?D^i&2(;W&s%zO2``bAaX`{Ru*wa3jpayrje z+^0;M#{E~KX9_15Wgx!czVWtBrOD&cw`5%DzjmzZ)m^mrw9UHB%iv1j|NHh@otItd z4PEEA+mIB+tltCEQ!8l(?;c(#;&~&V`TIaqLf{H#-w<7UAYNj+VEa4P>yK}S3st<| ztmrq}`ePgVJH_q9$lg%y_%BvqRHo+IYcTEf!H@w!P(|ZwpcM=%Q4<@Dh>KoLN zuR=a&uAG1wi3e)@P{U6gDr{311OyT@Q_V2dK{W7$*%b3j>LFm zDoNI2-t>Fv*}b|iN0RIe3qRt#4yECozR)I`rDj$6`n~thRM#J8;YSikyrC$Z@A*PW zWU(#Yx>pJ@R&;@sq)`=Wp6Nq?3;v zl_fW94_eDT@5vfIpz_mcj(587NmZgLyScnhS*nCcOeDy@mSGM5nA9S}bVYHi1U}+p zx?_vqtGK(vC((NM;K5V_f31!jbb-o`wumcTUebLUIeIk{>BM^AY-}{`5GWurn{bnM z|9P_n&nKksbLq5d`xlA!aM~9mjr&T*`}_WkH%@wKN);j+OPQ&Cd`+G^=g)5Pjgp=# zq9^LxUd*QCEM;rvb+G&?S;4H3aD1)Y?%-$1-Jt_EC*@^R^?IstTuFMjHs!snvG?%r z_7=z|3*Q7*zP6>ppNOnZE4azO+XGa>DI159{~B7riHNw=1+;E07$^Wp?JkHl6zxQQ z<^p^IfBBE85l9!Jn_Q^K&3|(|QKXg_SE4%*1Ax+z*tAvDa=K6n;?}1_7p*>7tB6(5 z$-p4t7aX08G3CyIn*lH?8g&$)^gVDN_7p&*;XUF@P_Bodd(qB0T0Jo4Pgi;1d&aJB za3BEyc_9>Lk2wXWWATHDfx2p)X}286 zj*3S5GnhC^OqP+3{pxGK2a^c*Sw8JARqgyq-bpz#adzT@{6VWR9Z71@)6&qC*$2MY zQd4HV2MUQa;r*n0%-XnmA2%YKEFlTx zJJP*ZEExudoYLm4EA1vE3@g}KXIbimKPSJOxpENa6jw4>@s`n4 ztD$r0v+2?7Y{2RVW{GX-_|n*?O?&Kev&4+v#tq~KKjB|H#D!m6*YoO3G~T&)@pt!Q zk%~c?y*w>%!`os87t*C4-WsrY-g1eYR20uAg>pRMS!88-n$6)cx0nU{?Uk-O?AiEN z$n}VdKJO=fl_u)#N#i*wF@XljB{sfGW{e;mQ#UAy*m%!<>(KNpLJ( z_{)aA7+&awUs-!;KDcA71t;DTI%{7%hv@jc8}*@rmg%wef}Zcr1sYN%bME_k3fY23 zY|kU6_tigXH*3q@d{A5QNXFlzu|8nnZ0yIM0GVr{bedo)90*+HNKn(HG(WjN}X-5ho3I#_R$x7RBNFq$UMpw z`|h*4(tS^jN-^b6YyJ~li{JGivhA9ZTWu)oj6yqj)u&9FQ696U!e*R68*8{^LvTgt=M**)3?u zfJc=60hdFv%7u<|$A!rmbI$C(S)1R^@gzJ-e|hX){EFB1>WbFUU+xYt#f{YD>nPQr zh=5RH>VIZ>N+_`flnZb)8eJ806WIaA)oDNkI5@C;jtOA)0>s@WItK?+_tCUy?7b>_ zoZmKUW>ty3&C0bzMxQm4G|1%lX%b?HEnK86+p$?~uZdKP z(R2XW;yHiBxtoR;%vNvE^5?WaSAL!evxgQk z6;Ihej&if<JJd#pA+` zqE26#IDgM3CG_4B6kHV1o$1bHiVC$`z_jpOUbgz*ieyZQ5gO5*d+pdW;U5v^nG>H~C%>P#UVakqJv>5h)72 z8N7?9s&1L|`(ciD0{eaVG|wnr+W)9z^gui#sN7lC4|-FoSIl1OwnEJmJrl6Vz=Cjxjg5fB*ng3JW!Y zzW~aB&RoQ8-=;x=w+{VxmnwyMYwRu+v0n!5hOvVVpAEu5kqBmUd<6Oh0KrT?bYXiW zYk76)-#a^0VLPVZtDs*L{$pBeM^`(Hs8I)YX5ukiA(WWzxN)}off>H7;$^=ZBTKfQ zuM^r<*0E_-v_8q9KHs2APp9PZ^4Aq3JYCTTZ;9o+uZ{3s@=cQ6nN5OgJ{SHZ|L5aN z;SVLmtJQOif>QRDpU#-bYd+b~6Jo7aF}xURkYC}lLGFE{)P}!;W#|KrVRd|=;?&Kr z^jTjM1@-TIISl;M`_(+$QMMA|t4rogv zE~Z6m~(=B2V?zDm=MSfW|t(~ zT<+M?Rv%7r_Q4b!5h+n=fqEZ&A%M3)LQ+^i0B;U&!dP-YJKMwnBuIHFOBzozW;NGcywp7@WJQ^F?*$q zvfb)8dN<=|+Y&S*5f?>Bx-H@sTyw_!`2BYBje%B^kEz<*wKK4NqYU-}ubpY6;5o>a>l=P%dA?d4NR zxCRDi_fxXwU(W>J!}s)_370D>X`lARJ)DfFDosr;&t_8m{LwKgb=zlOuwV7)YFmHs)o*{{ij?i1yf~mfx|fd zPl7S9DzFL0F+c_YCczk`kO<6y5UfH%UNXnAhHwFPIislu-W8}!xzim8csp$NivW-S zfb91o2AOhEKm@TnV3q9#mjMuh?xcL6APg|SCIgL%RU^pBWSA)qI`=uOu;kDk2u6in zQ16T?TfuCO6oCW)B)%9?6!ib;o(CCd|EYIJyTwpP3#ebEC)WYL#yVCbii(|9-lqVu z0Ep-9FgEybjE5w|kx7o4eNuewx>_~8)~B=21|}e(^@$Xmns&d$zqP|4RW_Df#_nYd z847+U4|Woh4^Nf^>S}8SrfCJdxyR?ydm=Se-r})L;^LaoOR`@oW$q$)Cp}9a=F;_I zjUe26c5(t5T@}}F@QboLzvE#r!OAE7ST3pA;+t3DQAq|=Z*;oG=|4Q0O=DYTd!n2& z@|Bd@tg1F{?}y$)Ii^U_6Lj8^9gIn~hW@eH)e14%5 zOL}mztg-8qB+N9#_M5~UaEQqb{JV7b#MKU{q5JiS#O|HmUDLgzGq*H^*jSR*z3d`t zeCpvJcZGkm)LG@Om6Z8PpM-ps{bx-+1GdTNNJK0fpgQ*e9~l5MX|TRgMtl&m`6p}x z_XfXGmRHu!OYkdgoyOe6z?{J>T<<|!6#lc|WX7PQ6G4*N)^aa$tu&)c@Yf;Ff3y7& z-#=Sz*ybK`+&Xt(({f6RWTN@xS-h>e-?HpQXjFkKCLxXu-| z>#$$Jbox=SoVy&)V)-cVMNI@(+`BBN^i(UyTfSal!x%=t+*dvkKJk{@a_b`HUg)lm zHb=eE;{{XbxVN5jo9q8a+gAoe)kOUZOM`SbBA_B74U&R_N|!W9gS2$6L5rlYB8{Y= zfPhPP2`C}b-60^|@Sk0l=kfo%@7MRk@5A1ioqO-hoipd0Ip;SU&n;#Re1w7RHznq| zN02fha2i=O5I?>v>~2@rA9)BqA+lP_dxzem(O2sA`8tB5SVP_R<+swg=KVJr zlHLrAiG2K^sVs5Renc8?KubtDN*>**@GM=PWBT%3y)bJ_jQA4H`V(4 zi;#`$TxNXlm#b6%DU)6H8}SYH`$C>?vPWBc zS5JNL_?L5f8%4uuO1!9ly_G-3Q?Ru#}>yC>aycg@$F2-H_Vln=>>myTsk!+mC|vR(Qt2pKP+FJA5noBm*P?ULx(n5hmP=15x3gNz8SV+ z$r~k5?Ue`=@NgCk{Pkg$#D(8Dg!UQE?DhF;x)yUEhGhBzpBtHm%L-cT5^GynW*-;4 zr}-YXQ9rrTe|OvAV_x1$-u-Q6qD^KZ>9=7#y2s>%k`^NC`|wuz8#fDz@~N4UYromm zKOqyrF7Vq;Gn@B;aa!_0)9DYbPJ+(tyl-#EXTrs-wO6yZ-3m@a4RRNHPO*QjsxNje zMkk`dj%duMM0(_(^^HY1R*Ut-?yGP3+#$?P3==s!^>^KTclC=$=LFfK4Hoz-t|f~j zrRhev`O(rE$8lMpqC3l<-IT_g3f@X)K{_o72^kBaHuK>u1wU@gLB%o6WsbG%ysJaz zW@BwUZyk!I8R;5^_>Qu1dkJ=!n54;(Hfp{zzdpuJ*uG7z8W-pkxL{TraOOPC^o3X{ zx;^b~fBPT!nBO$h41;dolgjRsv%u%2B?*uB2juQ0c-)lsW~bzXS$ zIA!IqYQTvXRN?hlVroK&TZ5Bs8Y}ZInMabz25$I^y7KnkV>zYH$GHC)rc4lwyVuD?j){E znk<##NyO63s0J7d%zKw)oV--#HCVQ}G8zh-9b;Ohx>~>I6T4W@y%LkDA zaa-Ey-8$C-3ET}f9V-CVImaiN5|f#R1jPkm=ac7E4BSsq%MeEe)&svr?_ zIPtQFO2Jdd+5+dd@ak_VZ>6ItJSycX-qDi}^p^3D&_`yHEx|Yz89x0|AA=GoYC#O4 zNeg*j4Uz>qsrD(7tPe{1L$9@d4SQA|&H?Xqw{kA3_x<{oL0HacV`PiWiK5kKt@+V( zUaWewg%d6GXRScA56`5$nDyskt=&0mOQQ0~ptO+Y zNx5(H$hdhZc{brc9X@CaKI8jWTwiec!6Youv9ZU1panQzs}XyZ;v-=D@nWyiXat)I z4awQKzk%kI4`#MC$ooU?`+;3nR6NNJXaWF6Y<-zL#;))STRfQA>8#ws_fVn$q1o{W zUO26%Ky?5(-a3IH8uB1f(G5C2M}!uLQrCdljyi}54s28e{<9P)#wg2=N>R6@JZuQh zdAIYlc|-f7hUAMO^%Gk0m9!;AGoC2QV_I)=&iqzJym+p3BhzXM3O6skhDdmqf*5}g zi{!j-%HDcnz6jB$wLPv@2%j&!Lam$R@Jf=iP9HCEP;f_j zUQ2R;IyM|G-niVE%y@W4?H1QTr!M;;DKl!1^-P5<{{9d0$DgiYI*Hq;XubZNp19w3 z9GYz8!f=oUgAHA(-@y0V6T`dz&^ydfNk1p+nfKyY=2f8usM1dQizI4}r@JlLtbj#U zqq=-OAm#hFy6v^g=*q5fdx;S{Oi^Z&N7Gj~RuyiT)xbobyU$iWww>L6dUwyFRkK=b zn^n1ZHMEWC%QczsDZDl#&$!5%korKeYbE=OCL7j{ABS$1UHv%bRJeFmj;29VFsE>h ze5S6s_ojJ!MJzPwi_Xu{B74Onm(QLBJ7a-11go0jPY&-GbS3J{R5u8)a;09+mNitc zZ7BLRVAjG>8|Y}=E!#Fym_METsuI_hxL1IxjwJOC&*Rp9u#zXT2H+reZ&5dgnv3FQ#+(Q2@9$@F_Q5oaP~LVSO}#Pagm-l6W~B z0?7xnP1F*QghN0^CjiXQ^0M*2>8|I>5NgN%e13X>f2fLrJkN8>G6OURa9)Opzj%)e z;tUGFRRDMuE+GkoT^GznkLy`(_rYAepjZPLraUN*k`1T~0FSN3GeTo~2`b~PS!Pav ziGE@0fgM)V5?&1I0>E~XF%OW@2T7lvdE5R~6D@aG9$F>9i0D$+VqwS)x1%lSeeC@aq zbm^EEw0FRkJooQag1P{u0R-LXP##d#f{gN31{fj2izH^SOLlJWGlHrJ{72xdzO8o{ zy+__M(WJ?4t5Vewa3i5_E>JCGw~eLOLN()aHVof0u zY{KhBpJX>Khw#zIk+JBRx0*mHvJG3Ax)MGGzoOM343?2RxLv!km9SS6U!-<9)2%PR zLZv^*{UyzDJ8OZsOBZ9VnrVGd#;P3K(_9=WBJN+sCV`j6YnIbKb(b+=i*)@^ea>WI zQ$mitTvn|5!*g74MSi1Y^F>MNmDtV^qsf@TT|YtHQodAgKRMf5DZ`JMp>1J(EwEbk z!V3QG{%OS_ZFNAjgUPqGwY17~$K+8mP0)^>HrH($ux+xGM-@!=JI$uB1r z!W#V|g(37E-)-Q|5Kr0WO^a5_K0294EMGW#e#U~YX#4XDc3kTO zU0~TSSGfEm>@v@N=5YVSE$&g54(!((o)lZOjXh0z{1m3Iu?_p?Z#>DYXCgjG{n=X7 zo?l`E)f@6omXdhoqSj|+U}nCizh;5UQIu8Dn^s9Xza3-{v8S}(|5Xy2OM>T585vT? zc7!Fm<4el!UCM9kt)t9aJEB{(w91OJlJjlDBS@nEwvUC8*qmBrjO32j+%5m7Z?pDC z6}ks5>uw*|meJb{={owUv#P+hRYNTd#hXa5<2DJ!zV^3NZPQ;ss9ya&8v`bqbVQ)uooGZWo;AV-MNsc(3rl`4v5DNMLF(J)Sr z*{H_&=(NSN?ZMmE>ymE--t*^*3P#J)3Eh3OL5X+c(W#t|40$;#{%<-sUcPm8-HI92 z;3>A@0s*WXrbmiSuhTilIeKD|)t0ll3|;jz)xQ3D{Dwh(xO}^Kh0hs>q0V=@>K>aV zrwzGT`4!#%UM}9x3y;+}KWD!_Sj_hjU)&WaJ%wu2G^}Xt@232#pMacr*zay&GosSp z;UN6?AsRA4N9h{~4gChDCjcA-dh($oBSuNq@yH2Lj(!xm(77au0Zk#6mFhqwv4n#Nrf(sxfV<-aYtop(;iu8vF2t_lwF<{2RLhMi1P`)*l39+E}SGOq=ht z%zhQ^)FooMohS#L+zMztc`1s+apqNEdHUq8xI!IKNM3rFT+>b?p6QAj%!$SuJHYl!q!k)%A3Tn!x6QgJdL-(&hd5pP?ulznj-;!v?x~8U3#vRnj!ot)yIpG{6-`a{@^}&>5 ziP!Q-;HCRlzqojBx1rxVBW{EOqIRnu9kdbUl1#q_3?}w%j}`{YA4i~D`x*xAJn#-= zjNmwMj#!YZs%^;>m2)TiwL_o1&7e#~uJH4(1s4(P$XGTwkq#D{c$CZreT-t$M5SB6 zf-=#okO4%1Kkc9Ri+`EZ?t?~ZV(`tY5GxjlAV+AWfRYnM9Uu*c8vsUIh}VzY=+P$m zW-J8kSeuIzKLJs}{}+M_Z)3q%#Xu5W6nKExx)#s^0KCTo=L;G#qy$Mm@EE4*mmx`1)Xt9)x$1?%^8{pjwE75`dVVN;0?+1e@oaN3~oLc#bJR5ddsN z5zQ9@x&~I{PDmaznT3u04wL|#f8o-gtL~g^Xo&j+o2;Kz%KK=~-GK5VHJeJwYGaf@QEw7`z%OIdz_e%} ziLJKplLBOGHYwAKq|LdFxNsKfKbKPVtvpHFIo0nKy`U1IB^ObPrcIhvq+nzx zd{a}1d*Y??+|O6FC0N@D=ewpc@hr=~r?lP7+QG=af0i@XATm*v!->|Ija zP-MAmifI)lW39pU@pUXKa*MjklaObRCCM`CaBnW~`Hc6{ckd}11zd+%&_@nJ<^7sO z#XI#3gZaphMUJ3sN8f%33ap%U&T*&vE3=Vuh>}K-xGUwKyeV^@zg06_Tz<2IR8ULL zKUS~*>ivoj9`HF?!)=~tRf)AFqi(p^iSaCD6t}!@u{#we&&(Iw$66_Z@ zj*fkj-MnBuodd%hVFiYGYq)yPx&6UG>H3JP2BP zTR*Ec?f3dx?c)1cogoa}&vTiatzG2<^Wg{{mIP2QqOrux5ucs&bB(F1^51iob9MSczAd~JjtA04@Z$Al%_aloYx)O&R_*L8Tbg6GUHVu|mx~{J z)w%Y+cXs8d2{*J~a%lf+=?DW8=VTvDoK`Ri0M2FOb#T?n1f3q65L^X-zcxYth>nZc zeYa7w>GX$5@#9cnvx7na*j*?lIH3JDL7;(dlr{a6J?o)(eD6yc8?rNKA7kaFg5Q;l z#+Rr$E!zB6Ao91#`C|*W?kK??ym~4VUEuV)$xWc}%Aa1|&;6w>w6}H&Jg_2NXkOuu zS3H*#c&}&j>zN6~la=l(XkQ5*We^Pt2NVBvewi=*T3}g?n2+IZd@`q7=kvfc=%A@| zpvdJ=ocWK@Sf1|%Fswy`7Q4hFosUwRB)D(RJqh?qDE9n12MC1$k;>=<@k|>J&>{}8QXlbK zLcVkDKhl|J0 zfKhs?aN0N?n;0&hv+rqMNH1g?*z{fE*HwQtSCK_QE~?8J27U{9pATa~{Tw}bLtZ=l zt0RIqPJPlJlAqKNYdKh?kshXhj;^Q!;|72jYI2y@O>Av8VNl=qW)_JpLPnzMBQ`P5 zjXo63HzIY29B%y(tf@$rC$J1sz=-|Pv9K>loP1SUQp8E6%K0w$M3ym%-UgG;5{2Je+QLm!3KbTQR&=d39%gMw`w;xa=EZDR znjXfE}G(vY8O7M9x7j8oP?#yKza5tRd*7foupTzM_)41J}r#cVFc6i=&MD((=WU z*4plg&NX9OjkX1!lzQ%k5wrc&?tW!vL9A#C5i7CpaH7-iVNAbyFyCI1&zSz$dR~DG zDoj$)nNlK@teB_sGk@0nTcX=wq#id%9d>dv0mIi=9llns$P>HBM&D2o<4+z=-#=bH zYS9pS>`)pu=RHZX>h-}g?9(o+*(u%UlYyhBc!Searnpe^fs)>a1Vbq86V*(CfyCw{`mGpFI;!V@l&_>cGpK5&Y$%j@kSdczROB)}O7Er-(bR}h|W^pB5#_pxU zG1z>hdaAF#tT-uJgTILzS2V@m99dSESfX703-XaA?B$ijb#Jl{tmr@HR32DUk~dcI z9)EOhWvA#&qh*0=_e?QTu9ST_Nx4409LFy6_2*KedX(n@8iPum16DlC-mLgeiDwBE z+jjh=!-BH=oQg#EH*LAn0PNFU)0@^s5}Wf!iJms18I`w*&5uG4%sJO`6ng$hM)g^f zyw5g!+lDSz(Hb2Id7~or@JT>-)x+pdIE_Zfp>`7s*k~p_CY;a{FG3a0`NDqR-c-naTcpLW6S)&Sy;nm<9l_ zr@OfIZ04Ztno~nO2$;tg=M(V)BHHs*JwH$t0Ok~oMh0)^#lypZl7K%rX9_DLxcD`| z10meki0nMnNqDI2y#LO#*xn)~^t&K!g`vzDw*`mmg_Lg<`nSuv+DC*E&-=;cJkS|m zME|BRQB2o*H+V?A>lhM1+rUd~A3xOK2;DQcTwwS9&?fuN< zGKA#NSGS1+i9*rSWjvpMTnn~hOe3v&c!Z_t?ystmTQEf;B6Em=X1by3sjP`Li1S9xEAv zg2mSkZ-c!Ry$5@CU^>f@|1D0#XtOVkAQ(Sp21?$r@GT0;XLxNd<1Bt>UT3&76tQDPbct%Qw#k1r+oYzHl z`Sp?XS0<6%KF24Lds;iTaz~24hypTgH!Nlwi7VrzCqf4M>2|L8*Q9$pl=2z|!$us7 zUR&cQ8vVOu1_2u-CF!4(=yN>?Y}&%C+CfU(5$I`vb7KRzG+?-hgBOaxRR9>L5w0v7 z2xinjHvQJQ3C8LaWl>0tF!{PN|DMg@c#3m(?1j;(`vJ2S zf`|}6Bt^u0!o>b3N&vaeW`dG2WniT4fTjVEUl`zP!G_VQ;Bg|wfMz1pW9zSbATlG) zze->59{_k(F7{zM%B%VIR1l-kr3pkij zsU66>2E!m$Na7n3ko!o;cmBo~Cj%iKmQ5Mlp$*H~M;kFmz;ceb128vH2Z?HeI{<*T zC}CnP`1(kHlE`b2?Q!8x(tAzNhol*2tN~Y1RE=<{8Ug_bl6ld38K|&bpcw$zYd{i> zJh%lozCaV;DgbgokwH~X(vu`@fAtD4|3%NEf~sI1~)_CKT3%m>WCvtwx0nN8WM3PRU(03BdKtNeOXg} zPHHN9US?<%ERlez6)5?JEn7v?vkRHxE7t1VFNN?7j!!&2g|eo@BtA6q&_a*PAg{@y z4yKC2WN?yoM?=|69?H7B8WA-w@QJsT_s{*Y-S^Igr*Riy}Ort$W_Gw+$vMDeUyf06qK zhw_f>%#zH+p?}u$Opt0xD*-eGD!f}Py(E94)8rRd_>}A2N|Sle#vGl@@h_u{CoC?* zm*`wxC8(!6&$awEOKj1k^uHtDVe+`3kBwDPz|<**t+U*igG)qkCJu-B_Nk089@AEQ6ORVMHc0NCjdoGhedI*0;#{vB`?08ST;_8T2} zWbl6}Tfxb^sEEp6;K2cq5tYd8H0#4U<7eO%FRTtez;AKxK|(zqd^rX;3=IO}P+@?N z^y2iszvE7k)K~c8!&@)^n$(~jR2=t(wG+vUK@PLRzzt?o1zk(tlI4sLjW1Bb2#7o3 zb8)8wUIzf4^^6dRMugzCVLFgV}|d3XY7NHM7D2`rN7C78{jGceBunx5{>OPc-(u1#PZaCJuZlkM@fA;P!|Ax0KwxuCs@CZ;GFx5 zV4WOh*>HZXAAxT09Q!IrACK9z#3Ul30%2g6ak8RD*YjdfLoYjF(BUU z19br|)*(DtQ85-LLkJ6X~!18pyl!bv70AN4((b=Honj!Z(KE2Fw3%FN%k7OQe z&P3@=)AZ0it^;b}>FNButJSix)r7e>=Nd@-BTbYv1l9U+()!|m&#bmYRpLML5A~Pw z#P)_J4{apCw@6vv?laqxFp%MDyvewI6w)!M`%R=d{s(M| zL=UDC`B=Stm}lcMZU1MDaNZ2lJ%Rma2pO7H06 z5Dk@Z&A>0r!?_pKmXJ8*NvG0?FT)l<@9}w4Y`Y9((k3Kw2YI-0(#aQ65LF#vLD{jl2T*w za?={+B(!0Gifn$^+ZGpiJ(wV~o8Vw0m$u6p(H?0uZ}>BuFou@>@vEQF$@^Ccb9xlS z%=q`q$rAUs+@z6ycqn{)!ufS3V6TZw2yH5_7YiW4WTz7XU zep5r+*6cA{Y2Lb>$+BDO0l6m9H!ifz%$$(2ieB-HQ5EWYdRL{SQuQ^_f=S&shBGl0 zed1UM9@-~IKZq+?HD+qwOFFmW6>28ICF2eZ-%RVS6R= z4Or%2G12Tucxq3C%SPa^J=k1C& z**j(mrRsgRQmf`Je?5M+sVCi2YdF?v9q z`U6JYjxl}GQp<8gjJH@M;vb$xd>EIftC#=EXNX}I1Z{D~m$Enav&CO(J6vz^T+zu1 zBfsJNKlgGD)Xbe5C(ViKfLNT{hKa=oJCx&81mM9VNZCl65mN zcL6?0*lu@Mras!~Lub~MrNET0b%U8<#WT>kt(q<-J9yl6K1Z&ZXDw{UBD8xyDdQh5 z5sLg2Qdj!=d)w>aS-X=~%T#Tj4An+0LCgW)(Z|n6Wx;3K`jXydZx7DmcJe+$NvNDi z&P@1uYfGX|SDzW4S+0ioc=?_Y{ks4n;;<5g!1^){COE)(6h0#T2q9ikAs!b=NC+j9 zT^`7ZNP+1VDj?UVP}UNNxwtq8TM@Jaa3PThD+{1&{aGM-!GUEmsM-s(y{wr)pimK<$jlzAOCa=51xctF;DHFjm7VuRsN1&^T zT|l{8@t7qt;!iXcBTMZg?5)|euGD9$ocwZ^iu$m0kJ`Q&cZhJmiO=nj)EW3n?G|-8 zl4Z#_NCs+)BY7ug5T7M#C`T=se>YenTd7uSEK0X@WHv0n=A}Z2%8@UP^9ub~>pX?u zS>Ta;Xtw)o$Jy0R|C!R~H7opYdq#qv1k&(9O+QUGhyMaJ5O z0-+(&o*Kindf@^Th6B{wgN{NuBQNZ!!Ex+xbX-KN@30y(@fytD2%8dm44OyaKi|}9 zpE%*m+kg-qn}@}iM97rjwlgk2AtB?(HynR(!mz3#j*y5+t7&Fd9{*vJS@9bos% z-wUd;3VhHA4!RsG?Sj;s=h1iDF!z@*WQC18osH9y6mX`}l%<=ks(unYWUH3#dbC6V zy;J*$yGSRhl;EjIk@^F6x>0VelgP%TIdfQI#6l4hPK}5l5Kf(hF3=g;r08;hHVbAe!av-FjB>4rf zQc+CR=XN_#sZkkz=U+EUi$-MlArl4dq8XAHj3+8zn z#6U!X`vSldZsW^A*dxKCR~RVwZK9e$XzU374OAE?$~uMLDJ394Lt2;T*@oxV@*(&# z0T9oERNQY304=Bkv=0DN8Ne7o((@Rx0PXQDxC#J!!Gc{4IRsrvpbf5;fd&BJx3sYh zAZ)ncS?GvwZ^FQ{G@}?^flm+BjlG~Q0IXXViv}7(f^Pi`&DfiJDmMTA=yR%v;+Di; z#+$|)ipZkG;COuAX!V^FzGiX1rQ1lqvt5dcTS<t=BO`x+WcZ7f zml{T~flG}%gDx!}h?pYKO91f3d;-$*qfUE-K{s8P_(-n=Ahp%sN;u(U0ljp5F{gPh zSkBu)3jnYOOn9P5E!P+ysIe$57w(Ub8Gz1?p!^94!V@0_Eo=a%57J6Q5G6n2g z0ATD91iNftt4;qhF6K{taHme-^hJtVaJTbM8@2yd-1piI0?7c1wkiod_BQxGK(PzS zA{vAr^atX2bV5`T5GyDI_}5ARd-NA4>0Q_gNKX+WW`T|v1Sb4NNz4Wz2hH7D0CvR! z=w5*HIf4+nMmZo{03~$cFLD4U=s5$(AUMnY+%`kWQRLSOqM2c6CP3z11TM3h;0dB3 z50{N^29xBX$0H|jC}BO#__x^sSCzh)w-rA<=rn|<4B2V_a)~|#?*(wNPUFF-5-_Qe zfh&&U;O$YIbAPY=5b(LfQs}`4(F5KE;Ji;javw7GBQ_En`-0T!yaX)zuzFH3!zRGJ z0AMqu7|(HOz;k7CSDFpNYLW>lp{SSquh<@oRkWqMPyT!&e=Iy!YR1vYYSea0gC-*@ zoB8Uam)9PQmZ?WUrh8vs57y9Jw7-$Yd@Hu>N)x+A1C5q&Y-CP)d%R+Ag^J2gG75ed ze0t{0USN|AjP1;LLg@<<*fl;%O?!&%!uhtK;|W6R-*5QM3s3r#>)UrGT)qbvUA?N( zB@yT9>i9aiamcy4j4wgq7nYhO+U1aB`yBi4^osEYDk<;{i&`H1;(5+&W6_)>QZ~Nc z!Z6AFNx_^~o_)RHnNz&O6Vqsp^uB!$`!HC)TI)YDNM8B=is8#g!Uw$$p>xlZPP}Ko zD?=|^Za7aV;SEGycjTZR?oZ5tHEEedy|{EarGcqPw|*qhh4d&!zAace#bL8|Wr%22 zTxqoOUVfF$zU58{Wzp6^*IbDAosxd}xPYg7h5Pq%9y;;5dp_zw<1N3#ofAt(<&74% zRx~!RY-QBcicebpQDet{`{Ya|KRw)oA)W?$$h|=o&vo=R}KClwDh;?Yuzf&U#bx9ao`68efGG6@?*1=-t>hrDn(Ybfqg- z0ENjaJEQxf^dCjqM*L6nzgp2pkyEQ?7eeQ)#9iI4@Zi02FsiJbY_R`q+}e{&B@dOH5MCRDX~=9Dt4`i-hL6wnWq`u+mb09S^EsCE%6mO1@qVm zqsp>GcNtryc8HaCUw$0PYS-!Ld}+~V_l6So9&b3!?c~lIlR0G2 z+5nlL-fZH_uo*(QS?$&2RQ~HMzJ>~?^>SCan*9ag27hivCK9r+IbrlZe4s+ATDI92 zG5d3-?i%|bOI=-Ws-lb9_>VCus=Eqbr*(;3pMFv^z$ZUA92p##XgT$=@iKm@t7jPy zd*gFNNA9LO-yA08vepE%U{1-}AF0~*VCd+ca_A`6=WCa)JGKy*@;Xr4;C^)1HDeSE z!`pxn7iKt((_5nDrRlF7*XXYi79`bW?GVsvxu-e3*3&pMn;tOnj2)&@%~1$|txeA! zW^onWW*bHy`dSNZ>fd&d7;&c*h!eUeXwaL$m41)>v$Oo&;6NV3~-(qI3ODRlJ}(jyTk>i8Fwc@jy1>_=otS z;jZ?_*ChuAQ;#-a=qlqf-7he1RGYsFNP124an$uzzJxf(@B(+SP+P)$?m<#z@BWaf zuYm@E-vZ;!o2@6fdsL4)&Tjifov9u}b&njHS@oG(@*L}r@(WePK6vCcL_IO_82+#( zapu#o|KfT@s=?Pg4xZ_+O7{=HXI}f-TK4p+>F*wSTN$N;PtEOFu**i4?uyxNk`v8R z&{a6&(@W~*&$-k;U@*?Q_gQ?+mwtZJkvXZ63cB2N~M_CZP>4ggZs2T z!xt=?srlTxX|7+*_j!03t(s?h|5drFH(XV|#L*)ncEU81=|zqDU6aGZ_t2VfQl7FJ z=8<}i7$+HNNi3;`vVI59&w2AR z&bf08G(?APj&yaY?s>NO}9$s1sG!nx!L)`Y~m zOXW|&uYY`$fCKQ{SC|Qw4*wn z3>ow_{eAM5Jg@h;u4IdbQ8=c>rE($l8*9;HEYjhpxb+EzFP-u88~YV-4wZ34lfUdf z@M2~3&sYCN%ZrUE{<^UK)g#$KT7B)M-0g+DWW~5k}s5tVT@IIjx*39sG z)j}baO@VJt9Gg%l^7zMRy1rXFRxPL7`dUU=&@hpEU(InfbErr7q*mS6EcW-cz9=@yN#5s;#AYx~x ziC#U2@zO+hDJvO5cDHwx`pL7mv7xRIsBN8-`_)9{*$=~Ersg;3uiB6~2-iEgaQvxK zyvYFlMJqrMy86|DYm@PYAXCW*#ej-O%#tVtn#c|YIoa|DYOT&~$JTW0(uwy)3U?^c z;%6mFEwP)GIJiHKcl-SDuXY&|n{PO4|HEUnW8V6OZ-!J$Z12&d`@dqhwh}Eyudkfl zg}FacxHsFDqAjHV8!z~Ipyp7^3Xi#ZSfGGH5tPk3ZlsBSKU0BFuUA&DSWul)!zAOA z=6a>icNLY7f=jd?i<~A$uo;b6vqbLD_-c-`pOP=+Xp#r9dS36er_xs+SZY2QGcu>f z`u!p}r$6BX{$>rH=*kHb5kxndVyAgU@~+E|Vx~IgiMi#>?lcvLW-ON3dCoH8iY#B~ z`hBSLIJR3n8Y#N-cn^d3bq~&$pME?23or*?;r#W?iR4sWhVrY? zSIq<^dy412UeQUX-8cQJ(-4v|;wZda`+M8*5AmxglfJ=UkpvQyV`0`+-CewFem!~L zQVDO>$EOOpsx$KMEB;xJ!Y9$b${V82(<1aP44RN&GozFX8+v2E@lALIGjO5Z;6vJH zrY(I(S%PZOq_$aq?O~oE!&tJMt}Kpbxjey$cA3)Ga*q@~>+$y*P7=n_|6awAG=jIc z)Age&L;ChxG0<-X?3QXRf!; zj^}l0YIkW2k6OP`>MrVh`{TJL0VBufD(RL!V{-jDS1fnK=e_W&eW6Zm+GEUry+YPt ze#w3l)uaQ{(F5hX2hj~E!zK{SF94+KNVtZ>f@Er*!Uj$xe^3Gdhv1+wK_I3;|D!bl z?g>wD82~0`f*Hb&;QNd$gY4~sc3pro1Zltly%e<}kpt=iz_^4URPeeZyaRLyC1{5m zVWRv7dM5z##ulcy>d1XkKQ*BKdVqfcAoWhR2jC8q3l&eF{UuGnZUQRK>H(+<02}&- z5r#a`7kar&d1rn!{U-P8Am-@JW- z`+3yHK9bZ`kt=a{#LubUEKwQ&c`>x4r^u~9@mMm8)D-y82#vW z5Kbcwy^Ag|YcMDH^zAK^!pjdwUoiU&EDEp$G+{4fu{;r&F2Plju}NU}kAi4t8)aRa zyejqP()H!Qw|tJzmxGdtJHMC=JAYnNZ51(k^_nG?qMCHHrCNB-LFz`%qd^rt^wC?; ziI*#v#u*M&9XD;;AdJgS-lQq4;Uwj}AD6m9CuxfK#l#J@B_9oyO<@;fC@ z9nLFNqmNB zd1&vrTHTM=H?&eXEb13QIRZlRnl+86GbKQJdYNcdF zH%q(vh1eK$g#3ePjO%yStTA$LmzL)-jPjio50A}$+w=#Fr9!`(jh1w+L9HCv`~q4J zaVcA>@R+VE9Yef}ZALynlz3;n;%0fk`h33PTmd9b#Jufr zf=Y5|i6$Ek$ft>`61@J`p0 zfdgETo6hS4k_DUKwJsDx;O#@*x)$6T04|4)P5^-@fF^v0fTL0cTn2!p4B-f~iGiob zWYm2Ha&0cv0U-QAAmIiTFvJh40>C6erYG!oIT~Pa1ohj*O8lKb-CXdtNdM7oBjI!Y z(iBi10J#F``4YGz zjb2LjgMI8F@xWN+?^Ro7>c+dY*lXcTe4XE0PpOy%p}r)}ad!14)Y_dz3WPcxEjkq~ zdoOxgX08>=HqClCpBgQ*q#3;5w2tK>qA@G{_^y&lz00@DsAXHH$E|H;4d0o{Nupx+ z*sc?IW@&J1VP>;#v)mHX;nIE4yVg)ie;*Mmj>mG}%Jf4F-rOD9>DK=meZT$MPdoHk zrmbwf%|WA-H`yV-0SzI!g1nJB&u*LKUo9dLNKW64z1 zQYiO%VdF0cIKn+kn|UW}417G_vB7>7ax8(Fa6XnOFBW`2`|=(-6tTqS-dfd&2bJFe zIv7Mm`{?E0ettaGVXJ-N4FUoe0dWR zRr^Bd3dUdpi8No~P>sh1Q=yi7adnc%pe_6)Kbe7lyz1Kv*h5RGVWxzkrmKy1-y+== zVTz~28+S0YH=~40PC|TK8E-F8_GetP_FB1Y71TQf5%e*kR45!|VBUx{33RO$kx}xPx-|QA*V}|na-+~ZoahO^OvRQ$dCWskw~g0H+%>TLD1{+!MW+M7HG1E3=~s(sws{ zS;?`+PTvvG7;LaZKU?Ps^)I&eDN)LJ_pEQ1=x@c|x?x^47a<_}n3=*#ORz+YHZ@`@*@CzC9>*FsR#gV>o7i(07gE(^2Q+-djJba4_(8zH8;qoj|1}68d$=0!|1U=j*0^ z_ubHiB~oz__16)Z=KAUo9o+tNyY#csli-LsBC|e;6vN|bo)kt+BiFKt@sEZ}TsUV~ zPI8gQihF0TgS|&*7~Rn-YyaASMCja((+1|(fap29h=fMy+~?vxhgBN`p>)Ho{L!V+ zkQ|Nc2VmpqA^?iy5Gx!VX>`Y4(ecbe$l{CC#eYru9>;vO#@oVAUfn1HkN$%6NPa z?f?J}VI{0bM@AmTzX9P`1>iCOVy!}D4{=@k_r^HZ^kRpH# z;B%iv3n&Em=a`wYk6@qd9=HeqANh!;jmZYgBYmYU#c{j8TL+}x=K(i=t&S8hyG_V5 zHgGJ1evsLY2pgzh0R|Gek^yes^ZKZ>8j$a*WP;6!d{@;gV6Wo*flxa&|2)uW7w90= z10nx}3~Ht6#(2oK`@fyh2qMPL184t=V`4i$$FcydxfkbH`jz8Q!Eg(4ej#(1m;Qhi z9Ywf@yb03=9wQqec#*)ItK692CE~zXqh17cO795xE&$-~?_x5cu_3n3VdLfrh!fFt zfwhRJ3zBY8VmTaiC;g6{rgUpBN_yfFMVMh5=ZrU%+JmL=zM+6$boJ2p{-|!7}K>E1(Df4qe7s`0Es= z!d1NgoWkS|I;AH?uo4l1aiMewfG_8KfYL!T05FUq2oD>0ZGADBr$Goy{-P=mII{En zqrm`G0l*FuHO!}&kO2pTr0Gu=s7%6c%Mnmv+kj#Kn35a;J2XnTu)*ldmeL#sdWP8% z_CDF7z2+Tj@hki!M2gF2&m*tFKg#q`1jXL!XzX$$6&>bRH2p)UD7pK3Vo&@m825lE z?)kbSfrBju6Xo3(#srtLORWB|apRrh-7cYR5)FQc*Uc+t%sWi_oM!%4xpI@(LStjm zZzigf%3dSwQ*v}@uCQhOrEAOs8f`sPncTa<6Zh=>AEj{onJuEkoAxFlJ-q3H)sti4qJuU5eN&5_jKf9hktUB|lfOCBO+x&X` zv`@`}$qSzcim$_he9-TUM6n1YTKPu60*REm=9k2(6W$C``{rD=Rbhy1c(f9e!3Bf% z8LU-2z;N|cTZYzlo_*Bs?O<^n)crop(2hHvvvDodw%#DRz_*0thqs1?26yrBeX&2= zrg`L<-ak88In3ZI75YuG>xLXF1DORRjSoXuV~qMlj7U%9JK=ctaQtd=wuh>eL}Kyx z_AB@e*8@GtUFrK*CR2*_t2S-vWi1T51#vmP2AC!3w^Bn_MUHi39l7$~(z4I%ROQS~ zU(XI-J=9pu@mqBM)$`+6?4-TgX3_Nx&y=3LW=Y=whos}7Yb0A|d^848_OXBZtkmjR zpK!*!)g$yz!j+s?Q)`nu(uSD$#8nSe+lCGjmnQ2;+~zQ64nzO+n>;o-&d{d+o*@$* z!9=`f)WAg#ZRR_Kyd`gtG2wd{(osM#b1L^W!pra%St1|Tj!}T>gvjqj*oGxd$4Nxz zr<3L7mGT2tY_{=hPCtKSXSXEJ-qbibXr}Md-<6qmj44yl@8?YG{=ipM7Fw%b*YU36 z!xC?Ppz5RhRiQhsn3(IDS)cse?&Ao}SzKPp7%YMZSJRD2hj!$j@jFc3Q2H<_`LC}G ztgWyK1&~S&7Er_@ij;GdijeCNSx^GJKmQyrh7=pf&|PjN9swNS^Etb))PT$BeDYqH zKlg_)u3#XK^hxsrGSm&U4FG#%ghdS>@xwEPK#9Rr#dV98R{)X`F|!e?CE$VP;XM~s zlR%6j@L!EJrdp}-HhDmVL0&ixX|jBun>}YeAt|A9FG)|P=!17512}q^!P{t&(>1uJ zY*@TkRDbPfv)QLSMS#ge7-%-2-?{Cp(hU#*fdU^X$Z9P*iP;e#YtBG(Y7C2at zY_JW|nm@Q|q5cv}$-;hCc{HeYwET?yT8y4=DZ5^6gWXd57pq$a8n*`j_zrl@)@n~; zezVkPdsU$Mg6v55|2L}#VZ9ml$XZF}7tL&F`IQC@! zLu$6}*Mk3#t?v$``uqRyy7o-=2w5RpR%T`qLPSNP$lFnt|?z;OKV; z5BSgCT>gvMfJ|p-o^K?~Xr9LiQnC&BUI3i7UjXa6qqa6$grBcA^8cOuv}V=U&#TJZJ}iRKrd?}Me#yT_sb8^_ch z1_Qu+Y)7yoa7pL?PsS#&MZ?PyhhfP8@HbpA%t<^NZYB)$0KlA%CRZauNLX^y9CWEGxZd zlg$WS1JIoavVOtS(DWkmT7xh&RVTbI;Mw=`b)AK_0NgNWLn$SYAPq-<`~~7|g5Vp| z^$Q`15CF@6Yf&1ScSX<*mZ-*&G4LYs1V%0N0zj*85HX_fe<%Aa5CH8tuRL=@z-;sg z);bt4o*S)(nPc(ay&eDUT9^9%P?Rt) z2m9S=C$Ud6ub($|`-C%i&p9p8T<_DPvOP%YN5dUKV-WR1xapYeAKBklc~rK~*q?uI zeq@l_`CjhxdzM{{5lW_bcZ-jhXk{Z~=^MLJqT-XAFT8k&XSh=X`R9j|`>sP8@>Y55`6 zk18HgbeHZ*Jab%PZbM(#{MbA%b6&DOI)&GZraV!SmOEhJ;I-qZ+W1Yovf9;SZ#3iw z1G7`>&C#4RI@ff?ZdX!7olm%@r8-`gbmvq|6-XJQ6TDeg~vzy<}(h1n3`7wSw0ohHNo_srXDQ@mob?7RLUP%6tZ_bU1*xW z*s^HRAzYT|TWE<~JB3=ZQQwFiH&7crazu-}cf*7>QFY0Z!Xc)btFCNkSgPLd5Q;id zqrBDCIE*%g(}tCDq%HWDri+lGR;4xig^@%jUzDVQwqE^fYO52OGTE|`MH6yJ5nV|G z{T6f1lU*d***DU6GKWsk)p)un-xn%2p9^&kC|``K3qQd1;7rKbRY%Q1`KE1!3<<|l z{mPeXUyk+V_jTo?micHla#|?me)gEyHNPp}Hv7hoj%rQ0-l{ioUY}Cl>;2U@gYTs) zolb92sa`*4E$05p`~gZFFw}5T9hZOMc6L?8+#j@(T5fDR+_99Pr1?zz`a)vodK|qU`6W=5FNmo*Fmnx ze@OH=XaT?vLK6m&?+aX}pc&AyaB5jcl5oELm!4LRwaR~qgg0_w0$N|eZy#Nps; z{5RPUVVlT9Hvr5h9f}k9&`oK|Fsd3T24KpSiMR-1S3H0h+EXDldl0`9z}l>Je$?O3 z4SV||K?(@YE(&;lnGpO5$0pQz5(^3d=V5(f39Xp{uV{+kl?WcB1jaQO9tc3^pFy5L z45ByAAaA1fx5a$C;4j2%Z*i9I?X6{v#U4AUXSb;-Vzm_t*!l`$Fg03XmtHayL|tKP z3J&c*P_j{;RECT<i+m8TdN@2+VtjIuMl*Zyf5Cl^HK`&8^VcK})KlPn#QEGr$U76h%7Z4h5)Drv_D zic1H1_*P=g4Q`4otE=P(eG@ZEzWwIo1kd*tI+Y`rnPYh!(i}tdMUOd$X%ENs8@}gG z)(Sm3-2Ji`btrq|SEFlr$&ZA?Mb9)<94s$qJ-F?cm1!yDd^w|K?A=!xXZy+%3Ve5T z&h>oQzL~B_r`M!vWXaGZ5Ver?JL8jOPPx6l`;9?2b}!$-g|CazDm#CA!mXE@?Kak} zCqK^nyohyuaI5l%t?{8!XP4-asi{20mcAD>VRn5lC1xI=?7H2qudBJeR8gB*pU;ZV zEl4PS-Vx(wT2dC@GTY;oNaeXL=bB?sy8L}!FFNr~fN3<{cXD)M_lV8tYoFYbaxUB9 z8^`<$Ny+XUwc_$>r?gbao!TEc>Swq(_GEc#&Wm8F5HdyI4{s#F3%Lah)FrcMG;#8g0iC}W+3B>^5 z*%;BgiPWcYA%4__$vMf0p$34vxXvFUr9=k`lQZJHo<3rLO_hXd0HzB=>PUoy&_w8J zFSyjKpcsIe^g>u5aC|Da30(PmmYv5<$Yl{Y1*FxuC!!5D8aBHC_O8Q9NAYYVK>>-G zFrk`92x5aQe&^mTo`pG{+sn2IVx0eVyv4LuQBfdp>3l!sfK6c!+-CrEcMioM5+q0H zL(hRESb3@~DSa(zW;0U@8yfYk@N*E|R z-J1Yo+oLEz22XINWq@u0==U+yJ#Q^jp3d&ZTeRRhwpp*89s+0=IBzhp5%9sc#2{Uw#fwPVi{sF+ApA49c7|H-5 zq&?KJjlie&fjR(MX@q(Z$qS`8TV{fScpp>(u-2idc$k*&Vg5r?@Ok>-m192-kQM~r zt!`+E#ed0#=2B;dIdL*0PBcu3ZZ$m7N3XYG;d?vL)v7fJIn zj|?Vmh%Nj~5Cb>Qfa z)X;|(c9)2&ZaUt})!3@2dCPjnag20+q(0_&o%oo({SDPlN3X28^vFze z#-MXtn0b_={={oLAr88?wZ23e-%m~=x3iKA8I5Y|Ee~coL@F09TFxyoK8kky;3qXi zx_(Km_s?|2oK^?j&47|oJDV@ant2;vx0gR-O|zRVDN-N!`*%$b2)4IfUeBc#eJVvV zuY2{-xDLu9^HQBRyV|F<>^u9sE*hw5*PsR#_-OU-qJBM3semo3xoxP!0ZN$g^k*exx$BihlK21X!Gx0veA1~sK#9JCn((S$rZyr^) zkg0vSwHV}wFr6ymzGb7?_OWEVDELUljfZr#lq|i%ztI}rvzOU=&a={)WJPTrT};!a zn{lYW>!-6TtuQ;5_d_UeswekPYya-X^!M5Meix>NS<&Sqm1-Y7jkdV+O8zqMfaQV~ z`T#LsyI@rSa3_Y{2b!Zezsl>Pu>JpXsboZ_i<0xU1T`HdRFU!#0!a?jH42BLt^tMv zz(81z79!*($nRh<9AqD%7=R~2fTTdX#lsmxpdRq&1~%-#r9QqN9)F!15W0t8fWD{Z z13HHh{pJjfH!e}|bQjgX#v=Q>srd0b+szv~_l36wK*xHMmJ6Cf=ik`2dD5VBHaKmt z6UXu+1PgRqXbV7hC=eARL3WD%WDA4d6O(q^(!NFrfWwyc*xPmCiND4N!T`ef2(K9v zZ%;vt&xekS--{<^{<5wUK>A{5p9PZ89C#=I9hXI_fpe+N4h2IV0^5mOFa4n;j7V*0 zKNkz@MFZLcFbCqu{~!d8!;F6VRO+k$H5>>;KsY-Up)COWz8Pb$cj^c@L34$Mxg|^Z znE89u7KF*eOET_3a{%TZHR(-+066MeuYF4OrG>V8$1+4*AXwiJNz~Z zfxlJ23nr97IJ=K3?(ySG&;u6#IlI5(#5nsa8w{SG5jLq~etbXvF>fKCX4sry?I~r% za)yW2bYm?!#j3%R;~HG__t|F#72G&^0!}MdbE|El#uixuetAA);IPk)}gM~y$rj_X!fb6-$#QpNMZS+{d7a$uyqNRl z#jCY+`#|5~cf_YG>K`N(EZb~rRAZis{yR^&fx7DTmnQb<6N|kQayKC)NCI;NN|(~B@!;6C$R;2GXfWAHb(}IvN9+JVCrNLcaTWzf!_NJC=J3@kJZ94Vi=RD zY7sb=3uksguzv$~>tB`&4r=sP8jvA`lN!U7PWce;LWoU(jFv2-AtieQ%N&5$Z(zv~ zac(#v2=oWWn42^Rfjh%IQ&S(1!zAnoL?0ZGduNypJQRQ-pQhr)&!RC8cEUF(2A~)6 zhy`(%1L#xWa==SD_AUo(+GPO`*d=@odXIfzBd!xRBItn#M?@0z13+Jvpn8n+qIu*A zZ+RZZ4Zu=JIJcgNcQ8?YXbQl7CRX(Kca-!5fXR49IzWUwc+btj@!A1X0ieOXhXoxwN6v%`-g2WC+>QRy$1$QadTCs6 zNj(26;e#WRpcQ)xPXOSj2ck)Iq8!{)^iT@Ge3qknh!C`bxBZ(@-18cI%^ZS+3@GZo z+&BbpP>h2haWFy#L{db6|v7-hHoPVr2y1eP0rqwg&si#)^_LLeI27XH*MVSq<2?_C%WiWmRH zI_MjKhRCpt=;9|-YyvN#y=MAB(gtWRzt>)RkDXtI_5k$9800vPDp00@ox4XBK-ec% z%xxO7r$k7slw{%|jQ$Ax1Aw7^L@|v(f;tZU^*zw*=}-*7P70@rCPyO*sTpt|*INvh z`=0zTNsM?Dfx@ch)}42Aw_(D235c-a$q0)C37ui_pOb$&=C~8XamLEs*i*&tSRAjq zX|l(132>Eo&GAS_29lI6@eTLC3QtLGR3w)0&gwf)MWS!Qu1}{iet{|^-Rloo9*@_4 z5et|21E^1*<*VywHkfL^&eXf~CGPqx_9EZO8s53^Lne8Cx58U|H-Tp*g8Ia>g7i$Q zyRM=F8-d&kZ^SfI?;X?>u6jDVb=m0gQmUEo=M!Znz87ZNjgsqlBOEq1?Ba#iji$eE z9p>B&c(pHZx$UM&*O|->58F$ti>>VAmfNpK%&v3$pc)E~9_kA7IJ4thK*aL){%87w zBlV`YtWa`sJki3l8?$Zol-+78$%5*9m)8B>{|fn7?bYSgz(q9qzLcxUDbv3(K7JW< z$6S%hVhZ6lCbsx80HN&Td)x0z)PQxkHiMlB-HTaDWDk5IW?Oj_y7oi3g-#M*|9Q&ps!Z&5ZW)D*a;a5lzPguJ(*w$tTzDeY!Hxw?k%odrTh-- zbC|Gczxw8rT`2}09hXbXN}Q>fzv1tiUIf@u!?@(V_oW8&;!N4It;?i)(vMG z0CPB=L;-<(0s}c$z(Ljz9RTnhVAJT)nkJ?h!319cWsKu%|1o(;hNb{4HEMBpe_rbR zy3^_Psg^9?SJ4lIw&-?8jMsepTMpfvw5PoOa2++QT6Jh~v2mDg>&=+@fXi0M#Xi!{ zG(xQ>CHL8v>hn z1I-R3(H@cb&soBZBmJAKpd$k5kG~8kt!bE$aK52y&I50@2Au)Wwok}eF~k>;5b7C@ z8T17PVD^Zi4uA<}pphpMz-kzJqpt7A#v}Y^@j#AO{MW64Zv((EUZh|};G9_Pgkh|I zpcnvxCDJXNdH?ZA2t`Jqr|&@j0Nj^Do`I+8`9Ms!^H2)F-0&fOOpGItH+W&7C!rXC z=Hx@B2mrNYeV>>#C;P9lz=cH!kB|XP0qBV}>Iy-u>4QiRZ8`Q7-(wPC&F@*wr$Ji) zX5%}JF%n4%gLtF}e9KQ5Hvl^{R`gFrlKnU@ghuse&#}fdSYsxftr6BD3U4}+3H<=j zc_LKIXcujAVPr7$wS5F6g!0?FDg1!s(AU03}2bn7r18}n!WPnkMimyp1!kX>^||(v=uEG;VBnh7=-E z>g~LIh#uo^_e*lw902(LP4c=)O4*%J;PpREs73yDOw`7{qNKdF+)uJJec5OYpK+x*KDlt*yH zg5;wsS}Dk|XWLRoQx}|5?M`l0o*2%e_Iz~zq2H6WeY84>WjfEK*_Btg&98A+zpMOW z_$Z;d^Hz&;;@0Ifp9{#QK6#1C7Wz2fHF_XseIjl2sQU5v zdO6qQF;8^R74_AmQAmOAsH^+dXuI#DCZ*hV0_RKzzPirLZK^UT(i>A1HRx&^4S&5c zqap8HP!j*seJV(mN2#FcNN(sI?d+imM6vxzzc59$Vv-k`{|LuR3Ps=~f!VER&=3Ce@0 zl%wG}vS#__HT}L@>|cZQgcD0fx1NPw;McPIa7xoe#{8*J4yofcF4~dtuTvTPSud-c z%-w8gFW>Mkz28$dn?|?HN%e#FIyH+ZiB8@3rKndkcfNbncka}C7Nd8b&Uk4IIJnDl zhP9CC>TYv+D5uzo3nKiRF4_i;T-}kkt%y-PHYFj$ek7QFr;Gii^SQ5`FHsz~b|S-X zooaJF_s!eEZnxUIwP+_+E&tIr!@oR;1FW>tywihN4agdSd4NQtgop|#Sd;+Fa}P4m zfM~&5^?45(5OpX9;6xjO2GGM5uF>n`uvRze2s;6G6oCvefwlk)Yb64SL;~T3u8ROt zrXGp`nAr$oK?E)#&a48cck#Q2Kp)~yf^|4VA6x^Lr4Uv<0DWE_Sf;XTh~p>-l4d=w ztzel0kN!#^>OpKtkb4xsBe3`{0Tg@O2ulDthS*cE$|W83Xr6!Bq@^05)n9?0V+fEE z;F3HiV{ocp{|f(nK*v+Y=-{$iy=K`TUk^*ho5luBwNeE?n^`PPAo+&6Ydw7a7mGuO zo#W{A=58PLK59vtpAQkFD*T!&w!i0>d&zvgDvaCoP0x!ry4&wty>#{{Z$YE*HJU$y-npod zai{2`zI9--?RCnnYsV9|rBOeVMP6M_wwrhNOEdXxTMuVt&BsSF75f?A7c7S zS>u#Y=BBXLkT#19KmO|hD*p05;R-f~{SQJ4X$=J=t-=KKe!FS*r~8NBcexl^oL$N{ z_RVxZH!>EjHZ|fI^43F=7ay~>{O}JcxEZT~s=UHm^guu( zV*C;7GPTu@<=U%*1rHCHDy^)berNZ4+Rvl(v^K;(noD zG-5qmQ<#%Gin{mZliVNc;bRMTIKo(q%|2$=Y&1ptTOU8+|7e|?8tp2%^%uQ{H30aV zFGKrBlhFQczbb$fhW&+i#K7Ofw6OjGxSb>bb{E#X9-F!+V6S%&whNXZ!*e}s&=i3A zevJGg0%v{6y$5YyOCgNTl66bm{2iH2!Nds!9*DAnh0$DUZ6v7XaK;!X6#V^t4@-I zG|%`~Mvx)n<=j|mZG08TnLW)B@aG~pvZFHtq%j1t1GAMub)5(&6h#o-n_q`%F%j%P zAaE9eX*~u*0AOw}lQAH1!62Qb;hg1xVgMTADu&}Ia+7l|A5x)*ZUQ|GY&pS#gg}ww zHSv9hh;&?nh=Ztx-wLP%K*MFa&f&OqFwA+97N8ub$FuKQsm z0NmR~0^5(CF@xT*9KJQY0D5yGVj=o%F3nu*jAd%PMi6`UWnkG1EVw~cL6o^m|NyeJg?bXGv@V>DF$Eioa zUzA|)M^Y_AlaP^LXGpcB zDJY*N+sbvN_(Y^{dFArAe(yJY8<^n$1Tg zvGOvCth$7IzW2}RH;wUL&-#z}gn0HgS%x^sS3HTaU4J;Fb9AjeS>RKmW038>I`h;5 z$GPECsjE37)0PHCTBHAvR0=x`uGrYh zv#jJrKDrWpxN$>%IL6m2HMfE&o%G&of$WEQD!0$mUqP)@a9pD|uX224XHVL2`3C>M zxw%KX#Anw~Jny~^>h$lbxtocw$y=0gj#B#GK>Z21DtN|OJL`n;$e+h`70Mw*+J~cx zVgvOg+*`!W+)cs{waEl^aE_n-)+^*)@_dw9IyUT->;03a-t4jEB!U|s3~#E4U5r{- zh>q_tWTCnuAb!CAseil`+YJA}i`=13p^6^PJ8z_%yq=*@=PsU)6sJF}c%q?V^vr2F z<1I_GWYHYT%a;$Gvr(3&?~ycg+uD}4C275!o9Ywem_KMa-8>>nQLUJQGCz4@Jf zb)D`&*VKsQq2iOmS3RdV*4r{4s)oqYaZc#2ZRm7HS{I===ah0!CH>G{A$@=H$S0K> zDXxZr6SxfT6pXO!$@i&awS^qhNlcF0r<)csN9)=+h74o z0XQYr(Mi&5q#o2j$|Fv)Q&0oI$7llkT6D2E9EJo-T1<~PtqtDaJLebdP6AtssryC5 zi9p_m*2kRS3Mz*_0I@t0QUV|&us+tHSDp#mblG@@> z9b{mXDY$z7fl{Va?!nfdt6$a6YZ;X>@su0!XlON+=ieE{h{|&vk>xeNmqx}uU%b%! z$vOTfPfN0Y+yitNDOny#jv062MCywg`rhywS6%ex*i*N!@g@h7Oi2e=DpZ*fZ@!6f zcdW~t;c#vaGa*staZ!7Nd@I?8nip|Q)7_#~@V(O&X~CEtX221DRGyl$;`14HN73gg zt@-Q&S0u{}%c^YJ`xHw2SsN<-rYfqOM#XGDPN^<+vY$;azB!t-B~zm_lI9U6d)Qmz zK)@{_F@<;LO3h+-Ep%y54|`2Y{_b8<$`R4A=cCsC!@`Ghs|u??OgxVKb{<8wCQKKX zPJDyCck~eSDwjy)}s)*U2v^aQ`$3zQyMhdarxoql?E)$iIxFXzd_p7ICVwCCe41;j;1 zrg|#C&*`+RQk?DedpVkH`Fe$Ex6>V8GpCTn&R8a2@`;LN&ybo$opaA> zS0~X<u88U~li>{HTG{)=sQ<6bmS^4*l_H8S!b&RrW!|!#APEcR& za+C9-PF0L%wNUGC7!P)ex4;H={^}hzzIE0@0+WP?r}CJ`InKzDHZLIBzsB z%OB<*&8+5q)w82eO!KU(b^IoWUxAW=VFArenuKjq^sRQn2bu6FYS0HpX%M^PdVOUXEb&s*{UYFF!brd!Hu5R z1_`|=ueGuFB1@>9yUkCHDR@f@9*z`RIrT*LrS*L=wD2& zl@qA@9j2qGSgKUwT^5-O@rA3`W=6$#f9Ta;n3Kn|@50#gED&z>$!;=D3b@s?35HeD zKo{d>xbNUF0br{2i1>*1WKI7l$XuWnfIr@_#*O4!3Cn+RXQH1G!-zup-zm3K93rt>V|X}Ns&1isD*$PtQC#rjf`Ipxk8Y`*ODKnq z$I3Z+3WbiV^9~FYN-VS|T>B52FDA5XF8jFzAeRnFDYwLwXI8fzydC)6YyWe)`asiM z3%@sY+?@xG9bPaSjED^$A?4KYxO+4>NbpnKkw|n>7xQWI#9U-u-Tk)n^pTdF(&B-) zDj3{VHqJ}Dex!2VB(7R-I6scoKo%p4a*NIF?$Rr=ifFr+cj1+K0#}HJG|ibtaqvE136r64rCA(G~vj5u2wx+evx6i*lyf7kCn)UZ6W03^P zJif5$M;M}S!(CxDTSKuhVvEezbN9$b&^3?9uWEq@==%L~6ZA5Y$g&w%%!i)pi)JJR zmD)v(tjJRp1Xr9wGx~m6dz0kW%NKlwl#Ry4cDw9Itf$bslXSXa&AJmAvi8(%L~9SK z>S9y+Yy}R4{-Ko#_IQ(<`}oB6g4Cz-Nz^YZf$2i(L(Q#6KXKj?;EQm&deM0BkR5N; za3tfQxPHn0NsiW)Geeh#-yfw`lF`y*kVDl3%}96$tS`2*sRj8zC`s^(ab0igE$lh+ z(w5p}T zkGfrdkdbkPn@zPs-S>2RC5^whe{@ii`$bkp@^=SUb(KnjI#O&t-4(rUwKAm<;$gi! z%@{59nVX1t;xdos8U;VqG~cG=YpsJZ$wbyQh~WvTNL`yNOF_MI)I{ik+Ih8*ujTGU z^(%4@lx!%KQ|N-42F_?-Aky=kTj|hL!f>OqV?qy&&>oF5l5l7<6J)+mk5$LI+*;XSrOI{G$uQ*>xrQhDvu7%k zuM$iAX7h2J?Xu`AF}3Ddn6+5p^t|F6Brw9@OC(|By4`ObToZEg&FePXP(I^X-qjvGflG2xkpD3b##i?KmVBPY}sH+YRh=DyG9a6O6nOb2uAh7t)E}m{~FhVt-XC<4< zDK&4GhW!Kkw5i*m)mca91zy?!WW zOy@nH{=B=frHF+;{=u(GOtW)ONj6#e>cUF%=h?*_Juy>aZGH!rCk}z(y6op1>J`*m zkN-@%w^iXg&ckM`!4NuRvev_fYVp4#{?&;#z1X=ho2D$OOZD^3#wy|9Xz78DpFXoR z{Hc#-(;}@NlsqG^@EvxIrZ+UNo5=a@-dHl>btirx#LW2is)nMJy{}ba^SRr+l66cJ zD8W~kf3odkE2B9o^75$VsTY36D%7!^k)j(+7CyI*m9$gmnWS2p=S!ZLOwC5AircWn zlP{03@uc;g4jrI=SLRw8QpA*8D@e-7YL-lza)ZU~)C*NXMKeafkd6~fb{=tMuWof; zWFCpL5+jdjd}(87Y0AF;;aGNZQRX*+tZHwso{l*)M{#ifB6m+Jd(}y%#{HX0Un?zZB|Cb*2{AU;qAo{& zx_vo5(d2H_jf8@0V+HyV?|zI#-Jm>a(>~3E0rrUlv*t}PEXPA`YYenW(hFbl!^FFl{ zR;jWw;VDSXAo~vsz32+S50?z@m!xJ-O`;rAZSu-8?PGPe2R+S+4X!ri~90=tnbI} zUos&j*b(WT{ne{*r{5#&2wCv{z)QoVVK-oLD>lWD1tWbHv4#&cjx~$fbHgUMG~zC1 zoD+LRmf08yT$8JNA}r_*?|nvaV#kDV5kdSgtWBOxB^f6f!BP(sP)U}LPqu9-0<0E6 z%!2U|p{61d%!PrjeoniD6|c3!1&ouAVD%XIu8Bc-1t{=3$AH8+i+$(M=)nes*%JbR zAdO&n#0V1tpmD-Hb{Iq-Hu1(1T;Bi;(R)&EqyQxRwcd}=mBo@e|MURKrSMddEc5`t z@Lwkfn|iDU1na;;(2jh7jsW=g0g^H618FxzjzBl-dsZ)yat_ZT_CY@Y9IFcc`K0I> zTk<0UV0UI6T*5t6{P*bP?Fg}ZSl~YZboNcM79>QIM;|i>Cbknw0cdM;T0Mc~|Br(| z#H}V64(yqGVM#ii$r?^_*Q*LPZoSY806%m(7)I{mkggaEV*r374CVKF zAH_-#h6n*93}l;xn_2_blnr4`$$}~yuZ$w3QNe^hfy7$4q}pZqY7+S{;L`*$O%4+0 z;1|hf7#IM3f0g_vk_n#nH3)2@#-S8|8499e#wXMC!@$twVZZ=P3WgX&oC(nSQ3WM4 z;Uf<~B>*Q%ps;}f3Ru^ddZKp)sF_i2P>02Tu922FBfWBU#vgs{*R+GpJuFY5zejSV zHWs;$n|<;)^fHKSj@%~RmX|5`x=N4+I)uM5r2T4gY{L5`zt^Nqk#^=^N_J!A4{caY zBkd4A0={kWTefF|VxJDP@jvmB{>C~bAv(leuympX)mXyELGJs_#aDRko>S1QTGZw5 zTFloQ_?wBnASu}M@|!G%&&9V*!`m98L%mCm{B$#Wsf3=PI`QRUrS>yl-e`jJEDz8eC#VNS3Q>x(lzK9 zF7*|XJy(a{O;-K))<(i{$r9$?XH63Z+zV-F?qYK5D>|ydBOx1qJG5e`^)zT?% zY00^ty(Wy(ulkhz^)U?{cM;i-RH15=5%uQhvuyGZlwsR_K##QST87cT z_dnbEGd2m#^OJ#x+i|tg;ATeGUcNZ zoBM0)9Gx@wt$JlMoA%rNp}N>We02WtE~4b|TKYWA=POA!5IF`Xn&dxAhTafJJ9YAH zN!gS3M6vgoS!oq4D1OSBG>PkP9@YvJs?@A-rEK5A_`D~l_)&2?&x&v=`H&uC1)FxKuSf=X#X6*mLgs zta0s|c>cl;oiOHym{HWqlP{^;NL5u!*QP3U#n)R~(fap(3R&AbJW)&4pd?joKrSUp zsqXV;iJLK${WX`r<$S`S%3k_0xKeztWlUW~S9a=fPMoef7HF13dc{QQiMYlOdy>La z87&v@UbVHL_c8FvYWgE@svkZcC_B&pYAUCh;rW^Nui1Y>M?5l@QE75#u0Ey74d?6p zpjae(si$hLSJq9Z(}8wER@3nUhf?fVLh;w*PM5ygS5_^)nlc#FG{3$7$=JY;<1YS) z0E;`(r7v>j@+V>tlnh^W`LQm7!UA?Zf&a}-y_Nn-p z>ccJSs#*TD3&(Tsy|{?{dE9?=!F@b0!Cioq`a{q0%`URY@UYa>NJH13sxn7UnaNaX zy>+N}xOe>OAa9CD&7fS;IY$o^r59x@aoFW!3?xUoNX8T7&wfAGsl;~|HJoxW52bCL zsyo}MF)z^B)_=d9;?`~2%NZBs+(!q@E_NEKl@!rgzuWfMVTvA~UkOMIEt6@anbg>P z@Ii{)0ex09Nc6=`&9kbK{g(0MS3({KX+6BnYdsWb@%FKkQ}1tY@#-}HSWQ2ti_X5h zOo`DW>mnrh5OA<-0UELVV%IM;AmN`SlHqQ(m6@`1tQj@E%Iz$TJD$gs6UAR`_PNsYD zL-j{Dwt_bwzmVBGU2K1PrNFJR25;Wc!1wd;AW_AlKcAw$O`QQrI<4*Bkl zU$#b{Gx+x0>wBBTQ6G6e{qgep&!2}-N70N8M#-QRa9BW?FHY9Eyj z`=FFCL(%eLR8jJs}SM+sI_ys9RQZ|Lv=K?`#!~ zjJBACQN6&@=lBD^L*@IfI@2JT4~divjoW<7GI#54PSoUbV>L*QVQdLMg0fg_J#y(! zDcgj+-Gi0@yYTjdME@6lZ^I>~cm3bLn5!HR&)XrAw19IPwa!_8$H0?bxD{5s4{ptdZ)Y z;r{KVzL77lY(;k^tr7RKFe(x#Kf1%SZ8sK=NF46)eHg7L?cK#1tA=1?UvOq6#ls8xW1^e50d+8&?yc5DTO9jL71;Qp}*LNnj7w`DlkEtQ6 z$JE4P`@&H2S-oafrIR1L+ion|Ud{28v7L=RH@lm>TV5%+yzsZU65JN8OQx1Y2H`5{ z0zw-{^FekE{1wFs*A4*9q(Hfaya~6+>@6^!d#svGN>CbQ!t@Xl#oJ@K(XU*S3&5<&*b}9A@s9nWC#T1 zo=FrLj0b=jccE!OAYEXdfl@#Z#y~LuogqbBg$qUrIwfX8Di0&51K>4F>F|%wUqR41 z2c-Z^Kl~uVk@fo@_cmZdV*SHXfVUE!o?wNx0L-;=qC7kiiuGAQOWKi>?NOq*!Q;BA z^DHabzz!Z1Pquu7=|vL2FFcqs}wR%{zWBnZo1b!F>V4O-*z%F~1)wi5FOXe(Txy zNsNN2dml-r#$=C-@OVG@0sm3TXX)m*KKX43C7o^&qcd@IrIYqR9QdwyJafUCt<34= z^!5C2j-;eTUw*e7R^$0CrA~FL@Z{|8)MB3Xd%M$9 z11Z0UmjfHm(6*yirxFFzf)5&KNPZc;C}aBTb>xXWUYXX|<(#6zU@ekv;gyM8ZoTRS zzM{^7^n@~Phhoi33SrWbcUy;~jKA2Awx3Er5=XI#il#qxzo%h9&uod~9;HiQLOPGz z3)jZM9jEh0?`JAUza^_Z_=L4q^9TFNso4QVDqH$9n&r9}@UcnDNZZKZ}z3k1&ns$KTudE`I&8o|S6V zTZ*nVz2$Z)+aePGN4gv;{4I`~WS;jqy{#U%8GKn3ol!x3?3N%daTlfBdVIFOG4SjK zmmKCDrz4b0H_hIxvT)H-2GK=r5p8DnW|G{FsP=gwR-AC%wIDp>f^o0?yKiZx{jKpM zDG@g~kNdNgSl>q7?UIn%Jbv@pwnXQ(XJoN!d6L}T)3-*!rl86(+G&!TdfI4?b8}n1 z`&?Ls<=ffAREowHMsv$#A#1DKtF4N@{VlBtYELLP=C9kZ{4j{N+Xk%=S6H`;{h_K~eU_z_H9;{volsr`#PZ zhdcHyPyT!(L^~cD+eKBO{O9Fsr&WfuU9tEgNScx$&ux788?AAE#4lpzm9+iAE#ap{ zPxG;eOn7EVjIdaz-ZmNf@@QW}U!pH%-mHnq7gtGc88^REWTj>DTc0Uoi?T|YNKoUS zCM`)jxKqya59WWBA$`5&x%E}hTASkQ@t(T$dtGmtZpZx*>1kd1rtI>dBX}Y0hk**c z{V6d%wB%M{>{;dOtg`!a$W1m!CFe9?5#1O_n$tLc6jKLc&2Vjy_Z`^vDZ;K zVIfq&icKIvjfN#x#{Xik%ZI2DX3sQU+Aqmbjw!=3@zhmr+GhT?s*Wd@y5(cs5|mKq zh_hTu^w<4~#dQlu&K$T)VNviamve5rg!Z~HQ-k$7>mANam#k6OnZaXXj-{kl-&PuC zo88~Oy!C@U!qV{t@xf(^f&3Q(66ZSTxE}{Ps~Nkzm1!X7A3pb))aZhZMYV3{;{GYG z1G@`sH$O&PQ5_gI#autB-u^j^#=D`U@DXb3^3Qmre63YFDt)nwt8_`4KIi!ApnKL( z>h0Xt4yra5l%COQ*5P<`9@)3*`uB%z1_MjRr6Q8Ao{i$~(lP2yy|m;WCF%4|HbqL& z)x*AO@kxfqx0maa7j~n+O#hX49?RFC;$uX1{e3AOwWB4(wDg8G4!|VrB9?KkD0pkN z-E?BI|Fu@zGi2LyU0ixUVu~uJ4O6n>Vl>KOz3II#wcJ9 zZT%C*PGW^;d$;sa5H#TRzCO?vfal3KlxUCQLSc!R=~~`^jhalbiIj$zocLQ8!eC)T zVW9&`h}keU)-=vUxRiB2ErG}&n3-UvEs1!DDHPzjCrv!lo@j~5h&4`l~*RI-_O&QXEvS_StvpXN!#va@o$aeV=iJ9-&!lTD2!TN5Qu96m}BQ55{! zhW{{%J0m3Q)sgHJ<_MxGooZSUjn=18{$`!DO9%U#f90mCO1=Lm&G6^)ua)0Ly>U0j zvZDEAojmqO#6KI=6zp4h_;R^Kf&7jz`_pMMml+Iw!K;W7E>?qz_kO9F*RHi`v$orj z9KU+2KlgiKCaGY6R;0bPcV*=f2ic)h2T#knwpF7zvlyh`^YAe1J=3o&rKPv}9=P7o zOaF>xypiVDK81;5(mD4p>%{64Zf9(sJABM|UGTYJsP@U`>~D{gn-dW+(h_|t?w{5_ z|Ew`7HRf*yJxq>Xw@E9VsFLH@lVh2uh|4!l9s84t<|y(q^pBazv#EN2&q(X`6*FzN zH%~U>>`*4VU*Ah#D|vUYd_TQ2bJv3h?X1Z`{-;6{=u;9iHYZzYsG=`%?uwefS)b<~ z9ounM8e*+f*vTkb*|my(GvbK)D*zw3GFvm)ke;Z7-6sU%DJ3wn5s(1{MDl$gAQqr40R8no$vQ3o zm+t_T>5IRPG3?XuYLGqSJhEfRFE|IP2L@m(T?8EfFmDWyK}5KSBZ`XfcCz8?05DdH z#ES@A>>SrH(ESi%=ipQznPFslI3s8Yk%b;2co|FZ`U(6EA=VZbbPm8gxkf=jgm%fM zWI$pqc%$Os>$XB200Ulp`3U4?C=TrXCmfm|R08m<4>sZ--s>BG9)m|V)+-xVDewTk zhWx(jBy8Njy`vkO#1wDOTM118=&LkTzXUEq)BhS9gB3F&@}nm-1^m0LkU);1cO78X zW>5vd@HCo3!7?d!3(&G`R1mK6t4|TY>#&~T9IQU_m{P1;H7Ti)9W=>$iF+R$a zs<^bl@O}5xQIqfw0PY{SOq4%ofRk*hoM z`J(QC1GoB!66ab-?Q2KZwSd|-hpgkHUmWb$0>uZY0u`~(c+cu=Ls%SX&=i2FH6$*@M{X&`I^BJQH3Pu(RFHNfknYfN&waS^ z(9jxy7Z@-^5b^(GfKDre|4M(~+c*zN2~vjq}Mgh9M;+59-j-AS@`!{ z437X{4xgZK#d|F1j16vLb0y6ZHXSI`;%lf z&>9q6y3joU|7v)k)OQiy!X``?fKFZ{PQp1~di3yrBChB02>J0JgX_>_PL0x%Or)PY2(TkayYN}EOJZan$KY4YXA^4&z! zVmH|^31{*6kN0CD3c8&Y3UVn+&h`iSSrmV6cMiEtN#cz{#j`NK8I@mkSiiCCJ^0k= z4eDWqrTNbCLYC^!3*)nc#mkgb-D}U9m{xAq$+qntG4leKo9TYEdLJ&g|^J7HW_*`u`IJoC53HQ7d9H^cpRt zL(7CBICK2xR@gWF_zO1Y#t+AtU?j=i$Eju44zH0jpB&R{x9DQ!&|fvN+$0^3)2c#R z*vsl&b4s)j-s#EWu{N*lD6Qx|dIzz{l(;3mS=a5)p&+StlzHEoq+MyR#hlPPl4<9Q zGd@*^cNRyLysouI6>8NqCS!z0pCuK4u}~g=f&4!{H4xk>|FI0*TDs1Hm`1ei4dY!hF4) zVR~(IS#Isu?b^f7idQ3h707yBni$u7tmZ0z)|I+Xe~DVzSUG`G{C=?9XruO^#Jsht z<#yBJ_MO|3rxcc*$a3hmnilS^>S{+fy7?DBbtGa5qo zV+KOKk8&uqzN=TFyrQ6PHY}ZK{^ttQa2w;kZ}IN+v&Q9f=DvS+T6sCjg?J`CEw_Hg zxxb`1btQjoY)G)5`0Sa1_f^-J)Fn?ir`w-0e{lZT`=CNr-G%X;u=ClkUOt^b{j6He zMm1BY2vs{czw0|WBg>wDC0d7iO{+lRRj(%B*3~oU#q^fH=zJ`F&O;AYkc176(V(ZI zLEs|Rin)O6G&o4%BG$s~Sg#e5` z{P;IE3L%WvNLpIEXS~7Yf9DhP%y35%I5Bz_0 zeRWt>%Ns5sozfsFf=EcWw4g|f2uL>yNJ_&7Y3bY`Ez(_XkuGTvkP@W3k?uRxIsVSQ z_u+Z}S7;2h zWjWNp#7#DMa@*TE_Z3lm#pgCvQ~z%o=Y9>A(lxAd#BeP93lIU%_yXCXQY_UBXd^k6 z*?flWEJ8&|Y&_8%(Z>~=`$uO??rt#|A33*N9aXTKZJS;k%IUnoitd4GWpUhs)2PUK zqDOQKKC=5Ym*=Fg8Ute3U4NMhA#}oEhYX*2XV~L7kq8%3Pu;}WVS+yml!jAZxOHbpD$ z!BKLp1Wql-eumy3Nf=7_*nOyS>iP?6JnbT^6Oz8NAveR=8BM%+zWKg0OcjG{=6pd% z>+b#Xk}~$sC-#`m&v6nsL<{_vFb6Q?8b}22XcX*%HsvEB1<$A7*dgyX7%w)%-9bt2 zgrE%VS7s`NRj=!{EGz9>Km<3!fr=9OQkilA;x9}8*k>z;&pzWBme7ezephLk5dd-1heetg)9e! zgkoXcRE&T{hGHSWBdUU_bu0st4~@Ww2Y^w^B8eg(0@5%jt}ZyW1Hfef7>6$AefUd; zfgBF7f~3J^09Ypn!f$v)d(hg29n=s^0ha+_N$hAW2$y_k8p&Xd=Yq=sFt=pXtSf#Q z!ZOj9c3`#KoIrq>^IDU?=9hu-kYIwcD8T-&85!?vEb+G>4?+g70;Ix0zW^|k-diAf z1Q0|(i|m0AT@Q8*09cmNq3oM|Rbtt^ZDS8VBGLXyGi9Eo-if8j0$0pg$pgh(ckewZPB2-t zNN%NtM0_Hw`)uH8kpsy-6w^;mH7Oyx)ncwoo;1T2jdksY-**y}`W^w@b#7=)@pg84BWNd=7d$k|hm7 z_Q!84h)P+DBF6^!Czk-qhSM zh*SFfF`tgl5weXF>EfcA7_*D<6R48>eah`>jl@U3FU`fdN8;D|lQbX6HpXlEeR=z> zP4SmrqBS-7KFD_0~E-`>;Jw26#%EOi=3uRAhE^dU^Tck`WiMqqc;%Q&}W#1ChM z|H#hIYMEO}C6zgFeUghAo+?Bl?OXQ^Up~@%TfJPhElNgBohj2)ZrsNP&PUVu z7*;>{^3Wrr&z>8dw{la229@%OO0JWx^*+v*@ZZGy;ZVaD-B~BeR6T!b;Zk6R^IL-B z=P`IjfGY|1ntJ*UN(Q(JaCH@gML{o%t6aSqYw$mStN&eSLhjt)bhtJ_!&10WKEhve zj*xx=i~h!9C-@1|1>us0kog4Ymg1lfG0+F7GnjK3txvH5PW}Ih)>qlUa=xVG7i1cs z<@oCxT?7DLndB0i(5Mg~#$cX|Lx1tT26p!!Hv&25&7lqfZ7=ZG zJh_}EF+FB?o)EN5m=00uRc;*_PX|8{<{tK(#X)r(pvT&oJww{<9lk}tW^JvxA;5pj zdAWE;aZoW!4N1n2@=xQ_QWlGXb#Q6!B_!(0t8j^+N56-7nfM1E(ihNtW;y6UUwgv2 zJzvecv4(!T7m0W=_n4f$N!2E;==p=`nS-!+yy5w8yD5ZC!=hC)e0A-CF=#1Cfz+FV zuzQG`E&C+CZ)Z5nYcWY@Js{cKy<=H!5kJ#_|`>2dTgNxS&Nwk8_oEzN< zE|aKbHiEpkLpDBQVPKu>lsTNP$~5}~Sv1?nR&(1W2BAxv0<$Y5-LNi2YLDax`uzsF z$up-e%2-8z%@ovAl2QH-%v^VQx4vmYhD?Rw%kRosw98ujMbi zn2^zp6=W+M!q5{v;XGe52y58Tm;51}yLOPCYY-R~Jn8l{hdmtQbz)QLH{}R=C0+*n zU9VBMJueUU&Yrx7yL_((6I+^oxkLI46m3j3&&sQab{)4Q-WVM|$QuYssy007U960B zb18KedI#CChU@y8&-<=RLZSVqxi;?Xq->!|lf3S%7ejI4{DHP_oVz_{XYB-qVIk8e zG2cc1=Hei}R=iNP35u41nkA1n-DXp|a6d=$xdclhWVTZrj+}aJBdKf@y0Rf$9jbeQ zZNdFBCF}F|)+M~QN?+6vyiI>rMlLFKpHk7+jPwh~stNA_@tmO}Z6kC%f-1nhKK{Y_ zWH14QNYgcb{e)HJ*;zArHk?&#*)PxVq!lmswxyM)Zj>u&)}060QHhXWyXlz3i?opr zJ>dyuZrjg&yWk%h#(sAE*m1u~pd?`k=bY9^^J(%(T=&j=Qyy=p`tdop@Y?ZF*=pm; zKxZd(XXx1SUug}H!)o4XG<_xmT|Yu4x)GVK%B(+YV#D>#p3tz`3HJ-HPTG^LpJ`8Dck;ZB4=54#5DdelIyB+nqT#>;t?BHgdbG{Zr3sMkq?2 z7x;@pp5leoqsYNc2T>z9e6>*1v`0JnqSqvkD}YJ+QHRsk5s&YvXyE}?ax%Uq(T)$> zC!5tdmtSjlIwe=`3gy#0v(@vBeP@nt?6U_mb5~5`>vheEQPdKOXBK>egjScDt)J*a zr#|FhoA)LDSNt7!q30S84*Q12Y62WjII06)97BqjB5J~Gy1%%HY_l*+#SXU+PAVH( z+XT!&Hc)S?^Cf89%+qR{9jBqe_ojCgop3{%_ABdQWsY33ri;;UB9MJ+XaWi1uhSWNZgieI$+V%RQy9uUj4t4=(Xwh zMx*p)z#6*ZtXNrANe3`pK?_lN=q_?#?tDT1gALBGs_W{}ppwe9vU$yp z3G=o`Wk5jW28ZJncjlF-N(XuaxIDw@FhNHzj(<{?T^zFiRyyLnYB~%=U;t=S0%rH6 zd#mrHnqTOz^Y|hn{mMpm5N(XHLV8mqD-{CKVVXv|ou4IFsVAudx zQc5s*{BRK<&$of!0KiH`kRD!XEN|?AGJG?{V0+Aax9I+Wu=`fAdR_9r9umZ!Ut5E- zK*sEuf2>`v-juDAS4hC`=V1K11?}NSo zF8ZRs2kt8VgP?;3JZ?OdGP>ZErVgpd&pny7+0P2B`8VAK$ zgvX^z1TSv!0o*{yUlZ)23c!__a|sLx07g)T2vn$NpsgzEAk`=s``)#51B`grD%4G; z{Sq0*?*G$D4r~qoKPx$1D(JdICv096Oi=S1+XN7>uWZz7U>E?fcWGF!5H1}Q|D6^W z4vH(gJ}+nsa5XJ197umBgEYUgbeR=$S#p5J&BEgE1QJj;{@Mv40=fkN zoPdPTZv9(?h^HU}BrF8H*J|*(0j}6%uDRoG%=$Mg5qvbd%j5$x4WO^yBp(QApvfU1 zz6IZzv=P|1!oV#6V1kVpw-GL5*+g}KSj-JB13>k4Fmo^EU)&yGXupwvIeO50FQ&tP zT@t`^b^Wrl!T12KCZVVRDiIyD_1Ax-UVg0_m9|&^)CqMb- zwwDhCh#Mkl#O|Q*fnNYz+<_=kT}+S;Jd&oeYgae~gq44~*=~UTe5DkGg606Q0XyV4 zBnZ&?HEpRiKB0gwkMOS*>$+_KXnTSGip-Ihbq-og41RnH4AV+e{(^(VimTVJ^jz7S zl59vRs+j4SBiy}^ZhHHOPn>_9FKnP=p+uZ#obxoxK8%ZRxw+K7~31)BD0talr6Aq%*kkBE@@u8Ww zlQ7?z?m2zPO7u~TF(9)&6Q|n+9}*tEsYy5uUnl%HIhT?wX}vrKjvG@A&#*TV&j_J~ zw(li!Z%Wga;iiq9O@SW8a{q2;Z7&RUvW zyxY^F0>*Y-{nl-cukO32<9I&V?6B_H&d#ecVzw${v!Q%MoD@3!`ULY7p%!vHrJia+ zKo_Jy;Ioq@oVfl;!EhI<8H zcJO%SOV-gpTssC|v<+PX78E+$)iH3b$90a+{W%WO613>=Z*tU-PDr>f$(zd=&E{LE z=^0iOKdMjJfBMTQ_O<&tYZtoh6D5^ z*~;&GUqg=%lD(?GZ8ye0%$a#uTfO>cb~n*I?cx2umGld(?lvQ!b3_1I9RQ4r@nW~X zP*lgh0hRIk5V+hKE>~TW71~WO=k?mVD((iNBsHHrQ!%*(rf>Om2_mo)@Lru<&%tyA zxUAa;G12P4Pp2ENtDh8zqo(OaPL0BUN;vGBQ)A_E?xErNGG7@xKz!Qz*7Jffv1KVC zF7uqXi|IcyM&7+HCwG}a$j9(|B_C*_k!@d9dhEDz)Z%<63obx8xopqXzGiz~u#~eD z15U2Gy5P9`43mw2W=QX0X%61u?=CJ5A;q^n@Q|+AS2G(_?@uk9RS7+M?a1Tnzw&5> z;e^6Qp;Q$PU$*wL9mNEqD?XujxBtn7L$dGPPcRVoaS3Yb6ge0-U>PnpQE{iJlPlPC z6YI@FjCR#Z5k9m;1VwTE-Oub_I789J@H}9W?FV+0uCJyk+@((vj*1RKJ_piGE;_5Y zz!h=bWu-_)$$}%Xz^}Ng?1Y_Ubnqg6XKMHPN&*L>%=`9Iu6_=DmX`0DD9x46AGE#U z=#L}vFqdb%PgFSidJET1%Ww9*omEIkcKmx*2p;kV+K`YB>;q|=Nh`wMeR2%}WUA%P~Wj@L_CRzfX#4Z*p>v60J%&0lAnR%Oo5yuIz_jSVrJB0&{e86h(P>u#HrQD_2xWmgUy)@D*6 z8?|UOdW-b=C+xfiSqug(WLd>yvSHZK@b{O$#xcsivmg|e4h;KQFx4?9#n<0YD260J zn0XoNI!;&;jEBq_o~w&#d|;JjE6iA1V55p9UOW*(HrG$nL+M0i((Vy=7B8nl^3whM zqAVh;;Yh9;%ULVj!D=&`!r0{LE?Y5yI$DfR#)=`dHC&&)bDC&_lj8m?F1F5+wIZWV z%~*3N1MXCjY_3M~Ig1R>M|G=jyFPzNAWEJC3zeO1-|o7bAm!&S#E5g{x*0(V$J;+8 zXV*kW{xYr2qq|!($nJ|NNTC&P-FA=lim#GpdroTrV>nJ%X zk;DQ&@eCTF+B9e0!r`QoFsGYq9zqyI>vj)P^KmNYg?>#Am?u&p)8|le9iyCK5`tJU zcgyXQ+gF(tj}LbkPq>u#`!>61hOkw*s= zGWNtEX)q%>hjrr{D{4~y?UD6wV!u3Ve1%TRgnyu{{6ya+W40shlhHIXOFfCeTEOPZ zn@DIfO9>5KrM-v0MN4}&lr(*={wNS)!tTF#mR+%qs}X{K*YzA{$!)%3H`RPRkGu0x zL$copFRk-D)*Q}o@MaNJA?4so8j6F+0uSE8?xs^#LG#m4xjdz<+LoXbp-kGmGmHW< zFWYC0&-ooKB;{AnJ0Wg(_BD4l1=CxWTj~orCN*Pc8qJp)U9&Pb_Ml7Fyi#{bWs?jo zj{Zuv(*;|n%9@jkHk3vJjSvO!u3d7k2}z()Lo@~+!S#*zKC4VP;vna{%ahX>Ff`1W zlChs(#DePqyqqt!{VoJ*jge5=OyV_pHG zEE&7Jz-ZtwJbl{_j@^+c>_l1I1UXrp;Ndro&`%i;#_*`-uy6$5O;mmt7iN36l6u4= zPl;EUW$7=L`^m3~edPmZ7DtA!b!|Z*bI#p$l9m;=(+alVTe*(T?Z)qIh3D$dkCP={ z>_Mm|rqyV*%uHOQ;3Bup)^;YU`3k56g$1n)h`X#8A7@B?TC>yiU1hORp<+#orsSky z5*K*Dt;TwGkGoh!qCGA8F#h4H^M|v90Qrs{(=uyqiF)bTI8&Q7ho-f$3UvwwR&H8E7}4yv3DT2ogHku5^VP zgZ8CkvtAg{6`meAJvDzQ8#sjmadZWQh+Ha?7b)jgzkmax1wc73S~dcm188eD2d`oW znnu~#I{_-w_HX!sU09YU($mE#rh5k5%>?lr62;42AxQ}w#zvOH|)P2 z;zgw(_A8a}8EAWf{|Lb4QCB4cCd>?o`y}WyaQ!VZo=CF_IVycnf5bpg&#L&t7N>8V zQOurDL{!-02hpRb{IV@Iv&uA7LIr-Adgt7HuFA>!!7|89d|a2YgXDYvjiNTo`7W39 zed7u7mCo&u!Q0M*F^1R$E{257B5h7aU*;#Si_W*cH#r*Mp&XIe0 zV90kqz+i=hdg`HN+RPYM+hL`sydx|ezeTKu&ET%mtoo<=L}j|7-~-iA%bs*{I-X_n_pK7fAhh@ zZ{C&~4ps6FPZ(L@vSFmm3s&rO(sc>s=VMzCuh7(kxJ=PuX;a!8W)6>IJaImvpVbbq znR9mPp0f_8kZ)$58@(${_N?TPHz%1fiMoDU^spH@$I%|zA;<==E9l7RM*pID5>9r| z`rW?4c*dP-lm$Bvjy1xGd2n`Uv3q!;O)a{cVXkX(U(^4a#0aI$J9ry zcMHz=H_C_)`Q)tv(JKjwR>prP_%+%Hgz5DvY`4yzwUyXV0Sbw%nC))ZR{30}K zXj7HP>I}gmETHEnXh=@*M)kH;@9@79NjAF}}dw`0)Dry=ITQzQ{?TBm09RQk)DHEjo=r(XxmUFqqJ;0Hm@ zK##@+KLCIgIHO0wUnWmI)C9Wtb=DM2Q4<4rnlFk5SXhD>uA3;(P)m6FtNM-b2v|Tl zzEW%*L0^ zk*fRdm!%jqKl~Fz6Y2gz6%h%H@KU$GZhw*E1#mTdV5o$Sn*n>*F6adS3U7{ChDHpA z7|8jJ{VjCrHv$pL8u$eO^z1hRHAHM+t=g}FB7D=~E7ucm#?=oZ(*^@CvBq#;{6Wsy zv-}KW;J334>}+q0f0t&u){~SN=Vn=DnhtM8Yr_w%?V@}i)M_d-+-1-8m=B2=_nF}U zisfyKp8J?&szk8%#vKv~e^L{;^8k2$avPRbY&O}XBr3Xsug}O$V|hyohZrFGJFnv8 z3o(?8kz9v6HSr2VjC&uIC zg*v|fIuw{#iE0$ey4|9YpuycYs?-_OD7Em6fe#sC#I#L zyb-kkqyE;6ir39f?Olz0Loa9{zWhDk^mAXXq{Z}=ZVWEP-Hac|&L^)quMPawdG4S9K-+;>>w!oUZ3CqgcLhqzI z0p_u@nA_}_;D~;GV~qk)l2<2s6_~>Su>DLldc@08bpN$2UX-G{I*jeXS^&6OA%Nx& z>Pi5P^I~un;NmJiw3q;y|1uE#EFteK7@X)$c{c6?Q_kOZS&;I1wX|^T-DELr+EfgxcZSb!C`}|ZmY;eRku%No9{>3{Wc5XSJ;mHpZu5wO z@P5KhKgC8R#M~#7sJL$b`*cNkq(43>Ld{3rjX7zdTdnmo;ZJK2@IT|zMPxcc_?;LK zoUDu)28IevqqM#k(g#edlLm6KeiIfbg1&NM#Unj!ED2aQR9gRxO62s2P~%Y2FFH%7 zrrJ_#trgL?w3R+6^Gx+)(X#2uefMakT}MiTl32xk=ZUiifoLK2jZNoIt4TL|0!1qA z^oaGTK6QGMPD`E|LZ^+z;<+20AtL$67;)W$IEqqfOM%rAgSJm<)@arwI?@!^x+Ao#oI=rt%mfc-yUcs1NDj++qDSe(rbw_OHzN2q;STy zRoQNexEdgqdgG5)kXBC5v?(6e9gSItWWEn5sbu`@N>FMV7TYE~nBH2j2#LeaZCiwq zIS+pN0)5Six7}c0BD`0{KUR*sG2-Fwu!^lssO^MSRXh$e?i5R^2vI&RhEYXn6|K|D zJ+?O)kLMlqe2w2KTvIf3+oromC@{eHcr!#M!p{JnhHXmcbgBxk!qHTsYn?vLdf`ffryVUf@5ovAMt2 z3?xmVY;HWbYl8ZdOorCg<<75l3g+|s6f)>yzn|d_&WZFg7<&EYj#>;jqg^-FWLP#1 z`myqR|X!Pz& zSFC^mXXNC3Go?`f2~!Q{4RRb)W6GigS;H*ZLn0kB}#x zdK$ClTiF=dN{8J2;IX%-FIQng8=uWEDW2*K$tzv*)Gyl=&!xSa<~n^(NV{&KZSE7s0O@be)J^pH zmZ~`MUUyP6tslR~HV$CHAnR*T5)ry@tc1n$^lvM#4q70ghWO_q{GBoePOWewe z)6J*{iBvWp))EqYrO|N^^+Ud{O2MYs_ztB!5`CY1%lkk%vUk|pUeA}iy=wx0h{Wy% z&v$M=w880-w0EDB*wZ9eb;l%2RH@oIKI^yKOk3qvbFWoi1g+wVMdN+kJ@<-+M-)pRkybSeC%u15LS-UiqLuEW)D*w6eP zAn_r}f@9$0Js`{}g6RVQtGb7kj`$C;E0l5<1?3+Z@WO3!Ni<*47xpCoug))gfLC$5 z*KRuKFdtUSRn2HTZx2*^vh-o4wv9RZ+Em=R|#%kTv=f+O)ExC(Gl=ZOEZ z*eQP5(EOjjjuGG*`do%U?)Vj$&-~{=ISFXS>pj!agLJd|t z0wN7~YAPGx%Q^!`0su_h2JPil>F*+Ea1vdY{)Y8AgPH|&ARt?ly)!yy^{-I?NA9(c zrw{ZD09yz{K}NXDDSG=Jbnz8j27rdWhwnrL>lf4;<&o55dq?}BG)?Zpj<~{mEv@!A>8QYH$FQ;@GF3;Lrx5g+$~=y(i)7s z`G!0aypt<||0eb7*%D?TJfbNWqvjNdAM*k|0KnX*5TX(2KuDZsw{#}&XYg8O|BVT| zKFMuBTL9R|JVwpcP>x$c7k>?c0LtEmKy+EJqm2TH8(H8N0I(GbWKsCbdOJQ6JSu)b zxJkNJ8bEmZO`(J`(D(xX+1KWxYAr{l2wG}CvkH6iq|kB=-$qp$zct{|&mw`_AEJlF zGI;_|(Z|Ao{!?9}v8olV>PRGuD?KIhY1{|rEYtXW5BWoUE<1)*NXlJL%=DvQk1^SJQo|wwQSM z=Uz^oI^3|eNtu;R@q51x4Ijo4|FaZE>@^uPs0HqqcC7CqFEj*j&|hoRTGkP@vu<0IA7Z#Kjn{p|w6q2y>3 zMnN2nI^s=SwsrbviHynl?gfWE+5vpZW|;AwCgG~Q3pH}Z;*-^Hk{?7!Q4?i6il%rj zA0^{T{$SU^g!8LGHJy9Ei%+sjWx%WYBP|xBS)8QlPm>WF9nUu*CCUxcl7-&HDo+F8 zH0|Q8Z#(87io5To(ULpqdMS;how(j*J&P3R7_HA_KFXwdCn?|;>cgUm%Kgg^Y0JCP zV4s^bUv)z9+b52F$5w-o;f2#Mv7mY!GHJv%#a)6Wh#!9-e&#}Za#(y&Wg6a+NgVow zQl07e^4*0QhEnPk2xW8sQQ2J-I3d>G^~n2mJV+3s+$m$7&t z5HfJYESs(QOL$nK%KJcE=k|0D-aFO@ZCa$CZ9W#f(Sm5dOL47=qg1XNB9Pubq~&f`1DAV%6O0dXX=bR-!$UMkr?< z-?l=NpZd~lBumQ@GMjdoY_w&-cc|08?Q}||F?7eEI%1FAe$06BLR-)qMV33I2LhyXq9K>+; zu44C4?qP(CgwC&~eUsJxPo9*A$-Itn=5mm1fqj$1GLs&wQVy-9Li$}>ETl;5^s1+E zCx7WR7s+B{S|F_gB#K=mi(MKI@w9I}y|hfwjDk9)HyeNF)c^$w4 zN()~fflOdn02ftn@F5ELO1Lexm0HKLGS6L}>#a53L7_c?mwU!~VEHo=FvwHNGU%xa zZJLl+e#RwMkfK@FfQU{boxw#8;(yLES3v%@&bR%6-Fg4}XNw~z%klWQjZTS01U5oy zx@kx&xgK5Bksn59FyT~k%;EikcT?|9#)k-33Kffw)g{sTm0=K5r_bM4>xg+yh4dtl z#_$T_ZS5z~j$boZL2^>UUf+s~k#+DxQfX@2`_7P=;~hvb=U1sxHn?=soWb=+&t%ewpHA z!CAzfUiWx!&uH=%;(`G(H=tp@Z6ucYof7G?K0HQO!S*SYQA@CR!$quuWjzD-P|fH?7jW63%%7NcMD z{0aK=fG(TxIaBKuA7;!9o28!Y>ElqR3BI^Rr~dJlLwYDeGGxwCBg%2aN$i1E>0y(S zA-_)f;r+Sy?GJEHz6ISXoyjuiN&7&RwUqXifU)H?$A6H~^ZSWP$_vp&`zOwYX+u<1 z%iVq)j}IcAILMTU^l<1SV8pqgH0X8tsMaZ=V8pO{@f_c8?Cy>A93w}~E@kqHT)cnX zfrF9s!((-KlwGT*u<-DXWcSYr0eEvssp^LCP#6lUW_PTXvAn~8zdIuuZgm@CjcyS; z)7WC|LI8RZ-lwoW_7V6XTN9!`^LV+gpLr>K?4K^=wckCKQAp?={yB3uMk$6@M#Qi# z@%U-9!C_c!_50TuW8++t^mYMz6p>c)A#1taBO-zZ?!*u(8BU+t{39Hwl^*e)Nax94 zRMhBT^#KZ0z|Hi32cBIP?c?cx81@*58hd{^0a0-41%~;seI?y)DOOpUHX|1K9>HIdZv&r~JX|h=9ER+b1bffWBSe&iTdg9)`AQ`wlh6b?+li;bCwbkMWaXov+-#V&5N~zz6*5`&4R*e^g?0-q@Rjy(pN<`bgsL z9nPZ`R$T3lpK=*pi;Ag>6;X+P7^wb8=)X41Q2kkKQxWb>1yfqA>Tu#|iwo;wBG!o`y$e*4aZUg-e zVEm2B*uZiWQg}8^SlK;ct;fOu#*6FpH3s$oUxg_9a1^% zdk-N^4w?5h2?CuAoyK*;Nkt_0@axQ03WYIv=opf@$h$F_1<$A0KlaTDa>Z_!Co25x z7!EK}Vl}Y$UdhYfZ?`&1y?xTTxuj;5M5g`WShXA9njNynrUBV?s(>5(GEPBX*9Y0t zm_b`GtMrOro{eH*AvW5TUHxv$uBX(maf$zo z({9uff34+TWteOXRO*USO{uhA9)&4!a=wj@U&Od>>^r|t|8m}5XxqMxOR3Ne zV+{%R(M8DbK9b-3O%6>X$mCx8=cwB=bzYf{>(VNo4*=Nc% zG0nIodM27W`SP1~s*|X~FeJX{ywM2F=Xa!6!^356?RZY@{jpDtDE}@vY_MDyV}SeV zrjDU(47M%;J>Uz}Om;khk$@1hG@uk-*kwVDn44XJ9i5A5KF0GAToWeBO0FG!){23G-K@xF*c@RylY&)R^Jd68KK z05fkx&_YB6p&L+zIKYZ-3oZjdZQ_sz=`6rN^`iWa_rQ`yzX>%4E~YC5I2beqfbl&; z$3?g-Mmtpmyl^7mG5`#*7*zlsvJY&^L{u+@=0F!WXVnGI(UmE?1U$_J{-dF~Da(Z5 zvlG}wy&Mmz`$!}#{?LP<_+z7$4}&k(g2!5?|2&-17>iV-SrK`-&!}M3my@go1!3l* z2>JG{Tve4Gy&82CC-TbCE>B1X)9k_a*hJKix;?7ALlLH=T8g=1=L$RVw16YqO!(lM zzSgm3#<%%(6iW&$y&pzyk+I@YD42i0+bb32G}38CTGT>u&MbmoWIS!@6WoVlT@tik zwMaL${m5yF9%cJbr!$kuBx7N~(ZX6+$^IE#iGXe`*$~nw5}UR&6vGbExXtjj3&pOZ zl)BpPDRNz!cu8zyojm@515!h1zCtlW5s*D3Z&PGBckhUqFO~|-AKx1vU<;0DnJMkL zL*!mGKNZ_QU>|>=VWy? zq>(8d+sHLi469v>ebo~}Xtir8$+6g1-Jl!8ZV+zqgP>a^$C}7f0Zs5MMasuYF2b<( ztF~p*!H7{_d}Ru6y>}nnwsgy~V;6pd0L>Gw4m?<;;0vj!g@~w4f!Jlfet(`@bX>=% z0|!pEYHy9?En>NfUf=OgG?WrHO4YEFE&FE)_79HBY{ZLH{P|21yFn;r`b%`@i#K?ME^8`-_a( zTK3`qjBjy#J3^Xu_tQeBSEp%FE&G0_b3$J8ZHPKIcO}X^J!r75u6?Y`p8}zT>-B%;l2)DE@KQ~M6I+UZ$ z=^iosM0bbVqiV#}ZGtA?%dh3+qrb{AhytTjcHckb^Q9eqRtOLo@G|gFb#+(3n%TdJ zE#cAOzgl;4V1ZrWKZ|B9Ozq%8231G-0`ENU1oh@ z;PcH~VYruK_rmRue5-f89bP~uqWn41=^rW~WWdSLj%_4uD9pEK)->$RwTndRtza-a zcyEw05ZXk~_I`}}9>Nv@`LJIjGCKJuJN?m5#O)z?Vyk)Qr(-x7Ot1$=`rZ}s>ZC>T zgPBfsNMDG3{Z|fIl^$fH$p0=McHz1(viK|GyJpW5;zQ|Z{ zuLdSVdhkjBU@6t`O7L{RL8mEk9ugS~WaOKAqd+&lCVnpgZ2@4&9T+87bGazEw ze?h@!((+Tq|LJ%CkD4PXn0kg;ALU(%c>0h&p*t6dPMaAn;?m(67vy}8e)WgD;n%0- zFp@l7*Q(NB+YL0dY(&WCu|CMzpY`f7!3q9X=M~|%(wAH=`28Iq+_w*SF!6x_vA2#;y@z28w`$+U%_%R$^bw%U55 ziX({gRC*HK0M_dFLdUhGhBt75mby3cQ_u9_K{E$?+OQMk?X>oik9{L15r<=p24m;g zcOhcEGxA`-m#7&v5hrM5 z*GKBoXKG9x73(8|elsCkvt^H*g}JO;xbn^)y*V`ANqO~$#+SDExaz z!`O809A(oPAD-l&zG>cBW@fEtrHF=fRd_%gcH&TAY6*wl-1t=)1rQNKB#QPC<>gb0 zH*{H%N%@5#%ZeK)KTqpuC=-UaXcr?7DK*!J-!?uB*dIAMVurvWQd%m9`h8I^o%b&M z{^q2)SC`d;SJ_#QLTs({;EBD?lhCZfy8;s@^S=yEh0FCPOxz!@rq+&x+|O*^LovmN zrKFpldhEKCr0gO}vcxJ0cA~9VwjN>ZWhqN17Vp14N^ovk-r9e?*zhLrdvHsYwA*|? z;$FH0i?Tgc=|t1WsgQ6@8{_#z?;EA<)2}rd)|UH!2`Lwx!Fgn0_IHDW7~o>|6GCUm z&;sZ}!9-u~B+`ophj-w$2Ld=Nc(05)-C&Xfzzm{_#Ux7m^K zEdZ|8=7qH#>lVn<@&;D{V63;0hT$)XpDu6IEd=~7x4{1Zz>QcCK>MmQ;Ag)nHa&iZ zK6aVKQ}G#O+1zCDjDE(Hr2~4p=6w`5(rK{y9$s(0AiwIG68k1yY?&GL1Q7@~SA}4% z%w*Tn%+(Mtf)br4KDc~66xj4W z63HdA7gTW%ge2W4^~|E^)t3ZldWImEeh~Bl0QE9NDW@j|R^FRx5g++l4GOwA~pJ z4%&DZDyd%<#3n+oA>aDbvxQr~ej%?^>QVU_zSw<-R|<|%NNDI2JDr*0?GLJjLA2fE zGa;5$G%D30A46N#rTCEG^_K!kH+rb_RVJjKj@b^F>}DsZEe_fpHfc3wYNt)a9+C}N z>Wyq=rO4}hN~*e8Ov<%YSsNl2K6RbXKI;e=%{m$>OrD!Ld<{_@idTfKYq<(njTkC+ ztaXK1&!j9CtVB=Z+E%;nY7b~rf0OyS;x*7-HTKRg_^!3u0A{NXUYQP0T(tu{6@KCO^UHp+-UwTCUE05Bo=QCnW39DLya# z-yW)>ae9h5R^N7i^gcD<7Z$y_1Y?5ns&S|LpR6@FEfo)(T7SF##8j7~LzpkB(3J07 ziSwB%vj|*GsX^TPG7NM^^+B@-R3*y#l|}8!>xZucyR_SxAWSY!qZT4s8(iZv5q46J zRhe{X9{XKMP;Y#NVInTG5MB)_y$8ROq06u}j5o(&Ys41BFB9MYF5F3!uAEr^);e-1?eWo~H^D+u7K-sPpfQ!@d!&1-!JIyr$>iAZv>>O;WN+yIRMpkkh=B+$|j6v|8b`^#d+ z*JO&tVDSQ6?iTd)VDUzt4oVe(P3NLc-Ob{?mMKs{TYyUugmfFR>~fRJjKYfY1dAR1 z#$L~RQ+xip&I|NM4cWA7!J3&R6oswL%)$=ofO2_y-ZTc7 z3?VdL%(Uo@pOBE?hBRrZqPBL2jFC_xXu-A%#7@tr9RBDEf5R?N&>B`%gZ zmUq}~Q^8*Mb)H{a?QNnML$0)B60>p&LRrf8fj3*G+AU^()|{^mIVg0qY_xKlJS0@L zZzVDxi(xA;6rjr5q1#T^Wz3Nz{<1bc)a^3ybty8wlV_FnM_{-y<5|Pz<5!G60ipW* z=6P*V(H+ujvdR&y91xXU_`=%EymrC)BF)o7X&+bL@^2^4lg)zWOt{Zo&$>iModu;) z&~p!co7XG~v>-t(c!dT2aw5@1ndkNj@D=Xt&-Y&pq&Z7`k|jg8v?Y-8`qG(m)cf;J z+{d7pCbur6v&zSNE8*GH%B|=1g|FqFD-x6RbNc8EbV7TK3w}dBUOIXac56Jlx2*Af8+N#&ITMwA@S@lY@q_2gX~frPhO^?c_%HeeVJsd>!a66O z2ZGO$9BV)SRLhb3S=Mx_+&+1z>nbDL<0z7fEi|wd9nY)(u_x1jQ)}p_^x2=FRS|`3 zZo;@IYn{FnPN8OEh_g?1#J;D3l<1>$yJ__ll57VC!`S%A)DNE9{vFGAE?ndY8{-L?sfqlO zs#`^M3KK%4aGh_h5TH;vC|lWt%}?K!&qe!M$X1v?khW)3;2>gxOLbPLjnu_b6mSj_ z5l`HD-)&)XOi;Tfa3-IgCY>89h)%^IR;(4_iwoL>=G}^_GKbwck8@f%TxgS{qpfVE zcUNcq{W17k(csi8EUafRmzkA;m%^!)NnP~;I;^9C!QRrpWA}3{MCM|Atcgh@yEtE` zj6{p_atMDkz$bI2pG5((!In8@F;{19h~yX#t1-Pxm?Q@$}HPC&Usmzn$cG za*Fe3du_k-*lT-#mU!Sypg^IoKw`Pb+a4F`HbL_u$u}*|97)cZ^A4AEoOLQO+81SA z8-`x51`Ne5;5iR$`eUBUn>M|DA@jQoKCbZn zjJ&Bri`gtM@+cvKiP3D21$LrvsW^%%kCxWrFcZeEJ{I+P_i8x9%Hw8uy_-Nb#8Q~vn`G;h zV5cAHJy0CF{~5ydlq8(D?U_}|2nyz1Ms*$37oo^0^=Rc;J5uQrsBy%Nb7q>eS`VR` zDTsl4&(!zVT&UCodGc)i`R9LrN1**{~}~G6jQz*9%qnT65?hRGKE7 zD(l57Gr=U48ebp8m_269__FK7WACAKxF(tS;Nl+8Sv@>iU#;htVJG4`S@F;IB;aFn ze^^jDeVh?i@p_KNu-BZiny>JW*z@NYk{nxIJ$DZ;c&{V6Jy|GK;~x&v*q*TNs4nTW zeg94EMMi#n`Fla<4Y#5442vAqalCo^a9Iql1(y!kT_1=e*z60J@{#=t zZOgKddbw{n9jDgV;`wX0F?#rsk6Lrl8?ENx!bon%b-b{Fql`E*q>BlusQfPv{jjPG#H0M1b<Phy{wj0xw zMxTUU1|}6-<&vcO`a-K-R3@KT8Ykh93)ulzZ8eI@rGRYKc(dx8eBdt+#3m;H3ejgGd; zgCdsZ$As!7rWGr#yvbFz@eL{WdNYUSU*s=;KuJUj5aq2Le=`ff#IE~$W$g_mILFV` zouD+E$eF~1mPpQ`5NrS?_<{!*h$uh_0N~wt_)h>0hzcF2!<`2^9RSH3P(;;@r$Ldu zd2bWY|I=ITHbE51(QI7|D1gsoBx^7dz?lGI3a&7U1G0lVXa#`x%;8hQ;c$90slcKye~C zS8*9oNwrD3z-=bLF92u!%scQN*ls&1XaE(-Dxha5*JF@(7_B-U27Lh#!x?xlA*g!b z_aR_9#h@7g@e)Ejj|q(j_ry;CjMp+~27nu|Vbj9p6NtW|l6b8211&aM97B+NhkVCG z<=wklL_Ca4uA+Hvf&zY?Xc5Q+jDy5~Na&C6l`8cDWEfNSm&hMpE;b2JTpde`*S=~z zCF}zIpgp6|8rX)Rit*kh;*DklSxHuw-Pmx@sqYgq<0*eG1CNq!C;A3vf+Oxc*smJG zx84+91NN90bludZ%dYYZB$d~92lj|QIWS_RViXr+v^;MZ5ufFpuiWM(b@kcTvX~X7 z+t3`mOqoCz?!drID4ff#Z4m(`1%bIA5^P&$X%6e3RC{2Bhe&uP8ZK0%T%`(x<{?EI|FZ$IO) z9WMTw>2*bv`)AHbvNbz(zS~rBl5kDFs;Ej??aOlI#XSY<#NaWpr&DD*Dcj#+zqSQl{Z3L%bT?Qc;D8eS}3132h2U&xixm1?{ZPl z-BV7j5o@m{ii6N6uHSr0waT=%Tp78I0%K*kOn`v9fhKGW|^0D_Y*^$mWJGzgfRKaHZCyEdmws>a2MSJfc4u&zGpXFzt z_zgzR1k(XHBNn&8{niG7{^2Ir9{|W!S~%wrHW?cjJi@#zHxs;?LvRD+P6qXY&jXXp zL4N>14=CW38<2dc6d1{~6X-pJz%KxZPn|fo{?V~sBtA1^{hg=<6{Ypu2{=BT^F$#| zSk+JgFi->)Fesse1rUW)cz3a&#-RDlK9I1`0au9JecXB|^eSkchz0o{h`?3%m;K|kj#XzNF0zOY?v@{ir0|4h_#p{BC zuJG&)Fqah23IOliz^i2E1Ow3O)hZy9t7m`#P(mA$$emGp63`a_^=j-oa45Lsj2@oc zy!r6tj!+fzrPCxau4;9>cimUL603s=|1t?6qpx^5!58`s1^~!V<-~-b5)?|@2ew37 z&k`$P8p+~3cBKgq3=v3(^WEfTkn{;x4-l8KVx*Xa zX?#y8gz`Dk%W+r68r^ANEU z?wO$zJ3f`vYQY)x^6NT_R+BP$R!#dU_M4w+#>cX(xDN%mezy3LNJsd+Y&YyClZc9e z{rEPP#Id)x|7eAxG~Bx3M#jA-tSXBgqf95#XUsjqTa=~#f5BAV+z!4+%pgLyOT{6;XYlU`= z`e=%qJP66SlXG-L$3h~v-jnw17xAL!6ztms7o2$_diA;1di!RAN2Tc(+HEJgjyMZp zSl4oc{>spXm%IKF1G|WAHND+T*X2f&U-!cV;tz-!)-<1bYMB;LASTiZJD&-U{h@s> zQ%F5iR&W6x9H~CrDzUveNAIuZpdYvCt{VUR;TXi#ZAcptA-;*!i~!1-#^B?f3LRrvDE7e;@{e|y1ntQW1se$f zMWhA6o_m`KSP%x#2!QySNqhwYV+Om+S@01&4UE18L^9OwLh4k{C@VT8_y6p!_nj~3 z1j)PzNi0a=k6{|Ur3m_wv$9*-%@i? z^aQU@@#MX2ej&mQgW0S*uyA3M#{1#jTPs4Pg_|OTmt0&#GdrFg&AfGyZ;)QOV*PXg z<4>S+PiJhkY6H^+3!3M)Lh9n%1XEtv{U>_V6;%GBbuXuAeu&BgFJ(y@HAfA3N!q2> z)0cJ=UccD4(@d`?lY0sq-gokMBnjem^+{LVo%)S$GyjBRdDs%Ocoeoblk_rXnF9o> z$;JuUG?eB?sT@fqz0M1=p7ztQ<;bbA<5M;l%Q!ghrct*OR!aPIsW#%F(nd&e#hagu znUpc)6}zQmn0vGpn;)>~srwNM?u&kz4{#gqtA7r1))<8o@qZ!g-JTYZDo(1Y6qwP` zHt@TPy{7e6oJQd~-@h@vB?yRT~cN6hT9#*Fi^RZkFYpa{d#d+N@sg#CdRhl zkKutlPo}g}-Zxrl^{O|p_O-E`%>Ht&q=_LeBTsDQR*;W$mHJz{$$W6v;*!?8wwEbO z8m69OE#>>IF_wR5+%)X%S_j)Vw4Os&LG)@&eI z4RF@?pS$OLKw7+m`wJr zlDk7}Q+)Pm%&lGrR=Nm~#6-Va`}y;yEdyD@CG$GbyPA%tFxVi`4828;S~F+vH4&GX zg2q(?+fbS7xt~+QE;@dPnev&0N&#OmXG!N z`$;U=R+VH2?x;2Yx z$IA5V=EU_G(L~s0`J$@UE}>V}>|uj4zFzNic#91ky~DDr3&DN0Zn^5uvNDr~m)-9W zmA-XniQ9r^9Ia`_6hNakFC;wGtyRM*v9Hec+O}I0JyblVUmbLq^I2>iXo%Hj>Ne?X z-!`mFFk$#mMdB7K7#AXJ-?-@OUWT!?BYpkA)bQ3lQl%R(?K0J6_uPR7AB6PAGMvRG z?{Qr^W+|!4(1UWHZ*o%b^(DP4Cr&DPGk3QGcg3&3`^XFMcDa(5mr-r`PFs(9n zD%mPKO!Wl9K-iY9Z1f^TP?}1yi8!IZY&>xvQ!kf$cRO#WySgiJ(O_HZ^yA{e;Fvql z)=7VtTbT3y=#|;E)Q+KE0wMnA*dMv8v5lTcy}Y>^&L_IJ6k)q19;dxYYpQiC-*)CY z9mfrYS!3^K^weaN-@Nv_u=^VPAgy~F<%#a3r&7-i>11GIgHu^UF|b3ze?3QXz>@s* zavIA5y(CdI8p-{hc}qY+(hem4N9e14F)BcVF*WHF!%S46J4p6htEB$@He~r_ctKUI z9Z&stZ-(7VwB=Y&-`=RHA&}lLRrqWTqbpLoh$9%Y0IN1_jVL4*amrFmb}unKj)dV) zdBT0liMK;br>nN_Nw1EUm9dbqy;^unmi1OH++#>m8VY1_5MIy)4<-zo?+R)7N&+c zY>Cm@3&kB#XSf$vL{&>;BTf`I?}N$A^OeWq=*W;c;p22m=4%B@8%&#mj;|LE4u*T< zF5_lWKgn@x<@Eg!W$^5}q6$W?$u%KHpN@gs1VO*$K5k0n*_ts#SmeGpub@pSj;otd z8)jp;_i{;+`=iKlxQ8_hUbxXy@hyFrT4#FS{h-vDi%pW@Y;eaSd!E^T)#LZC@3Ome z7tT;qY{bd3JG8pcUU`}BO3Kx5xLhLEq35+@VJGkW!DWEKxLX46ePE3Wtepo- zB77{o&tuYG8my`V$*bW~4->e-&xwFE`e z=dmFbZ!Uh6zTC0Xul-pdt3MqPlX>g2go@Exx!axV^UYuGkBncmUdR2D&u368dRVvP z4Xty%Lc?&EIq!9-AUvX^j4SSUgx}CJw|nVoGSmh+w`()2cqYVSpIphK>vo9eI)47= z*Wib~y#S~67OasGzR|>&@Ydn?21-6$lOZcXn}12BJO7_3>oc+A|41lE`+Kzaq_rkkkG=y(CrT(a)RJQ5!u)afQI_{r8NhKmtL#3kn zEojSP!F-+LL#Es0b-4BO1H~NU$I^E3uP+Mh*5>suWrV&q_rG13c00c|E3H3Y3Rkz& zv-={wMR$Z1!35ttrRA|%%P0vvyGptu@xDaVpZ!guN6++c!1j#fm!aW^uaBvaeCxA0W z7|46CYaU*P2nW8N2j{+?NR`ytH`D~*1OU-?8Ip+&1v!P_YtH}|ngp5w;AGEo@lT{1A(|4Y0>X2^RXA!CA=@b{2Anlm=bfB|#L$ z9XA%1u7h2xx@KmY5$k7j{AP_Mo#kWj&?~NS=9HMgMTNOmo6D;!yvJ2!n{O7r$@kV| zV;5-dla9Bt;y_oZ<}TVy^a&KIuS`9oSGKMh4ySr0yLK7!v8JWY(TUH(NIAxZG>?U` zCaAG3ZhgA3ABQxRJ%hRT(JJO>1a5=<$EpHm7-`B?nFTr_mUV7J&x=c$mCyJyzBSuF zjcs}#x|`TbW?NM}_nqK5?oA9LqWXrEn1;wghE&N8^~RSC^fQ$&JTE&cZmxAc9?0B{ z6~EZx-mFkcrnoH<-C^ZT%Tlu#Z7f(qTv#<9olKTothq%oLMb+PuRP23DDXJ-TLW9C zB_Rx+y{}~qd*yq#XjS!N%feUUF077qHKC{n1=VV8$$CqubU8CSCv)G5a$+SOn?5|ll5MMlgvKNleJ^Q%G%1B5w zRvi_U7ghQrw&KQyzgU`qr`tiJXuuy@zK9PzitSqF;@Vb%6Y<4UZE8jz^~5Q&dgo9@Jy8S-XyPkpai=pr`t2x zA28+dOM5q#dYQBFwH=%ixc%9FFZo z+rOMTZP!;Y_)z&XuE2>X<)tp)H)j!hwd)o7j#FQ8E_c}ZX#1v_ei3utFD(XP_38SjOkce-Di$Xv*k_0}fNCZ;+V#0Dw|#*n z5$Y}7a$J26_ne&OXWfx&%#*b8zBjq@Aw1mqN$MZdF5VxmlfGsOE8D$>Psi`5Rk~aK zib9ZUcYYPM%HPZS+eH=V=HZN{Knc_UmOTJM))bEu3l$BGOw|mRkpcy$&>_)hS~U}J zg+2?=Rk?!w41n-r!MzDV#en}$o()iJ^302<7W4%`jew8jx9zDPX?=kU(34!mJvZzh zdlJ&a=CEAtvq!!xUi$6TMts@VL_HIi@0i++H8l8}W}}M;wcR|w7d>}*=N~Ov(ejX# zeLMw~hHpt?b+fVBstfI-YLE#zvaGjaa|{(HIg=IZhs953wL(*dp8MeS4J__I@_Rt6 zyTV#{P3lR`}5qQb$L1bSJ+zC6ek(oZTERdQznwA zFZ_T#5}0+Uz1E=JWcI0hjXq!HQIl}@^Td8V`OgL(_AsG4j37+swL*<5GTE!QQ`3$-7ojU*NHyH07 zo=ah;<-~>OP84NcQeIxny2R2|sv`Pi{8<0UA@$ZnRkf|vE1J@qHo4DXrIMFJw6oj~ zdTfqiuP!EBCi$ea+$ zvnAsow%xQM??Xz?Y>V`W2*teZp}^dH#=#mi3dY4BZk60maVgvH{vQ&L$B1k6>Yrt- zg*~#5Z~75RviIdI=sX;7skF1YuSB+NT59%a2{$?8g5*_1)T`-odAVeE(z~yCpRj~q zsPC9psq*0x9ONymxmmUrhJ82d%2S5a5ylYt-nZWx?~`9Xxx*Sx5q14R?tScH{rv>9 zs!@DN7Pp+NzRXe81^lD!|NhL7DU zv|L@h3Yo0_c>8e1PCLz|y5{5phjpoIs|EGoD{C=I{b~0IpIbLh-y;Yrv<;63`KkMy z`47JAmR_}gIF*6z`EaTzU&Q)YiH&&c{XX<3-}A@&MLgd&5s!37i}jFyGQ&P~hq&!| zdsuEk^$?0vYlE--Kg>vAf4N$MwBfpBDyu?L;2{5p(-1L02Lz&B|Dt#UXyBgu_%~3> zYfxG8pZwc@^M)vYOYSwGXXgX-0sx`BhGPIhm5ZyX1O5e|t|Y3qH__<@JW4iiBZueWc{w)NKbPE)xMJAw-VgJ;e<3VpUw#;M+-Iw z$nNf))c8#;vV?cyPQS0LH4^Omc(V-Ojmsx7T;=#zJPZaj`2I)m==I<|0U%y}#Hog` zfnaOh`;Tv4#00GMdDU4EZ-8c((Gl3ls0D?>m zlNS?;v>2g`NoPh2wC5&DPYI?1=am4~)?9D}0MfsV7XD0vkPVsyuDU@2ep&;!27nuq z5N@K%@q+LnN_hSesC|BJ^FhXFvwZ}wfOju?Q2;48pO-hkZXkLVuQv-u0YGs4hTMZ7 zEl*Ju&GhF**rFzz8=$Yi4L=hCTiV}=q$UV){GrIWr^|kT2^|Hq1VG67VO_<9f_xhA zyfN^&;$Un5MDG|TShCij`8gvf$P@{h0T6E(vF=0IfH_*1X{FGg8q97DFsA7G&!T7U zFvDPE0Mv@*r6OTKCg6ywnfNFFM&ZmvF$9KWokN`NKTQE+#DD;%bJiK1UlYwb|IZ4J ztOTXIDDT8dV8zih5O~~q+E^8AvNS`8r{_)|U`}DRB>Y9L`c;H!&+Qgk2=0wFrp&Cm zaQv6~mXE86$v4tNEt$K?3(H~ypDI%BoOqoWuJx?5j)(Rwl8DT!E?oNcO4Hysp?q_L zyIW%Tp-+HO*^HFcub+&IoRlYl^QWV}d*u6*83)6h*38z|__j?l;*^`rPV7!{PhXu> z+A%vbA;uQ}N>}p$ygnlT0_7U`XcdJile{Q5F0XlLDoW2b?q;C z2c$Ve%RBGDC;*7eOb8wXWmbc|0TxF>&nQfugo6Lz>|o6YwERz`Rk5LFhayyCUccfSLu@2=NOxu(5P8hy*>JgYMZ#;Tc%P zKxGcmvmM(E)(!w_?Ub59tf7uzdTUC+yCDG#1b`q{#!bRO)gR6b0$$^A&N1P0#!+bD3xzoE^%aM>!ti-?nV#NQw=WN;HhcLJ6UxMKKRHV45?XG>WS zjE=;A>1b4^6@?&KGY3;}_Jas|^+Ln2Z?#b73zVr9IL;)*Pv1KA6Xr#je7{Gj!c1v~ zfH)ekd`luAU(Zw@*b>lx8XwAbDe3jT+6nwO%({7&_Vgvo3r!5)lP+z4El5k1E!(23 zQQ&^((H#t$40pgp>*B80+xEq8DY#UQ=`Ox0qVKesbrwqxFH`dmcWc*#qH5{ zRoL}bh@(^VCKN9@!IXK}*0{qgS<+lqyNvw?Igsplk~JMW^Hn81s+?*3Z0`pA()jwP z;(K^$aKr^Jy`bNN#Z{@q^y+o4ky-os_fp9CpPfw2`K>5h5I+3fp^g(3ZbT}t)AWI> z^A$0p&s6k=lDRqYkNe?EbNWJ}YrN*pdCy?|34xtBQCj*&6#F15?pNDh`-M5HkejfF z3D=AmjCog2pEx8kUlm}$mGu_BbbV#>BC#lsh*;o2vjTl3{$R6$JJYW1by$(Z&k&~T z_8%5gSFpZ&j&iprYxvRskWvktBIJV6=j{)$;2n`tFkX^^l71TB*l_YU`eu(&Go5V> zQ_57(Vu#^0Q`B2#IxFfi(k#@Ml;oK!^Q>wNWeBeidA24vU1S{bZ1wEQSsuQcqn+;C zzw&;)sK5I2o##;ju+)(FlgExF`PqV_rs2oBN7l11kHgwx$Gm?Xq!YyLk?4r+H~w}W zS(XUpj$IMoe5_MC&$l!IvRZjKO{UbV-L@}v^QfwrK0F<_n}pRbKmEDSVXj`l#(fKLEMP{u%WDZb5pg2R7m;SklP;AS^@>?WuSO z)-nL%T|C73>@Wj_=x_H29#nCkFp3w+$>5IXj1Wj|^?!@|fCCRztmZSDFSy}7Mf0h} zzbV!~)mhNFq6!_lftj2aY~@vCVn!-33jhS^MI0OlTY!0#%*;jLlgB0|A_=bCB8+hM+W`3h>zD=N?A?W?VYgmIRU!4?v)= z!I5OWONUzoMgV}ny@o{@m9`s-ItZ(5flG)4_yqtyWs5I`DoiN71J1$oQ4DvmVzJpm zz%BnrS_B!x&X|KnFap3CnMIQ2-at@F$pN$iAa(+Y<)Ekxw&WJzEI6Y#`GEWZoLz$C zHSWd%q4qpJ#3Bx_pG^eZ)8S_% z9CH(%svDsd=MAb$T%5#9LwQsBzaC^)78NCP1NYP5$jTpA@ki}Vz7~eIcm{dRYxp4^ z&T7Dao9a*IP<$~@!n*efUQz#522?AoJnpVgFY+g*p>;QN&xW>avAsI^Q{S4Kb%deZ z)y>6d_On*yt10Fu*l@h2fd)Oy6vTQqXhhzRF-iuDs%Q;Q4dpx*#AFQ98y3~>>w|4wF2xsjX``I)>u550Yj9&eeeM-oKoX^WL;Lq?y`OEe*en#Ce|)}fKL{?KZMu4FdEZ30VlTTk z^s<-B086!6#~^kJOjgjN)tH8zykPFr?8`<0jJbyjB7}B{Eat@RQIpz%#?04OhQF3e zNE`b(hcvAF(Ht9IU-P9mjZ_yJq*3pF6E%Rp^}$Jsc^E6;zA+{5&kl2KYNMOpGc*Q) zQo+mc5Zb{4qy42r+Pyc@wz`C!8zZ;-P7hi2c~rhlbZNV<-h!pq+DD{kxEStDHzxdn z!qTxahFF^R@)l?BN;WleGG4yJRHSJ0EJQ5rx+b%=FhW?6AiMO|N!-oWq69Gu-OZkX zLwX0*@uz8}57+zo;=C>})wj!y!9zukcE{h>J+o6W*tq-Hbt;>%d|6JA^P#Myo=Qz8 z9W1wdLYgyQdk7zPZIZ~7z_cjkEoa}H+U#SVdoH72$JbWid9<8&d3YvO_nFxe4BmD6 zHW)%qYhV8&$@=sw|AviggcwhM!tDFoGv5yKwM`ZpG#0a^>R4@Nl>2PO^5#jGo9sLE zNb(7-+pH>^CbKq;eg_-$r5M->q%|i$Fg7k%VlaEwTfNA=3eyg?u1>E;>{fsDEvY~J zq$hKoZ+mR|Ew`uFbC{L zB>uxbR7TZWjmT2oo}}?*yU^OjcaK+jZ+Hj#R_O;R*Dr$k+C= zLs&TSU@t0m!{`USn-%nzeSU*FzQfU0)-Dl;R{X1xK@Y`=CA)iN-FP}T!m@Us{k;FX zj%90PtI=_?{fW%m^)L=?+-dGDTiJw`V59Mg^;%M$iO(jkery#Fd*0~raTW97PAxSv zJIm3GUQ_XYG@zQEdeGoK&DXBG9wu}!SIXpKAOZ9Ft^f1WVlf%_#1&xtI(FxXEs-Oq+ruv!(qJZ-t_~wS>Vll%>%~zW!8BuToGox@q_LucjZ0O z;@6^+ap{ytpR2r@uh7#h^PMsmZ8mH-8Pb^TD9#b2Qp`NZASRM;GwJp92y!61{E^-@ z6t*rn$tRz_dnvA!x7R?}+tz*k!JEs@hVEFb>~7a*?<T@?_AK!?bp6wEMKG{B%E8-0In38@_<9WzLqBwDV!^CU&MYEXU_UmNY z0Gx_te_HohQ6jCD9{6}COi+%VRmTL|%wDbJ!dhj#f1T+Co0X_o6S=@R{@sa!)}86C zUgB9x=FJGz4_rDaDo(8W1XNoqQ#QQ3rIwqkABz>59a*CdI0u_2-g97DS+f~Lu9uD# zey(yCipXw|Tnx5SJ$NQ>)8>*|+4e?7oo#~awbC=13EiH#3og5XI4~1~6w7?RN!Beb zx>u?p$@^)wy*tj+O-U=42+CD?_qdII@Gdu(#rtde(U5X$->Y@;mke<$mHO0@C8fTW zFU9e(_}TOuyFSHx(byC(^sKT+14&GizQ-m{#3e&9uSs)XqA)DKRWP{|MAhb=_Up&q zW^1b0@ytv&Zhh(L3PB~zK>1@Y=NECY4VnEL{lkTih9z|MXN_>CNqt6oy)#c9SR1MQ zF>$IrUffL*xM6tvPqDp`Qp&*E^~`)kaDw~J*z1M)gE)NCV-`8B%?X2apVAD2q-+o{{H z&{DhzEepWkJ~YrUp2;%s{wkdP?J&$qS;s<#x-!;i!A-d8;#c(fsV!$52~zQ_Op2<`TL22R|~U)-)9pe(;l6wl%QGX##1sglhHuU@ z;m#Tt$t)xnlC$CpI_g;pH?5_Hr36>+(Z^^|h*J)60Fi?dLT%>0lfhbgbesp5H_TX z#Z5J12FJhdDg>ND&orCoWh`Uv5QRgd!3g&}fV?;aMgTaQimwL_ElL5YguP6p4vwLx z=tB{xebFjnbdU@}@hi3kge?p_=byK=KXO3dmUDqg{5)54I~W@PUWEsxK}h3Z z2PbzVq=MOi!I1b5FSr_gGrUh06qzql9%b%z8!h#Vj*C(Pr zc+PGeh2#~xKMMWj$>Hj4;ijo=AxC+9)f^{6tccD0WVhvp8|O5e^jBUxKfV@vg$ua7 zU7xQV7N`?4nrCZuJiY#!o_h1`5Y?#fZ7JqLT3F)SdhHi#5E}|R2uwk5S~N4i=gNCB zqQ_CL6Q8e?ch(PhFJFRpV5(=4c}rhoGth^YVkpzysSB4WWNwf?I3Z!Cvee3-kuGgc zV5wErD;@HH5YsMdtb0ez<3LNGy10raxpk_VA$-s^Bg{SW@aS%r^c3RBWm!i?n9UY6 za`z*~rSP#HvoY05Q&=8G&hClc7W?LC>x`9`nTXu0#zgz_cQk`7-j_zc9J^a^j0sE{ zN3jk~ka%smBuTPgE0J%;*e>8|N~7G*gDGW4JiguT8_Pvn*suFD?MUeOzSE{SO^^2&(y}5|71Cx@Q zp}$_)dFYnNJ?ZymtGyq%tSzZ+If8S)RDke~B7s$h{E(Am^!b*5)UyMsni*R``Dg_z1na$HZaLC%F3a6F*hV9+uQ!k-QE0|c6i+>?F4EVToc zG62G|4_gEiW!gGBlFk@Gw1o?GB!SWusB$)Nk1_mz%^WD-7jiIKB?KsU(FK1|daRxw z_&D%C5L{jqA6m-+qReQ(%>WRy97LBPP)cys{U&hLBG_{PsHo1^0v70Kf@{v4z=? z1ty^blwA|t#)^~mbOvO2Jog|1MU&4fp&5Z801z(*AV*m2fFkO~w*uuJ(EaqG)!V@7 z>^$IS5OfAWV7uVcL7^7lu_EH}DB)dOgt)lD;5Pu&T-bnlNSAb3qmJ@#r5*UTxSGd5_pe>^a5^h2~2pjOK&~;^8ldT6!=?Qou zxuy0DaQ7iM8SO$+K5Gb#%Xe}`w<7NeByyZ2A zGhPsxm727CAP~HsU!FK$DLT1l@>=~VB2;Qwrr$?PLzR8kZS2pfG5Ny&FOsp+lH_O;xMNM|!cIT3SE)O88QU~?-89+%CV8TZ zbXGvz1@#cZOY4EZ8F6(|KJ)r`R$OK7pxrpWW?8>-p@;~_|ADQJRuEmfnfiLH*BmUp zz(R1&D#cw*ej@*t%^k{ozdL=?e*_S6TNhn3;_xntoD!N)BV9!Tk7qQSQgFtHnSMQMT;3zHP|b__ZEg1nrQ@ zc--%)rnmmJ<~fh1`zkqmy4sQ}8J#qr%|ptH2nD{eIg!ST;2I~sZ-oau@)sw0t&E7k zpJIIZu29HHwfT)o>$Rh9^K?PmbQ=%nkKU(^p3{GM;b(!REqXi9;}O`W;$Yt(*?JTc zeMV4E!P*9ZyUJqPuz~nE-JeX5Z$!jANM_aB#=~ zd%E_#csnR1aW*WPkRnnqV%I{Uz+(~qVFgrMcm#$3K+(7E6-+v)5cp-I9#B43@CyLq zLIYM8CYvi5d{_SwhrwS&444DZ?umaDUZ#W}sNtBQwBLY!QIeoZ0oodj+Vd!%gRH!G zs|)CJ0wvf0Tg0_9lwj(sxFB7?g!K7Oi7|@`-+<~Tc^vc_!V(X7|&t0P>%jv0Y4RE zFr7EB9*@;%{CVLeuXAb%oyO)TZR3B7Lqqroiu|K9+=Lw~A|N<5QBF)S5+eXGS7E54}tka4d!W#=T1InLL$e?51FptLY?p z`qkt4!vcnU#F`qi>&#b0_tv!2kJC@OzSSUxqL)fp&x?H z-8}bPP255u|HLB!LH2R@2~>pYo!b-UK*#&@YEN<28%n~W*R$074OL*u3!AKTQM1#n zqygGQ?Iz|NCr^4*Uhuh$Bu1*5{*DaM5Tzn^5hIQ)WLXn}(gb9U|nZMvPyLH$QV#P!w$64VW8#a|UuH=~!nD*C9-q`ol~TVA_+ zq*nGZ{O+p`ovl9!CRr&;oQ^kJGCCyoMOBu4etgu``%`{0f10~{`u(p8K!-^7z!_L_ z%fQ+JKtwtd>_Jemq{~;p*^icF5riy6Y7kUNy9^nSD#pP&2RPGMu}6V*?xR2{eFQe< z?{f+F-(avGpfdnMahQM_g7g(E>j7Iu4736u7xzW@W)GG+^b7bYE&~{8ut8J;0HQjB zxC;}i44S!yfb~ZmTmb-A9>VH}BAFL8IlwlcnHRW~1U@|?Tn>8z3I*;t@Q`1?vWDIi z@G22P8bsqSs0$`4N;!@a{B|C@+*6Fr$3}#F0#YMkWOjlVV1uFAHPN%ZH3Z%b0BXON z|AJg%L&mp$n0#uG``5+>J~G$OC=3ahCjk7T8DR_3)CH##2M#WUpcMciEsiS$VFOA& zT@q(M|GR&U0PINU5vW050Juvmi3y77<2nS2Ni@?3S2~2uqk@1jGyV+%hO=bgy=B`1 zQqq459{|Y=UHITLcn$#MD?h9J!Ul4&=`K%_!ehWRT+w-KfjlU7_T1;@1eQpo^H=@J}OdA08o^p=~FQJ?h^gitoS^o8uNME8eP6zEvgtY!K z!R0szpR)Ub@mV^U=8(2l4m5`)gjAKBne@Ja@c|Hbvhglrp`sQ)Ie^881)2fi`5HKs zhye$DLkJrvO{v@4SnY#k)jH8f08-99`#@+H^+McwIw;EN1OK@6!)5T3C{W6zbHN% zs&WnZjSe>h+yVea<=JAv8^8=fxZed64>%W>flc#FeY^m=0>BSG054bL+i`TkZxY?I zgCFjWJ!0jyorif*JoqM-&G;y%HRMU=x4u(Dd+t^Oew%3p-^Ah9{Gar{eX9AQm-mtS z_uEEW>3G4HnpcD`U$ikMd4FTGWB<^+ia${7Hqo6xj7#KlO3h*y1P2TXvx(9RYNoKf zE_X!_Uo#3*z+|q!^6`#&mJ%$^&O?zjCJFM)rYib_fHkJef}`g{%43Zip>@YboT))XB5ZOV0u>l_a$h*2~SFb1JZXPp< z_9u^4x;D#dc^=NR1nC=+(N!fiEBB*}=i9`e1{zRs^WL>xzReSmrEVh&EA(<&+)jLV z$Nc8%$j*?4gweqjg`5lFt{)l_dke}1XPBgjec;PA%3ZF01`r~nZbq3pef#XG! zhpQ8aT$N3{%x?venw`-SHxkyJU^UbKa)vG#3aR)ipRM!!8 zy&iX0=zH3Ku1_Sr$$R8-Od7Nk0b{H*>jx1gz*! zm#Tuw=n~!9!u+N%d+%H*ayNtV%hL{By`yUHC(Ou>MQ&T}s`gk!ya)^S`XD-k+p_fn zMmSUA45_W``>QyNbIU22_pLN7Rwm^47Y;@W@!1}^U`7lHEv{OK5!=`9hWOU*C;N!b zPhExYwR+Y!6$V9ToApQ+wJ0p|>&7bCV%G$`X8Mw+(p01(2Gw9SkXGGecWGi5F8BBF ze4#Vh_4vgnzo?62N3FZHFxgQ@Pov7b{54Avsh{xM$5P7Wht1FBzHeZ#Y)C&Lh?HwN zjz77$F!D*bCCGW)fPc&F>P?cRk|FJ#AvVvOD?O|E>p3uc#be34WMvKMZpT!ioDmUM ztx{-Te(4(z-LPJBz`pMO`D$M0QGS^z)FOS7ho8IUSSu zgYX8EcBce;<4zdI>Bs!s%G=e>l@X%J1#^Q>8+mwhrKqXl{5CKXOxT<7&C~kN2NfP} z>9RaieTo07ltGjy{6;n4?GC^e13(y6V|rksBr43|R;P-;HazeMLvMIj&==tB2+J+O zt3~A&N9Ot@L6@8m0X+avdmCA87VdQ$96ghu6#$WZ8KLS;eoeI9WB zi-LgwP=|##50)_$C_>=vCcta*T<5U{{yED)!lmbK?F5*MCh#&)LM=$>cSg$5r+A?g z|65GdEo&lySbToVnMgur2n@V;-795{wxWM=&PcDEYiC4t3QPov|8UNZfODp}39?47 zYTyh9rphlwC;4BIl9kupV0ML+I;iK{#RdR5gB%`zr?~m%r~UVDQ#{*+1Tt%3h_X zL9amnp)&brm``P6LHyWbgXPy(X?7+G8q_69c2&ZeD(ea1qPQ@d9p;v}E$OEgn5mW) zVUoC%NzHp9H#XnU@U+UoOTSMGjpUZ8TpF`m|B*zlFbFRQ2!h{xH@qP!Y}UJMj5Rs@ z;->4P6d2{$C!RO8jF#7K+tAaG)fqkS(-Ro(R9p3OJ2ai`3VKf<6DM49w9rwxK@+kr zF5K{899P13(dz9hm=3w#Hc_RcP>8~goFKmV!&U-b?xd&pG-O(T_+PJ_H^mQH^&Y3w zW54tI)d44s_2|5pThcuOQY*`Zh1Ws%BHFm$}ei5GKSP}crKdHj_3#r^<4?72S*-IKM!!7Dze;JjL z;^md;h9C$Otlooj))<(h{%@WHgytS0112g&?X(l9_fo)e1VCKw!q$YMwoK9mu&mK6 zGotk3{F@V!F%Um+@8375|59$O`V&HNZOzv?%8R~-h_gF)FU-#g`C%p z)Xon%#Ud+RjBE+C#+)fEKi0iZGhJ6Rt9+cQUQ4Ws=X!IIM1FzTJIxYLmR!4E&4sKn zDd^~Wl+*4bkgmwaflbGn@$|~q$9>7ks$B9gf5nf6BjqRkR1eHk6%3_64w^nt`s4B~ z1^y><`?9#%QaF)jX{UhXa1kQzV9sY$$LjU+mSvSsdjs;Zwb@YrV~E~cl=ei zNv1Z@D(q$vCIgustf`m-lb-p#lI>b@3omZmngBY&Tj_the-MHfZ;QpGHns$IgCSaZ zip+F%c1WPl8AN6g76g+$2XvM~ywwQ@U+G+Jj66}$ozao?h`~1mnV8TwV72@T1&3q{ z_|gCf;xOn#Og3yVhH8FT6VkKfTfc>KX*YI=p8>`>M1ihff2m7Ul0&OY-@u4D#trIaexMmJfHhly2o zY|=W)=_YX8!%A)C`iEf`GsR|q^7%{pKXj`JUk|~?aI^cVGp1nvqg$fHV)%*E)pES3 z@3Mm=RzGx8tz14Qk>5=T2ZPn_u(ITYU_qZws49V8*v1u9~kLz~G7U9!~G(f0I7J zk!gs1&~(ScI@V0^-de~7rQ=`ihC6fgOBpA#J@{?m2NrCr1GW8D)dp=&p6P!4$v$r{ z@NId}@d`d*($`8aA^%+be*X6OK%D`eJ?~LUN~DwShuoMfL!9ldhrQ0dD>}RP%5tjR zB{P%y7OM_e{X)hU11eyi|BtTk0H^wW|97lokL;0E$j;s*va?bog_4mFBKsJjjD$GI z9x0LCF|+rUQL@S2n~eW+&f)Xv`~Cj@UDxZn@_s+(d9UZbpL^e~YPajFRvr9}NM7a^ zaAY%YrhagKZWJifuu*V_mKM4q`B{CNjdUc~0_S3V_JtAGS~EL*+vLnliQ3&@r7Jg8 zoE&lDi?Jf7)2y9X7cdH>7#jMhKKQfTj&3l%@s)7YN`$VdqkMxvL6V-h{m(=eRWz1Vsq+GTeW)UE> z>PPs_X)cbcd=C-6ZF=fsJ0BR}q*C)?p~B_aDlGQT%DyS-F1v?~?XyFHGSO3hYg>-1 z@A1u(N`?*d_bC3A&4Ez^o`MvR|HpoTDm11_Nyf(mXs8UVbtJn4(aYxn+GiUTQpSvW zohyjiNv(eYne==o4f%z66YVVLb_A;UxwBl;k$@G49TbB!ChNIa^bqjjgmWXpKb|=l zpf>kN;3gBQsj1je^@gu6We z!^h6&mozym>;Dam2SCy@EgV*kYl_-3q(*^w5D!iPpbG4vT>9OVWxu7s)oqYlJ05GO|TE)2R1pCx~tnXo|ZbG%vzsvobP7^$w+ zU(60LOi^@{`I%|#e|EJ

BRo$AL9wL;HLN?x}tq_PCPKd_C1=JVSObZR9$61ZJum z@!lQATXQ4vRs*=3^m6e(8kXKWP~Wu7Y_OHO{;)a`W_fy%4;JMjydr@mXrJ1BZ#c23 zK4PvOPoh|+?%jM3rNIieQVf3JtI#{FP}@RbGmFWKoQk&XMD=Ozc7yloBM&bcbgB2% zW8l|CUbEp3sAsvr|4_BcvF1gtiwMyNclzgiFE)00@oagnN(C8ycP(JZ5MwC{8ruyn zY2(!>j#AAuY@3Ho-I4qGQ@TQ&n#Y)hnF#l`N@j%6UdP3K!_kIM0~QP63y=DoJ8XJi z*eHF;YE*kjUltMApq!QT$%4d~%fh?|^T98_*62!VevGVKiC`f9227BfsH)Y_}y^=WlQpe2aHSYClr8-@VOO>`yD98I^h~~M% zbsLj&HPx3MxN8~57|w9|*f5_zjGL@z2H^PBiO^RB^Pb%#FqE` zX{&s;vVcnlb0bV)hTiMGEnin4gDh;DGgVnYY>jA5#jL)0itV}QONX70;oJK$SfYDB zq7LB&Z2@^pl^xj^aX9RbwrAeuN)GCeiW>MIaJtJfWQEBw6KB*Zq#36NRVxsL=x)@= zdB>Y%gb*w14%?3}62oFGRXdLZyT6&oCi9Eu=m&1?PLT^Z9SpfKjy>HR$O(}=9bLQk zEo=#9$d(}gc*jJ}S^MtWzbmI9_iIT8AU2-u*XTNyJmBcUHVD5V2SfmXAlkuVz(iG_ zMY?&hboI+aJ$$_L`X}=1i5&Va91IzyjTyy==_?%9EL|~ zxKkoSn4lM(OZH~K&TwX$>Jipf(gOYN(;6*z$<9A{6D7aDPXElS+cT1Q8b0xGbgf>} z&N|-ina{M)ldEs(5cZQC9cHoWBUhkbGo`N8376`R-Y4)T)US8<)}>%ux25W7X>&gb zlJLw;-8rGVG)Npa8gTL9{=KKPZ`%Fb`EB1eVC(sW5%ujcoP}(4j^%@JAG`oQh_M!&x z^#BkQ1VoY$RO7mXsXMn8!RJc^tQ@ru0mJo~nzsf91Hg6n@Toz;6U!kJ#qYJCyEMn>_ue``i|k9w-fdRKL9{2F{}tM4XFw+n)HIB0O(?5 z$oyn=wrh(*+=yMV31~(s_FfF$*#xSp+W1&1E#|AFOS?{i;as`km&)y5Ou(Sj`_kMnQ zxgK%#-AoRf;>z0tbU&=!He)y8UxY7=IMEW=YXRW%t*?YMWK@1DNn$8{?sINvzh;K2O#y zQCH30M#&R*rLfvZ-5gl%cJ}k^(uc37X{t_repfS5J9pEDc)70VpKxtGNfIQ;m!E+D z@Er5-!us?_SLmZ5aig$y@s-1pO~<7anmQ=nm9}4>Ub2{Ji81#t2D zlO;JQ+oy1cx%REdrDTR(Bc>LWb>s9_>rTn%vKp_ynOiNS=U3Lhz?Ng>VZ3xZ_s4?( z>aP#+ej6G*mw8H~GuieG-;dK5R*~rgRTHB(DOn4*ng1fIz-p)L8}-)r{>8({uAbBu zCF#PW;3JC4Fq-Ukbsp^&dCZWm3~srwTGgN?Jz7c&PZH}Us_XDN-5;bQEVf?bgN&=; z9>M}51bf|;RgfI=ZzOZ}SG3wnhObPUQR56|HnQV(i``2gR+zjnsXu&t7iQuQwQf3j zkE^v2Ff6&}IL>rpv%V}sC_PF_#7o3MeM{xND~^haT6|o)nD^k-TO*xnf8KlF6--YH z6d8V|_2qYBaYuwa!!Vcj*B;xor+mE6POtsBD{QknyjLLn`i{q%Vxi^uUsO#DmV5KX z+!Ca>Cmv`!=x8g^^L9+<0f|-tguvf}ba|=tdrMaVQhk0dFM$j@w0W}^kOlz!nj#4$ zqCx<>9)d-Mq|^mq8eRnF01&K;5N=GADI#JWpEAl;4hjXe#s94@t`2_C69`;>n&2ov z6pH{ooG1uN1A7au-4&PUx(=?Ler8$~{wI5^8w^L{zm)sVs57$U^9{ZA)}8Rv>ydlb z1g!;7|7h`rvMd>eOqGp-AJ8RZg0V`qZoZeY@rAC3-8tr5-1=$@sgKCEtSx7mJ9FX& z*kB$vo~-XNSRATzYAuwe6;Hn+v6fx<@it_(e{P3M=IYOn-E;$s3>1res^5nwX;%r; z3?JOA<$03Qstsl2dQWl7qf6dVM%^LGk9RFQXeP6;c={_v_M6N?&m4HEqSYSJYRS6z zGqpRxOEiWt-Z`$^hQ3ba6eOD}lME6seBpJlO=md~2^zVeB6vc>x5&c_@6#<$qi)vk z#y>QXnxx|E<(sMY%t4U#xRY?*4Um(a^>t^9d+js#vOgS4nD%?@^oyUHdbHL9m)GBo zba334X zk6@z)w_k3_I^Ve_V1MNCn#WGt*jL{Em9s#a^$hW+%9~-v%ujxbBEH*Ow%He7Q(}uzamW2yoJXHVH1K%w`?f>~VJepshHyi8uoN94 z?g~4N7*2H%Elqbhdcx7o6oKu^9#dh&C_IN{_Ij#Wo6g}Qb6C<> zqkgf+OkXvJhts~UZwY3wzi5{(E?Ixs4D0zi^4fOHrJ4Uj3umLn^o{W0q9}vufTx1< zJ>$LPO3fwt^tk=*VbveGV(A66nEq@{LL^|HW&B-E2FGKmQVSOPyYnD@*TjVCMt_us zaOtvq#n+cC+UE=i6uMhD&_FnrFZ>c#WAFdU^x^6JOlq;tot+!eEG5CY{%|o3O~iUemtGC>&U^_*x@*UxvGvY z;5$F#wcHS`=K@WMS!D6z%OgiU?! ztsH|o2;r%|G3HUgt8NM3s;^Ij8n$tsEQeupsKt@ z#x%Od=%f{0lU;MOn)wa)Y(e)g!R*Mp9&dzbal49mo%T+D&^|GU^pe^8NK0JAoh{hU z#5op7Rj=cw&VE1<+n}ErVr~8AMg{-%eQ7rfdj{H)&qFwaywS~jLo0v9oFVo3>n@dL zv44q$NPQl?Q=IGbu6D$Q9J*lWFLJkV?z5pN`41Twfp*v31za5fDY8+)jp>O6{*4Sk z>jEFZ006YwfUK(WAO;HoOvwM*5kTxKntsp3(Ww1v9PFS#h;fW5tnlwhQZZ1l0zEPk zObUP~UL*jKq)vcY6ucmzgs(wBufaHQ4gh^Y1uzZR@Gy|u(#p9e59*zuZ(a%v1wbXJ zAYPwBcOmSc+qp65ktf3l+Y206>(r;)FbyJb7yzDBhA+tu z_DEw)&xdi>{(43bczb3*)c`{QqI7Ok!VUQ$%BXTBG_7VQ-@)+Cvmg!dppxhZ%>cuZ z_^*v~B}N0;1UFE6K(-=lX8uKe4V?-xEx^`MarR$0g3HMh7D-jpH8&tmaS zp4hX45-$&H_b#YXqU1)AC?u^lWA@pN8 zqWO9eLMl^g@!pxpfZURbOV>xc=L$pYNWk&h=UPR;p!QUm{$c?B(5!l|7CDdDn3q z8iiQNPp7X8Z3K;xFAH-uVfx!TXUVWTPXon4ulFl>i|KnDXk>4b6pu2nrKLJ1p!f}C0tppBt z$$s;|2}`AoLy(azIdN zm=yHXbY+6t8+%Ncsci1QOSmMFH zjSh$2m#~jT*~_i(mxK=yGdNDqjqo}ys(euyB6wUwGtr(=Rpl=JhUX5miC3Aie8jj! zbaLKc^P+)_oOH!uvA1qP`RQRj!!X;Q$~ASjHSEhDn3-MByxL}SEiUeXwqqiNW756cZx)vpo;r(&f zI)|5-rN_2;VwTicHkoFX;j;Jqk>k7BxM^zPtb3vwlJ|S3Xc#F%-hGb{i`|l=nERMA zSPieDtZs}d-59dWzWw=5u2IPemh)*S=gPgKu#uT%=wNGce|L8?LbOzkvo(>}u5~a> zCQj_zU*a1w6fu<_(A}BN4F?4Z=@29QkRvR14Zs7Lh@8J(0c@B4%>D~_pg5WowZM7? zK*X~_u0zxdsyR`QEg;`Ta0UReX^RhPSs{a`%S1tN=WTEp05Kv;90Os;1sLnYUIuo=`hq75)LoqC}zZY*qi2nXFaozET(Euom zwYZ6*xF5$pM$;H@@TS-LN~z^9Y>bTUe%<3{SH2s13fXt~*3HGD&Zis2+)bRs@(s@T zMvo|qV2$?ji(kGELu#vV-ro7as>Mx2pGA8>wM!A&gL|8=F{_sx`-WT$qdmkrl~xG$ zDX{DE=fGI=fw!C!#k}(btA>xSPt3dXH@Lacla7BO+@+R#oK*BRlv(`4JeyV%CtbKL zfrW5FDet4U&fYoK(I4bknK(tD4Af0^MvCr_DqWc{Kkwx4a)-uZDui^{R=X-s+MavXej;S9|=&r4C6>LTVOG4va}>2RrjVMq{CQt)bGa7;GJ@? zcxUo@)%dr7Yp__1qc2DHI*Ag!3C5GBw|)D2B=r%Io14}lgfs|lfds1)ei?qnFloWh zSFxz4>BF9Hn-x`(*9tr_X|^-4R5_ZlDYjX^=~ZG{oGbZV{(6zf@RYOt?d1c4LHei0 z!%}<19(nugEKBYyGB-88_7ppQ{r&#YPVvKf?M@IMiqIPsb$K-EYbLgLd_Qg|XHFx% z@@J>i4v`(*@8!cy`HQ0)f&CDyq^^D7 zlX3;i0|36hk2#6*JsA>H^|pXj6n|bA>z@i>FfbGVF5Za43wy}?2g`jSH{kkox|*iN zC=+(o45vt-pTA~$adZE3(8Gbr-3oTChJdnPDll=SF+^l+XwT)bwHO~iG2eCyr^O4o zDmVMF_i>1d3mDgpt4nYL8Za@|l5-ikuafw@Y3hQkj!8-@U*J^IELMsb5tN9a-ofVR zZ>McOCh`|_eh72E8Z4~YU)xSKsC;GTkdFB6%In-=nc)2BiOI~*4vdWhm3tY@U6FW~ zIxh~qy2=6H{w1V3HXwOW-{sBO)8aHPYss^q>h|`R{Y+@k&c;1PLU+Y-Y+A-Ai8Gfj zeVb7K<(WwOT-vkBo-K!Jw>?4IPl3jf$z3Gtb+fZ;?HjF2FuDXib^MlBQ%=XJaF6xk za+TH_dZpLbiEyFMe{GpJFj*;QP${w6lm00*)ykWGu(Z$b6j-hIW^*6=admzc`?Uax z>s_juu62lIulxC3WpUp=!-g4pj{@(Cs*>MOv+F)`Fjxp0U)0zg?kXzXoE4CSMf7rC zA#*=?bxTQgU<)R8!XglpJa^KMp-uTtaz0SK8dN&ek$+2J`H_7CZ;ej+O8p{6X87hD zXFBP13#sg2%FTH$X8PP3mERP3?cU-ZLA0AG{RSI1Rco)pcv2D_({OY2o|9mc)-XTT zDk``cMOJYS<1^Pvs>5#FXDq3mV(Z%!3d*_?sXcGHAIPfeIu`U)k6OG6Nr^l5`H*tm zx*(1KLM=Q~_i0u!LZ6Gy$Ct}yOhVL*{>eJ~!`j+c?E>qBgYzV@OO*J;8NCB<;Q2Tn!zA}{jM^V2kTsi-c1@M4>+AZg(;h#`0bqf z;IhSalZcT2g#7W@tbV)CD1Y*c=j{Y@3Zd@t>6E-YLG`5k6Ia0_OXX?dv`quZU#YCf zl<}>^cJYg*;1@C*PbaRP>X-kfWn zuQG%ER}yHB=g)f<-*oo8|D(yhleO~)ey$)>94=y)#D{;3>s+F@X0UTqYekKXGV=dW z@?yGunJm`L2%vt;sZrFSQyTKlZ^)~otNTkVG#}4&=p&V-BBjG1Y&;7ZVX8zs!6x}p z7bkSwJID084E~p^Q=UA6voh~u9Zr)v9B3i)aLfQFM{@qDt?{bqxcQ!(q0pWmORQQ(=%zm!XofVH&PzvEaAv3iIY%e@}I z7{Oln)Svglq|3wS2Xy96EIA``>`BDYt1|UL{AL0@WUm9NFEl1JyS+S>9G!M}&;?6Oei0z@(PGvlD9hyE z1$7B*Ckbmn;KT&49RTrd4FXz5rh~)xNq~B`2@V4wd`NI$|Nm+==r|!~FcttU2qHt_ zK>bQk_X3?95&%vDpid&BdeNC{Xj$njz5@NtEx|WmUhIrF2J8FRnY948LC?x+`ht0o z_;2O?T@}(e>0{Z=Iq1k6P&_%4$)R^$&CHDO#yb7GSGZYCZBpu!Lst`>BcArMKAaR) z*tF59$RA34oM#vNQ~Hl5Wro5PoJ*sl-Y{ut`3hkV42G)&ku_s?YT9v}7?!6gVNWcw zo)4s#^-b_Y$W1bNb&5@5JJ$=FX7f#`QzZST6Fxot)24CTnqWDAqdusPK0SKF|m)MT>XL#UA?vJUM14Id3Qd@i=@cn zHpcFP>gIf8_tL$>+*MsN>T~@~_NZgKiFU|xuHGByl9!zhA}gecIgZrpVpT7WlQpba z-+0NxteMhePDaK#*^XYay$3(lF^QXVK+cKCLV7z$Zj@#4$5Y+ycx0oPSyu*`m>dd zUc4{CY6L*9Y-DPuBnJ@m&vk=)95`l}SRm>ZKHd)e!24h@00PoMWD3E03=XS#17Xe! z90ownK?C>m#-zZ12dKa<@+kKf+)R*|>Yu6_UV_B5u%hDU3IQAj6hf{$Q#52EY%}Su zA4NJP*(r!)!&$310(w6CcG=w$QduYq5^>FsefyKVc9?E%?N{Q>B9eBy6X~_%agXZO z!gM_=jrcRrhHnxUSTxvn^+!R! zCn+<9H%}IQzH~B2&Pgg`ZyTScO9SO2W3y8?Poo~yT6?qYQ*D?dKIlhR}B?b zE|Z0KZU%Fhl06%Pcf~h zJjKgt$1$dp+nckL{P`lI2p6luC4Sso2oO8IMb!REe);k9mzJDOIW83!I|`mve@&gk ze_3xl_pDxT6Jsco;e$V*cfbG{)0Cz>aW}5xxlGxiuWg$QX4TUig%Ir|) z&8ckHIBPo;DDn^{{OR*e=B)@FRPks_N=$-e#0uYe^lC|h^cT5{FE;X{Yk&7QJEqf5fSdR@Iq^6M)9Yzc6 zY!VAzGhW2uX&_%|rko)Vyub`I;Q`%OTD;9E8Xn4jnDEo+5Zwx%vi14M$f`SPcZv?uj;cxzkHB-bdR8~Avih1b& zz1%M*YO&ouhc}2lgIWET=_JIt;Ss}W5UE0^rMO+A6-JJI)rk`O&%_9AP)C_=UHF%& z*1u#Qdcb`_!x4}_k2dFQ1M?98nvo+5#E(>iu&y%)3gV<1TN8qhOlc**G(Rj3PsPKc zwmcJ7|C=CI-c{Rw2LzFA^e-v(m+tLI4aLc{OYLgHy_1 z65qH?ZtBver({EJPv&(P!K175-^JyBdR^94{hZ1fq2!WBwnrKF+!nzsj=w`%^ zq2;$M`9EF=nw8J$UD-2GGjFHMkWTv8VwY98LwUNz8eOuYc$CY5PyF>3_l0Lq$l8MP z+8nw$DolHcXI^=IKCDaBfy{p2dxl@he6dY(BlykUI!FGjISCC^6qa5`p?0`4B|ZeP z;@&!Ve3|)fx|E+aon(pkl$j^>i-fFn#rPsE;yKO-)1H4qM<}hQ`Ng8#%rc&tsu5kk z8&$`(JnH)^v8DF(WgC~;kvQ*@Ulb1}t`)kC9<6R>DSzIx;oqnH@{U_Z9qVzE4TA@p z@oy`5NH+fjW7TC@lJR<&1l7f%jdkWSd|5LJt)?w~qQUFNDIyl}HyHaOs7MF7qQp7h z>(k#BRS~239CYO-I|qe{w)G8;?u9k;@4U6cRqc_tGi@ClJlyUr3&|Yuj4S_+OoZx5 zkIq{~lVXZfJdTR!FBkH$NM(1ie%9i;io<{DQF-=S@<=W1%i!CMsjw~wmiwK3de)ux zQypXLbaSbR(n28)l-CL6NMwi;Qa_m8xtnO3klfsYY0yjSIZ^XHQA&owQ1oCU4(?qR zF_bn={J^~6cFp}l4{@G4#N@;zcQ`#^v!mOuXNF}r_S7rfR_#AjJno-z0o|m+jRX*D zU#k=*D^#i^#7GRjTle2@wA~Uje*e<0`U&$zxj))QP+Pts7S*VU!Qn9f*}HXCb2jOX zHX98r{_X};r%SFp&tF8=NGb{@f$*T&9!xGd4$BBmhauYac>bT3{$^^ASyd(B+< zfzpM7-^`DjlTvynVuogBsn{TTQ?$39!ji-*-w&@_)<1rFCBcZvD5l_gU}Xo<9o{Sl ze7n+_7q7Un_zr5QU^7AM-`3+!j@vI@ zEFB~0to*a>H?!f#Nss~QPrme2NT&=T?5b=dljN0h zn2FUy;-jMAqu&8?l5W%c~@sq+}WUPnQ528v=-IOu$yWt{>e>Bb9Vy?&wWZuN*NIkCn#!+FNtb3Y77sg>f z*lwtqUV6D>aqp7#*M^Y+8tJ}ShQhlAu;DwUvWv_bBhN<dHOp;T~4Iv-i98xLm2(F?hb_OSIqDq9t45@l)l_*ZwkXu(JbCsj+NFVV?t#q}b0ZC4kyW zXe-E1a5;dY!7Cw{|7Q^fklFM9E5d*>n5?^l&|+IK3jl(`18W(=ZVs*pH!a4&0$1EP zcWZ$31GH}L0mcF#@?SzPVxk)2NXh~)=wJ6t3AdL8-A|AquaFVo#Xu(noHsf_I&D!o zNM8Pm1lVBujWZ7vvKz#I<{;sOlQ3cZ6F)$5R>LeF+yDTYsC@uYZ*TxtaUM7dfbwx% z;e=+O>R*H*lNO4>8307yD9#cD3;4d^%m=vC#ON4Dth&w0=UHJ+c?W4KwSvt z0$xhJ7-`gJ@YRpOXF#$EP~z%5&>|VkgT#Lu6Z%n|cW`>Jf+;CeKM1lbvJ~jyzIxes zx&PA-7N$mq2_a0LW_Fxid3=0b)|qkHWM?@VG2Pbjmpmy;h>4|gh&}bZPHL4T%qREL zMy1_B=R0=x>I<${Z!+9eZjS8Gjq6pA(qvvqFHb+=a-)7X>MjzCL3;(8jacx-sudqgtpKa{^ zZn@DMu*5UN8@&A(oA94}?a^awZwPxZ7`Cj38+ac-Xz28nCvH(L+h1^_CE9ftI_ zu}6k+c7r9A2Kp|dyy74&484fkfw+Xkf4{sa1)E>0w1MLVi5+^kc*lczWMuhUS(n{z zUQlGMPDd2_hI!n3wSI+t`Gk1IR+nh=!F!#s;S0yaYkUo?^rJ6%w^ziq1U!~AvtSqB z#;WvruI+sj)+@hzDy86r$Gmwb@5_>nr`ziq6^yDLW!|6`I300ENv!`EK5WJ&dA@-t z3o^XZk5GEoCzG~)RNB^8P{l@{Ea0LR?dB##5OZZ)k&B00jA7W7f^;qFo?gt!mG;j< zi#D!>YFZ3>N~JV@Z*tt<{^VfqyQ&A%k++4xC*`@lE}PkqDfF0IGmHIn4 zmouh+pbM=Lk~BWD?k8S8$Y8K|a>b;@&hX=d;zdH8_9^aPon@YQkYj^{Ca=m@L(CX0 zv+AZkpXN4x?`vtUSR!5y2AGPaX?_sTEnMQY{GeH!C|u3j*0OPX#4RLYQ0TDn?K_F<0$D1fs*DV5_*APLP?PPjWwZ86BhHzr3R#@7B|Fbpl`AiV zd1&K%FuBn=)qud*u-BHteO2lV$1sAPq&2F?8i^mfMCNW$L??TfPcLvkB7J4VFZDbx zvsuND98nEGSdWX$G! zcLI0!_k}vX3AIb^8XYhvi584Gvc*~ESCaM>JZG#~O?`Zu%IL;?zb$px#^acDM{Aa>*XCvJR>MGo z<%zE=#N&xE*+{k82sOEbYia*J4a{@SYzN^`y!Tg=Q#jy6PlG^80H|k#tZ9U1Xuvfa zRTaqqbq5ClkOwKEHY2sL1i|pc9$@&n2+jZ?KxP#v`yB!(izVlGUo@cA(=%obY6FU+ zDXS5T1whOOV&_3PK;Vusf&MS-6EJrB+y)LhpPprBp2f%%;my-xasZXacu(sEvo@e@ z1fbe;vFJ?0*#hJWfMU17bkN(V8WWOJfZdLROOAm{-kZWHhhQOT?4 zkwzhP!2eGS?f?LhTZhkrjx>su0{PCv;4lDOX9$}X{#}Y>4VB*@=>vXomf3)~=Y#Ky zZgWMcz%?NN9{c!w{{t~!=zZ+0%@x9V5LX=&6Fgo4Ire#m#D4_Ig2bIDd*OfbcG4q- zAy_itn1>bvR0P}$KvAOB6a-arl2G}_`xEf0v(K;h&nKh?Lje#t-1xK*RE4S75)jRB z9@fDeg|7%dDIw-Ww%dYBLBZ4bgI@r^jiLDE>>xbqf0;DMwMR4QvzRG#rV-L13N3+-A4GTs2fM6nV==8|FD8014kI+fY5FRt^k0Li-Wje zB84hckxP=Z`b1~K73y9&bigBDUN^dptVXE{u8(r{ARGLm{RakMCIAF|Ex{-zJBT$i zZcBcsO$BcDpG^!%V(5>39y*BUNFsnLDz(e#@cz=j+aiWAsEmSsU8-PO00eskwk!k- z=?y_uMm?*?a^@64RYt`D=a}9BgFqX2nE;4u@34#jli>3>GAAm0WxJc$C^2NkJuceZN}S(&iu%oBoaFoyml zXKxRcQTi$qcNX2V=iVBiK`QW600^%&0&55=Ux|OR@uBNqmqiMg=nr>J+{(=Okto^H zhZ}IWb1z&PH|`n-h@~@Ly+N^u>8sdUyKfz7tGAcYSI!|vL{D2BmJX&!(*J^uT_{^^m051;xi~v z+rV#dR@Ew7#arHa$moz0GQJ2SOfs=zfD{y5B42SRq!-h?hq(+hl@!~PslL_Q^qsSyV3O@q z51qT3|Lk@*esJTpV!uuItE6JF{e+YALS)d3&wCV3HLC8*JW&f4e9*ii&mA#EHHPag za}tt#`?`8i6mwtL(J-a$^Nz>DQ*^maPx*dUaxzkK{A)qjqXW5+Erhj6Ngdp)g?MDTaEj;SkI(^8czh+_i&Q?BAP8d#t$oPx$qH+AZYt! zd80yh{P4F4Uaw@(&BbQwWSRC>js>-$w<9x&-+%WVZ)Yk}6ka&`OZG(;aQjy?gNN#n z;FJ7k^)@s^WB^2r>@iG?W-8}>w^2J0Smp3saX{dvU_ArCyT!3zv%dyw|KFL<*dmAw zMbls{7z%)%92wKvAwKlQCsjG}*09|+q!3%WkzKgbDa;752+33jks z{?7#gwVrXLv#>hU1z}iV=%rh#RbK&JTAoLz0Z%Df6q#ylF!SC8{QTMr?nPH`;THt?55HrUQ!7F-PdE|DlQkuTq*nN^EYy&lP zU&+*)&EK@_JneviPCU$yvfmK02mN2f3t&g;Q5X%kB6x9x^?{cH0(9WD_!xdTymjPUs>lMd=kZoXRWE}5H~y3%QBmEktrfPFkrEPnUMmAhZKn~XE? zC!d1|obORM?SvT4E5VMB^12^oWj>q=idkkzP=IiS5i?nNwl^&ozs6-IlaWfUt%Q^5 zdi%PBp5{*p6WZ5!`rrJhcpcv(0Z(e)pV0s1U7e)Fswb_=A3t{yC1-j?N!Ry&{FwY} zHtXJp%Fsnp6*@7PJO7It9Fk9J6Qgtenj??8*FTsD028lmcDLnmpBq(RT7;e6<0hEa zfm#@eTXK=Ny4Tw$4UAj+n$=^8`my4-Tf?xra1*J*3Ez;HOeT6w`OLSocXBSu-{F!D zUrZRJ%jf8Req}=wL`a^i}NQtwDwuZs59maA0qtTJo7{c-(AgPf~-az28VE2HA zoM$7H+Qg)UZ_L3K#y8YuDOtGnGk_rHF`vzWxDdu4Z+UgIjpFfQ!##TH&q=v?4}N~W z^?saGjCc3YMXn^tYaCty8$Ff(*9e4EVi{SO`uj-!+SQQ)G@2~Wv{*!-9sy{ViX?h; zy>qlUy90;<0JW=ggL4XnV9PuY%tW#Rb|6z3uXXNahylVn7cY<@2xzVWqVAB9cL>e_ z0v$|tkpB$|vWGJffw8@3n=}Z?IdhpcgRuZbO8Xp`?4UHMaS2Ibt_ry6;M z+;o^~#=5`gysgYzwIWGx2TNcsq`ABnWmMr<*?fFS zdd*W;ijdWP4zd%sW3Mj1-`VuNS#q3n%PREXq@&fNgMSGk>-7ycv(Sy?gK#O+3r@ou zUtzCgzf_R${&t&DnawnKsTe1(rfs(D7SI}9p&j5eB=5XAAgp%e?y-CU8ckoV%O8B` zWX?Hg@XlaVaY+R~EJ?B;fCiJM?nZlhTBeRIpIGI{w!*I{jHF!G`Ql?2aX}fT@VUH( zALGv0;d7_YzAa%S*}nRI@|UVc2)->4^FhIz4ov7j1zeFI7zQMI<2RTu2<3p_-g}lH zA_U^2(O=?B&i^0I8PolQL5-~GvohPo%M@Yu9OQNv{R_#M;p~^w$<}T5X$@lr3TYmN zT3#oSoFx|`^dJj1!u zk8O&WZqma2dVNDGc>85o%E|Px%qo{x)r5wo*+8RyZ_=Fwx!q&QD2B>atjd%tEO+k2 zzE`T$rqsQ@`QY*o_BQUMmX?BsV#U^Vg?6YQl=^Ah7s?Fdw|?L0{=8uD7d^0PFrtjB zWgVPX80??Sh~Lr$34CCK4adL?fRYGk9e69E#_8-URs{ZdkQ{d zi^Nu1wRZ?{ssD$s=M!G>!UsO(b!)!?%lFa{`sVjE~k$g96!v z2i3gSDMoDW_rWfNpY)Pl3B9UK&DK17zt(kBv(($QUS{~x5ZyE_j@!y>0j?rHQsNxw-B5aHzaj_9h3RGWqN*Yj{!YLm@%-2)AC# z=oxRec` zT>aFonzfYD0`2Q`q?-?ME!c?Rc?P$C*kB!9{&eq`4W;SsmCoBV>hocCHaeQk`uDb% zp8SxN4W0j!(Q9uXVBf8kMGn*I9M4-#5PqbSeznZ8%l?^Bki{chOtJ=B9a!oJ*KuDWzki0?^bq0XirCr)!v+Hi+&^W(|sMpSs4owdn$B*jj< zOb|txbhmY%otM#!_Q==bOs|h|8X=x}S{u2_c$=12&0=fvhDBI%=OQu4fgc(On)y z0qLR&W1i_c9Dp|hpu`?_B=N3%(r--#Y;@;L^9Icx&T^8@h!^4BMOXph@B(8KUoe(7 zfw4zmEXp8)G@hVUms~I}0LaK7oPc1x2Uq=9{{?p6J}BY9jf# z@T%YU&1lP|4UF5$l2fCwq@@=?6jggN4p~_-9sB|S zQDK11gp2GN93`j)VtLWzb!LY^ku9q0L2o~}^kwi90K`^5(JC$$Ex2~X3y|`M)>_uU zA_YJRXTW$0W;Zxj?tFad?l6!Djw8DoPnm=z}-?M{Kgk6|eG2D|ip2uoquYryV z)<}<1Kh1ldXSULJ(h75}by-@RemyYUyY&!DuJsh79OKWUBjXpe7m}tKwdq5yu&qY8 zzl*^~7(qBc6KNJXNNLpe?-nin-i3B9xs^dWq75={LpMLLR2qyjWXey!Qv1osoAc4! zV7MVz{hN9JXmNgaX@lw5yR|3DvC6Z|?H!F5WD;c|0G=wu@U)8aabPg7D18?Te z`XA8DOWLe45|p=j>-|uG$~D|g@Vd=8m9&5Vo=!yv^fmX+gGey9+_%rVg1juRZaIt`P{Mx-}*SSXhd;nql) z?N~;YjUUEm96c%z^T@UPAj($%5vH2x@!W{Jd`iH7&oas^`gTWbm5WE#=1~y6P|<4* z&yO@S?B&|u8(&sC$3Nc?q1?uv2b8XXg^hHY;bFvs#pky1bI}z1b*>(OOz$)G06Gm8 zDgbh!Qo^mBNi0x}qZJZCR$Lxf-2muK?ipD5JzHQacn5v}fHKSDZewX8E0jjXZ!`{rZy&h()66>uSZ7K zrb3%J{lQQGP`N}93)petpuG?y)DRp5Kxh%-m0@A+gWWzv2vC0!cm)9PTp^+(RJrN0 zeqj9;1%m<57XwO}vHY@SmcU;Z1APEQ(CQm07zzM?flaK&;RlB9U_}O_6K{zRrw~d*1FG{a)F@clboj z0L1~*07SJ@e?TR(KW!7fn+R^M=uF=OZ{n;63rJ)~CbPrGWC^I@Oujg&C=mhKW$Mgz ztpo-DAm`^m`XQbw0sH*0`14u>2PQ9;kFLa0*Uun}d-=ITrM+Vk{3Oo;4fFJCm&f8j{QHnt~xxbtmn5Kq*J7VyUSwJ;ts{#onfK4+v4u- zcJVFl?(Xiku(-n_1(wC_`z1NK(9ZkydHPq5lQi-*@l#s~NA~ED_u~ zMuq=6Ezj3%R_ksJ7l*E^8gZhpGtJ8mcS7&yTGYGP-dE$NO?Y=dw08AT%hS#pS@810 z+)J(23DcLIKfTWP7E7(7NiR$t{I1cTfxoqwQ?hLIl)b z{VulqwD(-x!G9imKDUf_?%y)?FJ5f@nA8_)oUJ}+^qR7n2K%4-GUn5)?3KF2xmIUK z%Jl0C<~tEBf5DpTl7BqDHuDMJVbvzQzL)x4zj?KNE-soesQ>=GDh^SpJMIkmhQ{#Vs0-s{>`a@v#b^G$Aw6aeWR=j`xAy4H3?eBhE&?<20 z?2Os0fk)au7})G|`<$6p?8tGbz`4%%r!<=~wfMe8e`E=YU$S?e6N?6&ZxJ#k%d6f; zQa#Asy72IW%ac`!x68k7_k&$?Z7LPwQ|$A%FBh+NYMArSHqq{6j+XrBwpqO|m3%(` za<90tvW_1(EYsAnIo1t0+^O@F!#NHn3SD$Mz0(zU>Re*rt2HBiqMZ#`*X799^M5%? zj+{~ZV&BfIcO{;X>G*|Q10#0q%RD)Ey7z;Qxq6ie={75R+FK|7IO(6b`@MAIyQhnu z^>q6mcgrpx*?C*xXwH_$4&A-jzvbEqE2}IWH*{LPSaar-ah~k>_Q1=<9bWF+*7we{ zyS;{Hy7R1ayPCyOZt7OOWMdThky=U)7cOJcIbot)VH{;J$Y~P_>!!JKxw0rf# zzwwiz*Y1wLb12cPU+Yfvyw2%k2z!jiZi_e;t)I8PcWniS!!nzTOj61e@w|OfI>c$f z+PgVQ_1c7AQLhz&|0;T9)j;T=M!F%H-cb34Yu`!b7nSpl=G3qNuA+^a5 z%ZE{g%_s*RrM6NR^-mUf0pVV*-24V8;5`5j+!>I<7uE1dA4i8QmaRI#O3@RavIts! zWUG?c>SM20DGFN`BCu68Up#P)cl&WGgr$m@t%9k8#=F3Tq50uM=yz6PcqJy(`ET*y zQ>Z$__;EUgS>cKx)zbH#0fHs*@j0s9bPEeO-4f9;9n^YTJ#9d;z-cIhh1k1N_btJL z(_+`gZ-YbPV#f&1W`5oE5hkG|9%67sv!ASr(zz8{F)&$RE|51D9{op1iCuBuEO4}r zSsS*-O%~V}aJ&aXy-|SoSFDQA{0zYA2*ITV3vlvFO4i*?8;_qUWK9&rWTk5~46?~e zZ8$47`S;Cbh1>#JBWM&3CQR~3HxG8)9elrA^tOPhG zevt>al>n35WBQFyOcUS+6xBv*76Y6d1;Jg!+pjN{}Myiz6 zj{I2kUMVoGY(gxGawmK!7R_cB4W{3i$n|IOHPm6|$&?ES4d~H8dZZPz=;tPwm3S!D zJ@;Chzmou!Padp{pA@t36n2R0^+^wC)29Olpks?(dcmqhA6nJv!m3wdmd=t;c(IL^ zffE*nCe>A_S%VoKI~m|uMc`<35Zvf{2j33mdgOzcz4O4W4kpnLHc|?Wy|3ur^)c&6 zkr}6YSo?YeCI~u{5^K|o@N)3Bx_Lot{=G8DIW!dp;M!I;cPV@#;D!E#w7S#sKJTTMwuSW0l21F({DJ|+k9bI+}H*`@FbLbs7Lz%D;v52 zC(j4r$ImbcVeo6ka&mflIO{$rM<>7$cN;8i*=Y-SgFZOLvHXC`s~13Tq(RR)7pE8% zynS;wDoi5n=uLPqj^O%Ug*+jd~iE_ z#x$N|rP>-dK~S3_U>$UVE(5T37=~4M`7@bc_rd{66~orJD-hwQxRJG+>=28sUkR~8 zi1si&uYvo4zV2>c8@(LsWfe~WHq^o}JdbS5olWM~6lu=J8F)`_M2 zPy)jHq%X}PWQ-6wBQioRY;)~t^gE`E?_c;GG1hkb-`}ZD{hCgO-4pU*T#ai&Oq8SX44d zAe>6KrpAjVRgSG~Z29knFG*gVF{Jw5Q)CX7lK-!OF$jzN#mL?)qMT|S1I zLfhR>28PxDjhig!WPJ>P&`^B{C|=YfkfEM?A1XV$0dvkAfef|UrRr+|F58ePKyS5R zI@u)!cY1^6%ewh!Ax5FpZaGF_`BXDtaJFCoxl5V9Pq(MQfdy+PetQ!J$tVgg+eL85 zhyBr}#oj!y1-O2KOi0%>3W^8C|-V*Nr%m(;3b&!XvoHA z%P?scw~ha5osxBCOha-CecvgngY>9AT^JR5&;UnS2YA?R{}jGhwBVHUQ_cyKDq#?O zg9!{1=_070S{p_OBoDx&Km-;Zpq0?_w%|Fy!jy9$$cqV#uO38@w;C4u;xRP${!b}0 zSzRu~O&Hj-JBy1klf}#yF0uy=SMKV+3FP<;Ig3n^7np>NO|%lMc-cPbHWUD%mI=tz zC%J}V(K^{*m!bv7co_7|y|HMBCKp?E(P%jA%@GtR;8%(0%~5fL$IWqE*|2DE@7x0h zf)6|S{^M6Z>=^*&;m%(qE}kw*ao63#ShO#u!Gsw#AVYUypg7+SnE+linD;Co6vl6W zSs|MQe0B?Rgw#X%oW|IeG^+=rKhzzTZOEkbQ0i+qYh+U}3Svf1(HM|GGs}r0w>w|r z7pq$e?_UgO%#9g(tqMrIe|ZABFnI)Y2~Ri*If(ge=n<}3FB$+IIui5qH_k67r@%C{ z3erAo((~xrd~vKdY>idJ<8(|?Rx-{O z7==g4j71oRy*2e2vn?Q5(DMmwr8KwnH@G?Q&ZgBS4>W%LWXy-f5C+~?+$jdj9x>x0 z{m=yEK9O;EPs6J8)VhSWP0cJ zgdt*_{!%z1O)F#v0$G4Vpi{yx4Kbbca%a^Se>(>YJqpccvYI>{eVMWe1^To813|vb z#U}JMwqP+GyHt+|;AoPmo;n;yL#`;`xCRL)neAiu8jNfzyR^k99K|GewhJUXUCA4= z6>AZ&$mNk7Rs?)(e!%Aw9DUUyn^p9vF#%6n9BMUuDYMO_D`)f+PQW`{1F6cb1RPo` z#`7ZJs&>xCSU%}0pof@Vn5t^$qQ_OwCV!FS08~zX-|$yUa0Qc)MH+d#XK->A$E2wn z&)@q8JgpZqs-e5GjwQh$nje$MN>k>YG8XXswh>^2ae_! zP@oZMx?xTmj23J6yDsZ8yoTZ0=HWmdV-gs}9sJOr7K$&Wqp6SW{P+@*dkF`PY?u>n z6&Vx4kkq!eNO2q)P_28O?B>&Jj4zIKZK8rjpP{_eAL9Ucd9&5BepE ze?9iRLyMw1A$w9G#rq4Y6WFtNH1N9QPCmWSr5$EZ=S-|wVr|2{1*8NrVHZZBd@mAn zS1H*GqdpA%=ZPt&#Mr~fGx#kwqa2h={%8RFZvhS$V&qPf96t)piX4geeS??v`j&tE zpv#ANnGlnce%5nl#<-dvulDT-j!2*OuL5-BFmuFs^w>IyzNxEWReYQslQwwxpRPxk zqK4x58bK(&0vJ!c;h!w%Ho;NbFbDsp1KMCfs#`eHTT?XEEIP1vttnlF{w;(TeG$x8FuKVjfE3_>ht(zgvt zF61>>_}vttcW=j zg2-t#h;x$M%r5t5s$15EDgg-sb6v+M+sXF*b!V=&RJ{c_`T%7W+L>vFT+15xHw5Y1 zJm|XrE>gkXgSAn>_;@>TY7WH+mWh zZi;7wSbcqh)7XY60pNj!{8PYxxTm^zG_fx1L*zQ+DGmf+4h{?nV-r7WP zMHSu;@M_uMh4;KNR1(LqN(U6ifRL#;UjZ0>crcU5Vfrgu};`K@ba3^v!^yDrur?yG#O4=}vxQjZ0MiRDhLpSmoJv%p(k~U>1n^M0 zf*6nQ%0LTK*zacGT*6xJf8{Rm)02RAFo{Z7Ipyfhb=8homFq9feqdFqamj#5Isleb zPL<2cn<~17wrWIOK-+y{_?iRVAPtK=BB}nEM8(i3XW`VIsy@Ndyon*YtDW21rq?Sv z7O+#53c!j&8@k5ozr$)>Ul>vWgHQ*L8sJdV9-r-g46}pydLx(oT^yUhJ zz@I97ke>Z_C*W`(;vgt(Co}BIgR?LCJuJa7$ZTiCa*?%RIZd+DFmUqL^r5SXr5ILN!55vm7wD96AL!Hdx2^2wd}Q~l!QARrAr1SCf$tcr&K z#2ewsZNAo^z_8bV2bm6vd~C@A0^#OU=-k!p98Bu8?YG$3tNl+Gur(`IrXR8se5mJ_ zm9PM2)vma36giF$9xka2I-KajQnt#WheS+aMZAR+wQ_-$(jknX)Xqsq0nVY{{t)m& zeli1a^(f96*fih3IYTFj0rJa8F2Q;LoOr{r9m&UQUWW<~T~UZ^v?f<(`nr#Oh4t82llWW^6b zBTO*XM7ha5S@&83-UD!0BXjdx*R1ax4=hW38g?a?wcs-1)qgMwhR}qICv+6$;6Y_t zG@EBlp6s76pa5tFB@>!!&K-<6$!%@=?_q8Dr}|)2WDoCO5R;G+nR*iiPipD6CVCb# zrPam4$`}N0{bJ}NnGEkjpb<=lSVX;dXU{k$@94cKt9m8&*tjAlv1b&@+McllDEoRK zMC2<5fHJ0pP)I3HS7hG3U}wFH08Rm#$ow=NfNGQVEgY9@Ba1O>Gk+6I=D!D=|96qGbucZ6fN>OH~8B;}a; z#zfoI@X-XX1VQ=&ILwzRZX8f-GXfrt3Sv-(iddg6t;N~->HvyAc2Pi?tCA4Rte^o1 zckHpwWUtHvjJM3A3s6M*=O|#

  • E{>_2MRR|1|LwS%CyfWxtIryi8fD?LQPbUv(K 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
    owkq~ly^pBArhdcF5R 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

    91<%*#OfGxKdYNqpZDrXkWWU_y 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 Date: Mon, 20 Jul 2026 23:04:59 +0100 Subject: [PATCH 18/48] Backfill 768 missing transports from upstream (7e7e5bf94b) Import the origin->dest routes present in upstream transports.tsv but absent locally (mostly stairs/ladders/climbs in new areas: Varlamore, Kebos, plus building multi-floor transitions). transports.tsv 4949 -> 5717 data rows. Conversion (scripted, validated): - action column space-form "Open Door 9398" -> ";"-form "Open;Door;9398" (menuOption;menuTarget;objectId); all 768 match Microbot's parser regex. - inserted empty Currency/isMembers columns to match the 12-col schema. - Items: upstream named variations + '|' OR-sets translated to Microbot numeric id-sets (AXE/MACHETE/PICKAXE/ROPE expanded via ItemVariations -> ItemID values; '|' -> space OR-group; '=qty' stripped); COINS=N moved to the Currency column as "N Coins". - Skills/Quests/Varbits/VarPlayers pass through (formats verified identical). - fixed upstream data typo "Shadows of the Storm" -> "Shadow of the Storm" to match RuneLite's Quest enum (otherwise the quest gate silently drops). Excluded: - 15 upstream rows with id-less actions (bare "Climb-up Staircase", name-only walls/gates, 1 empty action) - unmatchable in Microbot's id-based format. - 2 Garden of Tranquillity trellis rows (obj 2149, Varrock Palace) that Microbot intentionally omits - caught by testVarrockSewerPathAvoidsDisabledPalaceTrellisShortcut. Validated: shortestpath suite green (73 tests, 0 fail) incl. real cross-region pathfinding after the import; paired with the updated collision map so the new-area routes have collision coverage. Co-Authored-By: Claude Opus 4.8 --- .../microbot/shortestpath/transports.tsv | 769 ++++++++++++++++++ 1 file changed, 769 insertions(+) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv index da52a59975..5a6cb7333c 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv @@ -5292,3 +5292,772 @@ 3102 9764 0 3102 9762 0 Open;Door;142 1792=0;1793=1 1 Draynor basement puzzle door 3099 9755 0 3101 9755 0 Open;Door;141 1790=1;1791=1;1793=1 1 Draynor basement puzzle door 3101 9755 0 3099 9755 0 Open;Door;141 1790=1;1791=1;1793=1 1 Draynor basement puzzle door +# --- Backfilled 2026-07-20 from upstream Skretzo/shortest-path (7e7e5bf94b): routes absent locally (intentional exclusions omitted) --- +3205 3209 1 3206 3208 0 Climb-down;Staircase;16672 1 +3169 3171 0 3169 9571 0 Climb-down;Dark hole;5947 2 +3169 9571 0 3169 3171 0 Climb;Climbing rope;5946 2 +3168 3172 0 3168 9572 0 Climb-down;Dark hole;5947 2 +3168 9572 0 3168 3172 0 Climb;Climbing rope;5946 2 +3170 3172 0 3170 9572 0 Climb-down;Dark hole;5947 2 +3170 9572 0 3170 3172 0 Climb;Climbing rope;5946 2 +3169 3173 0 3167 9573 0 Climb-down;Dark hole;5947 2 +3225 9542 0 3219 9532 2 Enter;Tunnel;6659 2 +3227 9542 0 3219 9532 2 Enter;Tunnel;6659 2 +3218 9532 2 3226 9542 0 Enter;Tunnel;6658 2 +3220 9532 2 3226 9542 0 Enter;Tunnel;6658 2 +3239 9525 2 3241 9525 2 Climb;Rocks;6673 4 +3241 9525 2 3239 9525 2 Climb;Rocks;6673 4 +3239 9524 2 3241 9524 2 Climb;Rocks;6673 4 +3241 9524 2 3239 9524 2 Climb;Rocks;6673 4 +3238 9497 2 3240 9497 2 Climb;Rocks;6672 4 +3238 9498 2 3240 9498 2 Climb;Rocks;6672 4 +3238 9499 2 3240 9499 2 Climb;Rocks;6672 4 +2597 3087 0 2596 3087 0 Open;Magic guild door;1732 66 Magic 1 +2596 3087 0 2597 3087 0 Open;Magic guild door;1732 1 +2597 3088 0 2596 3088 0 Open;Magic guild door;1733 66 Magic 1 +2596 3088 0 2597 3088 0 Open;Magic guild door;1733 1 +2584 3087 0 2585 3087 0 Open;Magic guild door;1733 66 Magic 1 +2585 3087 0 2584 3087 0 Open;Magic guild door;1733 1 +2584 3088 0 2585 3088 0 Open;Magic guild door;1732 66 Magic 1 +2585 3088 0 2584 3088 0 Open;Magic guild door;1732 1 +2683 3271 0 2683 3268 1 Cross;Gangplank;2085 3 +2683 3268 1 2683 3271 0 Cross;Gangplank;2086 3 +3077 3493 0 3077 9893 0 Open;trapdoor;12267 Shadow of the Storm 1 +3077 9893 0 3077 3493 0 Climb;Cellar stairs;12265 1 +3295 3428 0 3296 3428 0 Open;Gate;24560 3637>152 2 +3296 3428 0 3295 3428 0 Open;Gate;24560 3637>152 2 +3295 3429 0 3296 3429 0 Open;Gate;24561 3637>152 2 +3296 3429 0 3295 3429 0 Open;Gate;24561 3637>152 2 +2522 3595 0 2522 3597 0 Jump-across;Basalt rock;4551 2 +2522 3597 0 2522 3595 0 Jump-to;Beach;4550 2 +2522 3600 0 2522 3602 0 Jump-across;Basalt rock;4553 2 +2522 3602 0 2522 3600 0 Jump-across;Basalt rock;4552 2 +2518 3611 0 2516 3611 0 Jump-across;Basalt rock;4555 2 +2516 3611 0 2518 3611 0 Jump-across;Basalt rock;4554 2 +2514 3613 0 2514 3615 0 Jump-across;Basalt rock;4557 2 +2514 3615 0 2514 3613 0 Jump-across;Basalt rock;4556 2 +2514 3617 0 2514 3619 0 Jump-to;Rocky shore;4559 2 +2514 3619 0 2514 3617 0 Jump-across;Basalt rock;4558 2 +2508 3640 0 2505 3641 1 Climb-up;Staircase;4568 +2508 3640 0 2505 3641 2 Top-floor;Staircase;4568 +2505 3641 1 2506 3642 0 Climb-down;Staircase;4569 +2505 3641 1 2505 3641 2 Climb-up;Staircase;4569 +2505 3641 2 2506 3584 1 Climb-down;Staircase;4570 +2505 3641 2 2506 3642 0 Bottom-floor;Staircase;4570 +2510 3644 0 2518 9994 0 Climb;Iron ladder;4383 +2518 9994 0 2510 3644 0 Climb;Iron ladder;4384 +2515 10005 0 2515 10008 0 Climb;Iron ladder;4384 +2515 10008 0 2515 10005 0 Climb;Iron ladder;4383 +2516 10002 0 2516 10003 0 Open;Strange wall;4384 +2513 10003 0 2513 10002 0 Open;Strange wall;4384 +2504 3191 0 2515 3159 0 Follow;Elkoy;4968 111>0 5 +2515 3159 0 2504 3191 0 Follow;Elkoy;4968 111>0 5 +1509 3595 0 1509 3593 1 Climb-up;Ladder;42207 +1509 3593 1 1509 3590 0 Climb-down;Ladder;42208 +1496 3571 0 1496 3571 1 Climb-up;Ladder;42207 +1496 3571 1 1496 3571 0 Climb-down;Ladder;42208 +1519 3592 0 1519 3592 1 Climb-up;Ladder;42207 +1519 3592 1 1519 3592 0 Climb-down;Ladder;42208 +1539 3581 0 1539 3581 1 Climb-up;Ladder;42207 +1539 3581 1 1539 3581 0 Climb-down;Ladder;42208 +1524 3563 0 1520 3563 1 Climb;Stairs;27201 +1520 3563 1 1524 3563 0 Climb;Stairs;27202 +1527 3563 0 1523 3563 1 Climb;Stairs;27201 +1523 3563 1 1527 3563 0 Climb;Stairs;27202 +1524 3543 0 1528 3543 1 Climb;Stairs;27199 +1528 3543 1 1524 3543 0 Climb;Stairs;27200 +1539 3547 0 1539 3547 1 Climb-up;Ladder;42207 +1539 3547 1 1539 3547 0 Climb-down;Ladder;42208 +1539 3556 0 1539 3556 1 Climb-up;Ladder;42207 +1539 3556 1 1539 3556 0 Climb-down;Ladder;42208 +1543 3570 0 1543 3570 1 Climb-up;Ladder;42207 +1543 3570 1 1543 3570 0 Climb-down;Ladder;42208 +1552 3567 0 1552 3567 1 Climb-up;Staircase;42193 +1552 3567 1 1552 3567 0 Climb-down;Staircase;42194 +1552 3560 1 1552 3560 2 Climb-up;Staircase;42193 +1552 3560 2 1552 3560 1 Climb-down;Staircase;42194 +1565 3570 0 1565 3570 1 Climb-up;Ladder;42207 +1565 3570 1 1565 3570 0 Climb-down;Ladder;42208 +1567 3557 0 1571 3557 1 Climb-up;Staircase;42195 +1571 3557 1 1567 3557 0 Climb-down;Staircase;42196 +1567 3557 1 1563 3557 2 Climb-up;Staircase;42195 +1563 3557 2 1567 3557 1 Climb-down;Staircase;42196 +1568 3545 0 1568 3545 1 Climb-up;Ladder;42207 +1568 3545 1 1568 3545 0 Climb-down;Ladder;42208 +3651 3486 0 3653 3486 0 Pay-toll(2-Ecto);Energy Barrier;16105 2 +3651 3485 0 3653 3485 0 Pay-toll(2-Ecto);Energy Barrier;16105 2 +3653 3486 0 3651 3486 0 Pay-toll(2-Ecto);Energy Barrier;16105 2 +3653 3485 0 3651 3485 0 Pay-toll(2-Ecto);Energy Barrier;16105 2 +3669 3452 0 3669 3454 0 Pay-toll(2-Ecto);Energy Barrier;16105 2 +3709 3496 0 3712 3496 0 Cross;Gangplank;11209 2 +3712 3496 0 3709 3496 0 Cross;Gangplank;11210 2 +3714 3503 0 3714 3503 1 Climb-up;Ship's ladder;11308 2 +3714 3503 1 3714 3503 0 Climb-down;Ship's ladder;11309 2 +3578 3526 0 3577 9927 0 Push;Memorial;5167 Creature of Fenkenstrain 2 +3577 9927 0 3578 3526 0 Climb-up;Ladder;17387 2 +3504 9969 0 3504 3569 0 Climb-up;Ladder;17387 Creature of Fenkenstrain 2 +3504 3571 0 3504 9969 0 Push;Memorial;5167 2 +3019 9741 0 3019 9741 0 Climb-down;Ladder;30367 60 Mining 2 +3019 9741 0 3019 9741 0 Climb-up;Ladder;17386 2 +3019 3337 0 3019 9737 0 Climb-down;Ladder;30367 60 Mining 2 +3019 9737 0 3019 3337 0 Climb-up;Ladder;17386 2 +3017 3339 0 3017 9739 0 Climb-down;Ladder;30367 60 Mining 2 +3017 9739 0 3017 3339 0 Climb-up;Ladder;17386 2 +3330 3520 0 3330 3523 0 Cross;Wilderness Ditch;23271 4 +3330 3523 0 3330 3520 0 Cross;Wilderness Ditch;23271 4 +3331 3520 0 3331 3523 0 Cross;Wilderness Ditch;23271 4 +3331 3523 0 3331 3520 0 Cross;Wilderness Ditch;23271 4 +3332 3520 0 3332 3523 0 Cross;Wilderness Ditch;23271 4 +3332 3523 0 3332 3520 0 Cross;Wilderness Ditch;23271 4 +3333 3520 0 3333 3523 0 Cross;Wilderness Ditch;23271 4 +3333 3523 0 3333 3520 0 Cross;Wilderness Ditch;23271 4 +3334 3520 0 3334 3523 0 Cross;Wilderness Ditch;23271 4 +3334 3523 0 3334 3520 0 Cross;Wilderness Ditch;23271 4 +3335 3520 0 3335 3523 0 Cross;Wilderness Ditch;23271 4 +3335 3523 0 3335 3520 0 Cross;Wilderness Ditch;23271 4 +3336 3520 0 3336 3523 0 Cross;Wilderness Ditch;23271 4 +3336 3523 0 3336 3520 0 Cross;Wilderness Ditch;23271 4 +3337 3520 0 3337 3523 0 Cross;Wilderness Ditch;23271 4 +3337 3523 0 3337 3520 0 Cross;Wilderness Ditch;23271 4 +3338 3520 0 3338 3523 0 Cross;Wilderness Ditch;23271 4 +3338 3523 0 3338 3520 0 Cross;Wilderness Ditch;23271 4 +3339 3520 0 3339 3523 0 Cross;Wilderness Ditch;23271 4 +3339 3523 0 3339 3520 0 Cross;Wilderness Ditch;23271 4 +3340 3520 0 3340 3523 0 Cross;Wilderness Ditch;23271 4 +3340 3523 0 3340 3520 0 Cross;Wilderness Ditch;23271 4 +3384 10052 0 3259 3663 0 Exit;Opening;40389 2 +3386 10052 0 3259 3663 0 Exit;Opening;40389 2 +3405 10145 0 3294 3749 0 Exit;Opening;40391 2 +3406 10145 0 3294 3749 0 Exit;Opening;40391 2 +3407 10145 0 3294 3749 0 Exit;Opening;40391 2 +3067 3739 0 3187 10127 0 Jump-down;Crevice;40386 2 +3068 3739 0 3187 10127 0 Jump-down;Crevice;40386 2 +3220 10088 0 3220 10084 0 Jump-to;Pillar;31561 65 Agility 4 +3220 10084 0 3220 10088 0 Jump-to;Pillar;31561 65 Agility 4 +3198 10136 0 3202 10132 0 Jump-to;Pillar;31562 4 +3202 10132 0 3198 10136 0 Jump-to;Pillar;31562 4 +3200 10196 0 3204 10196 0 Jump-to;Pillar;31561 4 +3204 10196 0 3200 10196 0 Jump-to;Pillar;31561 4 +3180 10211 0 3180 10207 0 Jump-to;Pillar;31561 4 +3180 10207 0 3180 10211 0 Jump-to;Pillar;31561 4 +3217 10058 0 3102 3655 0 Climb-up;Stairs;31558 2 +3246 10215 0 3124 3805 0 Climb-up;Stairs;43868 2 +3184 3944 0 3184 3945 0 Open;Gate;26760 2 +3184 3945 0 3184 3944 0 Open;Gate;26760 7500 Coins 4469=0;4468=0;4467=0; 2 +3184 3945 0 3184 3944 0 Open;Gate;26760 6000 Coins 4469=0;4468=0;4467=1 2 +3184 3945 0 3184 3944 0 Open;Gate;26760 3750 Coins 4469=0;4468=1 2 +3184 3945 0 3184 3944 0 Open;Gate;26760 4469=1 2 +2800 5160 0 2166 4409 2 Climb-down;Ladder;20278 2 +2166 4409 2 2800 5160 0 Climb-up;Ladder;20281 2 +2705 5363 0 2705 5366 1 Climb-up;Stairs;22931 1 +2706 5363 0 2705 5366 1 Climb-up;Stairs;22931 1 +2705 5366 1 2705 5363 0 Climb-down;Stairs;22933 1 +2706 5366 1 2705 5363 0 Climb-down;Stairs;22933 1 +2720 5358 0 2720 5361 1 Climb-up;Stairs;22939 1 +2721 5358 0 2720 5361 1 Climb-up;Stairs;22939 1 +2720 5361 1 2720 5358 0 Climb-down;Stairs;22940 1 +2721 5361 1 2720 5358 0 Climb-down;Stairs;22940 1 +2747 5374 0 3317 9603 0 Open;Bone door;22945 1 +3317 9602 0 2747 5374 0 Open;Door;6919 1 +3318 9602 0 2748 5374 0 Open;Door;6919 1 +2736 5352 0 2733 5351 1 Climb-up;Stairs;22931 1 +2736 5351 0 2733 5351 1 Climb-up;Stairs;22931 1 +2733 5351 1 2736 5351 0 Climb-down;Stairs;22933 1 +2733 5352 1 2736 5351 0 Climb-down;Stairs;22933 1 +2727 5347 0 2731 5346 1 Climb-up;Stairs;22937 1 +2727 5346 0 2731 5346 1 Climb-up;Stairs;22937 1 +2731 5346 1 2727 5346 0 Climb-down;Stairs;22938 1 +2731 5347 1 2727 5346 0 Climb-down;Stairs;22938 1 +2694 5328 0 2694 5328 1 Climb-up;Ladder;22934 2 +2694 5328 1 2694 5328 0 Climb-down;Ladder;22936 2 +2705 5327 0 2701 5327 1 Climb-up;Stairs;22937 1 +2705 5328 0 2701 5327 1 Climb-up;Stairs;22937 1 +2701 5327 1 2705 5327 0 Climb-down;Stairs;22938 1 +2701 5328 1 2705 5327 0 Climb-down;Stairs;22938 1 +2738 5325 0 2738 5325 1 Climb-up;Ladder;22934 2 +2738 5325 1 2738 5325 0 Climb-down;Ladder;22936 2 +2705 5305 0 2701 5305 1 Climb-up;Stairs;22937 1 +2705 5306 0 2701 5305 1 Climb-up;Stairs;22937 1 +2701 5305 1 2705 5305 0 Climb-down;Stairs;22938 1 +2701 5306 1 2705 5305 0 Climb-down;Stairs;22938 1 +2730 5306 0 2734 5306 1 Climb-up;Stairs;22937 1 +2730 5307 0 2734 5306 1 Climb-up;Stairs;22937 1 +2734 5306 1 2730 5306 0 Climb-down;Stairs;22938 1 +2734 5307 1 2730 5306 0 Climb-down;Stairs;22938 1 +2729 5304 0 2729 5300 1 Climb-up;Stairs;22937 1 +2730 5304 0 2729 5300 1 Climb-up;Stairs;22937 1 +2729 5300 1 2729 5304 0 Climb-down;Stairs;22938 1 +2730 5300 1 2729 5304 0 Climb-down;Stairs;22938 1 +2713 5293 0 2709 5293 1 Climb-up;Stairs;22937 1 +2713 5294 0 2709 5293 1 Climb-up;Stairs;22937 1 +2709 5293 1 2713 5293 0 Climb-down;Stairs;22938 1 +2709 5294 1 2713 5293 0 Climb-down;Stairs;22938 1 +2721 5292 0 2725 5292 1 Climb-up;Stairs;22937 1 +2721 5293 0 2725 5292 1 Climb-up;Stairs;22937 1 +2725 5292 1 2721 5292 0 Climb-down;Stairs;22938 1 +2725 5293 1 2721 5292 0 Climb-down;Stairs;22938 1 +2713 5285 0 2713 5281 1 Climb-up;Stairs;22937 1 +2714 5285 0 2713 5281 1 Climb-up;Stairs;22937 1 +2713 5281 1 2713 5285 0 Climb-down;Stairs;22938 1 +2714 5281 1 2713 5285 0 Climb-down;Stairs;22938 1 +2713 5277 0 2713 5281 1 Climb-up;Stairs;22937 1 +2714 5277 0 2713 5281 1 Climb-up;Stairs;22937 1 +2713 5281 1 2713 5277 0 Climb-down;Stairs;22938 1 +2714 5281 1 2713 5277 0 Climb-down;Stairs;22938 1 +2708 5275 0 2708 5275 1 Climb-up;Ladder;22934 2 +2708 5275 1 2708 5275 0 Climb-down;Ladder;22936 2 +2722 5276 0 2722 5272 1 Climb-up;Stairs;22937 1 +2723 5276 0 2722 5272 1 Climb-up;Stairs;22937 1 +2722 5272 1 2722 5276 0 Climb-down;Stairs;22938 1 +2723 5272 1 2722 5276 0 Climb-down;Stairs;22938 1 +2733 5275 0 2733 5278 1 Climb-up;Stairs;22931 1 +2734 5275 0 2733 5278 1 Climb-up;Stairs;22931 1 +2733 5278 1 2733 5275 0 Climb-down;Stairs;22932 1 +2734 5278 1 2733 5275 0 Climb-down;Stairs;22932 1 +2738 5277 0 2738 5281 1 Climb-up;Stairs;22937 1 +2739 5277 0 2738 5281 1 Climb-up;Stairs;22937 1 +2738 5281 1 2738 5277 0 Climb-down;Stairs;22938 1 +2739 5281 1 2738 5277 0 Climb-down;Stairs;22938 1 +2722 5268 0 2722 5272 1 Climb-up;Stairs;22937 1 +2723 5268 0 2722 5272 1 Climb-up;Stairs;22937 1 +2722 5272 1 2722 5268 0 Climb-down;Stairs;22938 1 +2723 5272 1 2722 5268 0 Climb-down;Stairs;22938 1 +2722 5260 0 2722 5257 1 Climb-up;Stairs;22939 1 +2723 5260 0 2722 5257 1 Climb-up;Stairs;22939 1 +2722 5257 1 2722 5260 0 Climb-down;Stairs;22940 1 +2723 5257 1 2722 5260 0 Climb-down;Stairs;22940 1 +2703 5363 1 2703 5363 2 Climb-up;Ladder;22934 2 +2703 5363 2 2703 5363 1 Climb-down;Ladder;22935 2 +2740 5359 1 2740 5362 2 Climb-up;Stairs;22931 1 +2741 5359 1 2740 5362 2 Climb-up;Stairs;22931 1 +2740 5362 2 2740 5359 1 Climb-down;Stairs;22932 1 +2741 5362 2 2740 5359 1 Climb-down;Stairs;22932 1 +2745 5355 1 2745 5355 2 Climb-up;Ladder;22934 1 +2745 5355 2 2745 5355 1 Climb-down;Ladder;22935 1 +2698 5304 1 2695 5304 2 Climb-up;Stairs;22931 1 +2695 5304 2 2698 5304 1 Climb-down;Stairs;22932 1 +2739 5296 1 2742 5296 2 Climb-up;Stairs;22931 1 +2742 5296 2 2739 5296 1 Climb-down;Stairs;22932 1 +2696 5291 1 2696 5294 2 Climb-up;Stairs;22931 1 +2697 5291 1 2696 5294 2 Climb-up;Stairs;22931 1 +2696 5294 2 2696 5291 1 Climb-down;Stairs;22932 1 +2697 5294 2 2696 5291 1 Climb-down;Stairs;22932 1 +2743 5286 1 2743 5289 2 Climb-up;Stairs;22931 1 +2743 5289 2 2743 5286 1 Climb-down;Stairs;22932 1 +2739 5260 1 2739 5257 2 Climb-up;Stairs;22931 1 +2740 5260 1 2739 5257 2 Climb-up;Stairs;22931 1 +2739 5257 2 2739 5260 1 Climb-down;Stairs;22932 1 +2740 5257 2 2739 5260 1 Climb-down;Stairs;22932 1 +2722 5255 1 2722 5249 3 Climb-up;Stairs;22941 1 +2723 5255 1 2722 5249 3 Climb-up;Stairs;22941 1 +2722 5249 3 2722 5255 1 Climb-down;Stairs;22942 1 +2723 5249 3 2722 5255 1 Climb-down;Stairs;22942 1 +2719 5242 3 2715 5241 0 Climb-down;Ladder top;22666 2 +3680 2963 0 3786 2824 0 Transport;Brother Tranquility;550 2 +3786 2824 0 3680 2963 0 Transport;Brother Tranquility;550 2 +3495 3464 0 3477 9845 0 Open;Trapdoor;5055 +2764 3666 0 2766 3663 0 Use;Rope -> Boulder;5842 954 1 +2865 3938 0 2866 3938 0 Squeeze-through;Broken fence;46817 6528>199 +2866 3938 0 2865 3938 0 Squeeze-through;Broken fence;46817 6528>199 +2895 3672 0 2893 10074 2 Enter;Cave Entrance;3759 1 +1795 3106 0 1799 9506 0 Enter;Colosseum entrance;50749 +1799 9506 0 1795 3106 0 Exit;Stairs;50750 +1799 9507 0 1795 3106 0 Exit;Stairs;50750 +2304 3194 0 2306 3194 0 Pass;Tree;8742 517>1 5 +2970 3462 0 2972 3462 0 Climb-over;Crumbling wall;24749 2 +2972 3462 0 2970 3462 0 Climb-over;Crumbling wall;24749 58 Thieving 2 +1401 3536 0 1275 3559 0 Travel;Mountain Guide;7600 5421=1 7 1: Mount Quidamortem. +1401 3536 0 1272 3475 0 Travel;Mountain Guide;7600 5421=1 7 2: South of Quidamortem. +1275 3559 0 1401 3536 0 Travel;Mountain Guide;7600 5421=1 7 1: The Shayzien Outpost. +1275 3559 0 1272 3475 0 Travel;Mountain Guide;7600 5421=1 7 2: South of Quidamortem. +1272 3475 0 1401 3536 0 Travel;Mountain Guide;7600 5421=1 7 1: The Shayzien Outpost. +1272 3475 0 1275 3559 0 Travel;Mountain Guide;7600 5421=1 7 2: Mount Quidamortem. +1259 3430 0 1271 3436 0 Pass-through;Cave;57219 4 +1271 3436 0 1259 3430 0 Pass-through;Cave;57220 4 +1486 3232 0 1361 3309 0 Follow;Mountain Guide;14529 17226=1 5 +1361 3309 0 1486 3232 0 Follow;Mountain Guide;14529 17226=1 5 +3280 3412 0 1700 3141 0 Travel;Primio;12888 Children of the Sun 6 Civitas illa Fortis +1703 3140 0 3280 3412 0 Travel;Primio;12889 Children of the Sun 6 Varrock +2744 3152 0 2713 9564 0 Enter;Dungeon entrance;20876 875 Coins 2 +2744 3152 0 2713 9564 0 Enter;Dungeon entrance;20876 5628=1 2 +2745 3152 0 2713 9564 0 Enter;Dungeon entrance;20876 875 Coins 2 +2745 3152 0 2713 9564 0 Enter;Dungeon entrance;20876 5628=1 2 +2746 3152 0 2713 9564 0 Enter;Dungeon entrance;20876 875 Coins 2 +2746 3152 0 2713 9564 0 Enter;Dungeon entrance;20876 5628=1 2 +2713 9564 0 2745 3152 0 Leave;exit;20878 2 +2835 2987 0 2835 2987 1 Climb-up;Ladder;16684 2 +2835 2987 1 2835 2987 0 Climb-down;Ladder;16679 2 +2834 2988 0 2834 2988 1 Climb-up;Ladder;16684 2 +2834 2988 1 2834 2988 0 Climb-down;Ladder;16679 2 +2835 2989 0 2835 2989 1 Climb-up;Ladder;16684 2 +2835 2989 1 2835 2989 0 Climb-down;Ladder;16679 2 +2836 2988 0 2836 2988 1 Climb-up;Ladder;16684 2 +2836 2988 1 2836 2988 0 Climb-down;Ladder;16679 2 +2861 2998 0 2861 2998 1 Climb-up;Ladder;17026 2 +2861 2998 1 2861 2998 0 Climb-down;Ladder;16679 2 +2860 2997 1 2860 2997 0 Climb-down;Ladder;16679 2 +2862 2997 1 2862 2997 0 Climb-down;Ladder;16679 2 +2861 2995 1 2861 2995 2 Climb-up;Ladder;2268 2 +2861 2995 2 2861 2995 1 Climb-down;Ladder;2269 2 +2823 2958 0 2823 2958 1 Climb-up;Ladder;16683 2 +2823 2958 1 2823 2958 0 Climb-down;Ladder;16679 2 +2824 2957 0 2824 2957 1 Climb-up;Ladder;16683 2 +2824 2957 1 2824 2957 0 Climb-down;Ladder;16679 2 +2824 2959 0 2824 2959 1 Climb-up;Ladder;16683 2 +2824 2959 1 2824 2959 0 Climb-down;Ladder;16679 2 +2825 2958 0 2825 2958 1 Climb-up;Ladder;16683 2 +2825 2958 1 2825 2958 0 Climb-down;Ladder;16679 2 +2845 2954 0 2845 2954 1 Climb-up;Ladder;16683 2 +2845 2954 1 2845 2954 0 Climb-down;Ladder;16679 2 +2844 2953 1 2844 2953 0 Climb-down;Ladder;16679 2 +2844 2955 1 2844 2955 0 Climb-down;Ladder;16679 2 +2859 2954 0 2859 2954 1 Climb-up;Ladder;16683 2 +2859 2954 1 2859 2954 0 Climb-down;Ladder;16679 2 +2860 2953 1 2860 2953 0 Climb-down;Ladder;16679 2 +2860 2955 1 2860 2955 0 Climb-down;Ladder;16679 2 +2870 2971 0 2870 2971 1 Climb-up;Ladder;16683 2 +2870 2971 1 2870 2971 0 Climb-down;Ladder;16679 2 +2872 2971 0 2872 2971 1 Climb-up;Ladder;16683 2 +2872 2971 1 2872 2971 0 Climb-down;Ladder;16679 2 +2569 3121 0 2569 9525 0 Climb-down;Staircase;16665 1 +2570 3121 0 2569 9525 0 Climb-up;Staircase;16665 1 +2569 9525 0 2569 3121 0 Climb-up;Staircase;16665 1 +2569 9526 0 2569 3121 0 Climb-up;Staircase;16665 1 +2572 9499 0 2588 9573 0 Pray-at;Altar;412 2 +2579 9583 0 2567 9524 0 Climb-up;Staircase;16665 1 +2578 9583 0 2567 9524 0 Climb-up;Staircase;16665 1 +2594 3085 0 2594 9485 0 Climb-down;Ladder;17384 2 +2594 9486 0 2594 3085 0 Climb-up;Ladder;17383 2 +2591 3088 0 2590 3092 1 Climb-up;Staircase;15645 1 +2590 3083 1 2590 3087 2 Climb-up;Staircase;15645 1 +2591 3083 1 2590 3087 2 Climb-up;Staircase;15645 1 +2590 3087 2 2590 3083 1 Climb-down;Staircase;15648 1 +2591 3087 2 2590 3083 1 Climb-down;Staircase;15648 1 +2549 3112 2 2549 3112 1 Climb-down;Ladder;2797 2 +2548 3111 2 2549 3112 1 Climb-down;Ladder;2797 2 +2548 3111 1 2549 3112 2 Climb-up;Ladder;2796 2 +2550 3111 1 2549 3112 2 Climb-up;Ladder;2796 2 +2549 3112 1 2549 3112 2 Climb-up;Ladder;2796 2 +2545 3111 1 2544 3112 0 Climb-down;Ladder;17122 2 +2543 3111 1 2544 3112 0 Climb-down;Ladder;17122 2 +2545 3111 0 2545 3111 1 Climb-up;Ladder;2833 2 +2543 3111 0 2543 3111 1 Climb-up;Ladder;2833 2 +1829 9974 0 1702 3575 0 Climb-up;Ladder;34863 2 +1831 9974 0 1702 3575 0 Climb-up;Ladder;34863 2 +1798 9969 0 1670 3569 0 Climb-up;Staircase;34864 1 +1799 9969 0 1670 3569 0 Climb-up;Staircase;34864 1 +1800 9967 0 1670 3569 0 Climb-up;Staircase;34864 1 +1799 9966 0 1670 3569 0 Climb-up;Staircase;34864 1 +1671 3568 0 1800 9968 0 Climb-down;Staircase;34865 1 +1671 3567 0 1800 9968 0 Climb-down;Staircase;34865 1 +1670 3566 0 1800 9968 0 Climb-down;Staircase;34865 1 +1824 9973 0 1825 9973 0 Open;Temple Door;34843 2 +1825 9973 0 1824 9973 0 Open;Temple Door;34843 8398=1 2 +1802 9958 0 1802 9956 0 Open;Temple Door;34843 8397=1 2 +1802 9956 0 1802 9958 0 Open;Temple Door;34843 8397=1 2 +1803 9968 0 1726 9994 0 Enter;Strange passage;28918 5087=1 1 +1803 9967 0 1726 9994 0 Enter;Strange passage;28918 5087=1 1 +1470 3652 0 1650 9987 0 Enter;Hole;28915 5088=1 2 +1470 3654 0 1650 9987 0 Enter;Hole;28915 5088=1 2 +1471 3653 0 1650 9987 0 Enter;Hole;28915 5088=1 2 +1563 3790 0 1617 10101 0 Enter;Hole;28915 5088=1 2 +1563 3792 0 1617 10101 0 Enter;Hole;28915 5088=1 2 +1564 3791 0 1617 10101 0 Enter;Hole;28915 5088=1 2 +1695 3865 0 1719 10101 0 Enter;Hole;28915 5088=1 2 +1696 3866 0 1719 10101 0 Enter;Hole;28915 5088=1 2 +1697 3865 0 1719 10101 0 Enter;Hole;28915 5088=1 2 +1726 9994 0 1803 9968 0 Climb-up;Vine;28897 2 +1725 9993 0 1803 9968 0 Climb-up;Vine;28897 2 +1726 9992 0 1803 9968 0 Climb-up;Vine;28897 2 +1649 9986 0 1469 3653 0 Climb-up;Vine;28896 2 +1650 9985 0 1469 3653 0 Climb-up;Vine;28896 2 +1651 9986 0 1469 3653 0 Climb-up;Vine;28896 2 +1616 10102 0 1562 3791 0 Climb-up;Vine;28895 2 +1617 10103 0 1562 3791 0 Climb-up;Vine;28895 2 +1618 10102 0 1562 3791 0 Climb-up;Vine;28895 2 +1718 10102 0 1696 3864 0 Climb-up;Vine;28898 2 +1719 10103 0 1696 3864 0 Climb-up;Vine;28898 2 +1720 10102 0 1696 3864 0 Climb-up;Vine;28898 2 +1638 10047 0 1461 9879 0 Climb-up;Vine;42350 2 +1639 10046 0 1461 9879 0 Climb-up;Vine;42350 2 +1639 10048 0 1461 9879 0 Climb-up;Vine;42350 2 +1640 10047 0 1461 9879 0 Climb-up;Vine;42350 2 +1461 9879 0 1639 10046 0 Enter;Strange passage;42249 12341=1 2 +1665 10051 0 1639 3673 0 Climb-up;Vine ladder;28894 2 +1666 10052 0 1639 3673 0 Climb-up;Vine ladder;28894 2 +1667 10051 0 1639 3673 0 Climb-up;Vine ladder;28894 2 +1631 3570 0 1634 3570 0 Climb-over;Stile;7527 3 +1634 3570 0 1631 3570 0 Climb-over;Stile;7527 3 +1658 3505 0 1657 3505 0 Open;Gate;28851 60 Woodcutting 2 +1657 3505 0 1658 3505 0 Open;Gate;28851 2 +1658 3504 0 1657 3504 0 Open;Gate;28851 60 Woodcutting 2 +1657 3504 0 1658 3504 0 Open;Gate;28851 2 +1562 3488 0 1563 3488 0 Open;Gate;28852 60 Woodcutting 2 +1563 3488 0 1562 3488 0 Open;Gate;28852 2 +1562 3487 0 1563 3487 0 Open;Gate;28852 60 Woodcutting 2 +1563 3487 0 1562 3487 0 Open;Gate;28852 2 +2455 3049 0 2457 3049 0 Climb-over;Crushed barricade;6881 496=1 2 +2457 3049 0 2455 3049 0 Climb-over;Crushed barricade;6881 496=1 2 +2455 3048 0 2457 3048 0 Climb-over;Crushed barricade;6882 496=1 2 +2485 3045 0 2477 9437 2 Climb-down;Stairs;6841 487>10 7 +2486 3045 0 2477 9437 2 Climb-down;Stairs;6841 487>10 7 +2477 9438 2 2485 3045 0 Climb-up;Stairs;6842 7 +2762 2943 0 2762 2941 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2762 2940 0 2762 2942 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2762 2938 0 2762 2936 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2762 2936 0 2762 2938 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2762 2936 0 2762 2934 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2762 2934 0 2762 2936 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2791 2935 0 2791 2937 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2791 2937 0 2791 2935 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2791 2937 0 2791 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2791 2939 0 2791 2937 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2791 2939 0 2791 2941 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2791 2941 0 2791 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2791 2941 0 2791 2943 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2791 2943 0 2791 2941 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2793 2943 0 2793 2941 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2793 2941 0 2793 2943 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2793 2941 0 2793 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2793 2939 0 2793 2941 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2793 2939 0 2793 2937 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2793 2937 0 2793 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2795 2938 0 2795 2940 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2795 2941 0 2795 2939 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2795 2940 0 2795 2942 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2795 2943 0 2795 2941 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2798 2943 0 2798 2941 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2798 2940 0 2798 2942 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2798 2941 0 2798 2939 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2798 2938 0 2798 2940 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2799 2937 0 2799 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2799 2939 0 2799 2937 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2799 2939 0 2799 2941 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2799 2941 0 2799 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2799 2941 0 2799 2943 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2799 2943 0 2799 2941 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2800 2943 0 2800 2941 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2800 2940 0 2800 2942 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2800 2941 0 2800 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2800 2938 0 2800 2940 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2800 2939 0 2800 2937 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2800 2936 0 2800 2938 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2816 2936 0 2816 2938 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2816 2938 0 2816 2936 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2816 2938 0 2816 2940 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2816 2940 0 2816 2938 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2819 2940 0 2819 2938 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2819 2938 0 2819 2940 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2819 2938 0 2819 2936 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2819 2936 0 2819 2938 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2820 2935 0 2820 2937 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2820 2938 0 2820 2936 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2820 2937 0 2820 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2820 2940 0 2820 2938 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2864 2934 0 2864 2936 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2864 2936 0 2864 2934 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2864 2936 0 2864 2938 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2864 2939 0 2864 2937 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2864 2939 0 2864 2941 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2864 2941 0 2864 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2866 2941 0 2866 2939 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2866 2939 0 2866 2937 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2866 2938 0 2866 2940 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2866 2936 0 2866 2938 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2866 2936 0 2866 2934 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2866 2934 0 2866 2936 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2868 2934 0 2868 2936 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2868 2936 0 2868 2934 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2868 2936 0 2868 2938 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2868 2939 0 2868 2937 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2868 2938 0 2868 2940 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2868 2941 0 2868 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2872 2934 0 2872 2936 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2872 2936 0 2872 2934 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2872 2938 0 2872 2940 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2872 2941 0 2872 2939 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2932 2943 0 2932 2941 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2932 2940 0 2932 2942 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2932 2941 0 2932 2939 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2932 2938 0 2932 2940 0 Chop-down;Jungle Bush;2892 975 6313 6315 6317 139>49 2 +2932 2938 0 2932 2936 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2932 2936 0 2932 2938 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2933 2937 0 2933 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2933 2939 0 2933 2937 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2933 2939 0 2933 2941 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2933 2941 0 2933 2939 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2933 2941 0 2933 2943 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2933 2943 0 2933 2941 0 Chop-down;Jungle tree;2890 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2936 2943 0 2936 2941 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2936 2940 0 2936 2942 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2936 2940 0 2936 2938 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2936 2938 0 2936 2940 0 Chop-down;Jungle Bush;2893 975 6313 6315 6317 139>49 2 +2936 2938 0 2936 2936 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2936 2936 0 2936 2938 0 Chop-down;Jungle tree;2889 1351 1349 1353 1361 1355 1357 1359 6739 23673 23279 13241 20011 139>49 10 +2521 3494 0 2521 3494 1 Climb-up;Ladder;16683 2 +2522 3493 0 2522 3493 1 Climb-up;Ladder;16683 2 +2521 3494 1 2521 3494 0 Climb-down;Ladder;16679 2 +2522 3493 1 2522 3493 0 Climb-down;Ladder;16679 2 +2511 3511 0 1768 5366 0 Jump-into;Whirlpool;25274 3759>1 2 +2512 3511 0 1768 5366 0 Jump-into;Whirlpool;25274 3759>1 2 +1742 5352 0 2531 3446 0 Ride;Aged log;25216 2 +1761 5362 0 2531 3446 0 Ride;Aged log;25216 2 +1559 3046 0 1556 3046 2 Climb-up;Rope;51647 2 +1556 3046 2 1559 3046 0 Climb-down;Rope;51644 2 +1557 3047 0 1557 9451 0 Climb-down;Stairs;51641 2 +1557 9451 0 1557 3047 0 Climb-up;Stairs;51642 2 +1533 3051 0 1533 9446 0 Enter;Cave;51761 2 +1533 3050 0 1533 9446 0 Enter;Cave;51761 2 +1533 9447 0 1533 3051 0 Exit;Cave;51760 2 +1533 9446 0 1533 3051 0 Exit;Cave;51760 2 +1533 9445 0 1533 3051 0 Exit;Cave;51760 2 +1248 3722 0 1248 3723 0 Open;Door;34463 45 Farming 1 +1248 3723 0 1248 3722 0 Open;Door;34463 1 +1249 3722 0 1249 3723 0 Open;Door;34464 45 Farming 1 +1249 3723 0 1249 3722 0 Open;Door;34464 1 +1646 9848 0 1643 3450 0 Climb;Sand pile;31691 6027>6 2 +1647 9848 0 1643 3450 0 Climb;Sand pile;31691 6027>6 2 +1646 3449 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1646 3450 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1645 3451 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1644 3451 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1643 3450 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1643 3449 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1644 3448 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1645 3448 0 1646 9848 0 Enter;Cave;31690 6027>6 2 +1673 9800 0 1677 9747 0 Climb-down;Tunnel entrance;31692 2 +1677 9747 0 1673 9800 0 Climb-down;Tunnel entrance;31692 2 +2822 3745 0 2803 10187 0 Enter;Cave entrance;5007 1 +2822 3744 0 2803 10187 0 Enter;Cave entrance;5007 1 +2822 3743 0 2803 10187 0 Enter;Cave entrance;5007 1 +2804 10187 0 2822 3745 0 Enter;Tunnel;5011 1 +2803 10187 0 2822 3745 0 Enter;Tunnel;5011 1 +2802 10187 0 2822 3745 0 Enter;Tunnel;5011 1 +2772 10232 0 2778 3869 0 Enter;Crevasse;5025 1 +2778 3869 0 2772 10232 0 Enter;Tunnel;5009 1 +2778 3870 0 2772 10232 0 Enter;Tunnel;5009 1 +2779 3871 0 2772 10232 0 Enter;Tunnel;5009 1 +2780 3871 0 2772 10232 0 Enter;Tunnel;5009 1 +2781 3871 0 2772 10232 0 Enter;Tunnel;5009 1 +2782 3870 0 2772 10232 0 Enter;Tunnel;5009 1 +2782 3869 0 2772 10232 0 Enter;Tunnel;5009 1 +2782 3868 0 2772 10232 0 Enter;Tunnel;5009 1 +2781 3867 0 2772 10232 0 Enter;Tunnel;5009 1 +2780 3867 0 2772 10232 0 Enter;Tunnel;5009 1 +2779 3867 0 2772 10232 0 Enter;Tunnel;5009 1 +2772 3836 0 2790 3794 0 Slide;Slope;5015 4084 18 +2773 3836 0 2790 3794 0 Slide;Slope;5015 4084 18 +2786 3772 0 2794 3719 0 Slide;Slope;5015 4084 30 +2785 3772 0 2794 3719 0 Slide;Slope;5015 4084 30 +2484 3486 1 2649 4516 0 Travel;Daero;1445 6 +2649 4518 0 2894 2726 0 Travel;Waydar;1446 4 +2654 4495 0 2393 3466 0 Operate;Teleportation Device;4869 6 +2896 2727 0 2393 3465 0 Travel;Waydar;1446 4 +2762 2989 0 2760 9389 0 Search;Well stacked rocks;2234 15 +2764 9376 0 2765 2976 0 Climb;Climbing rocks;2236 15 +2840 3516 0 2836 3517 0 Mine;Rock slide;2634 50 Mining 1265 1267 1269 12297 1273 1271 1275 11920 23680 23276 13243 20014 10 +2839 3516 0 2836 3517 0 Mine;Rock slide;2634 50 Mining 1265 1267 1269 12297 1273 1271 1275 11920 23680 23276 13243 20014 10 +2837 3517 0 2840 3516 0 Mine;Rock slide;2634 50 Mining 1265 1267 1269 12297 1273 1271 1275 11920 23680 23276 13243 20014 10 +2837 3518 0 2840 3517 0 Mine;Rock slide;2634 50 Mining 1265 1267 1269 12297 1273 1271 1275 11920 23680 23276 13243 20014 10 +2840 3517 0 2837 3518 0 Mine;Rock slide;2634 50 Mining 1265 1267 1269 12297 1273 1271 1275 11920 23680 23276 13243 20014 10 +2840 3518 0 2837 3519 0 Mine;Rock slide;2634 50 Mining 1265 1267 1269 12297 1273 1271 1275 11920 23680 23276 13243 20014 10 +1475 3687 0 1470 3687 0 Climb;Handholds;27362 6 +1470 3687 0 1475 3687 0 Climb;Handholds;42009 6 +1460 3690 0 1456 3690 0 Climb;Handholds;27362 6 +1456 3690 0 1460 3690 0 Climb;Handholds;42009 6 +3008 9549 0 3008 3149 0 Climb-up;Ladder;17385 1 +3008 9551 0 3008 3151 0 Climb-up;Ladder;17385 1 +3055 9562 0 3055 9555 0 Enter;Ice Cavern;10596 1 +3057 9562 0 3057 9555 0 Enter;Ice Cavern;10596 1 +3055 9555 0 3055 9562 0 Enter;Ice Cavern;10595 1 +3057 9555 0 3057 9562 0 Enter;Ice Cavern;10595 1 +3106 3559 0 3035 4852 0 Teleport;Mage of Zamorak;2581 Enter the Abyss +3039 4805 0 3039 4800 0 Enter;Passage;27054 +3039 4854 0 3039 4844 0 Go-through;Passage;26250 +3029 4850 0 3033 4843 0 Go-through;Passage;26250 +3021 4843 0 3039 4844 0 Go-through;Passage;26250 +3018 4834 0 3039 4844 0 Go-through;Passage;26250 +3018 4822 0 3039 4844 0 Go-through;Passage;26250 +3030 4812 0 3039 4844 0 Go-through;Passage;26250 +3042 4811 0 3039 4844 0 Go-through;Passage;26250 +3050 4813 0 3039 4844 0 Go-through;Passage;26250 +3058 4822 0 3039 4844 0 Go-through;Passage;26250 +3061 4831 0 3052 4831 0 Go-through;Passage;26250 +3059 4840 0 3039 4844 0 Go-through;Passage;26250 +3050 4850 0 3039 4844 0 Go-through;Passage;26250 +3034 4793 0 3221 3219 0 Operate;Appendage;27027 4 +3044 4842 0 2269 4840 0 Exit-through;Chaos rift;25382 +2259 4846 0 2259 4846 1 Climb-up;Ladder;16683 1 +2259 4846 1 2259 4846 0 Climb-up;Ladder;16683 1 +2275 4833 1 2275 4833 2 Climb-up;Ladder;16683 1 +2275 4833 2 2275 4833 1 Climb-up;Ladder;16683 1 +2255 4830 2 2255 4830 3 Climb-up;Ladder;16683 1 +2255 4830 3 2255 4830 2 Climb-up;Ladder;16683 1 +2281 4837 0 3056 3594 0 Use;Portal;34757 1 +2275 4847 3 3060 3585 0 Use;Portal;34757 1 +2273 4855 3 3066 3591 0 Use;Portal;34757 1 +3049 4839 0 2464 4826 0 Exit-through;Law rift;25382 Troll Stronghold +2464 4818 0 2858 3378 0 Enter;Portal;34755 1 +3050 4837 0 2209 4834 0 Exit-through;Death rift;25382 Mourning's End Part II +2208 4830 0 1860 4639 0 Enter;Portal;34758 1 +3051 4833 0 2714 4838 0 Exit-through;Water rift;25382 +3050 4829 0 1816 3856 0 Exit-through;Soul rift;25382 +3047 4825 0 2846 4836 0 Exit-through;Air rift;25382 +2842 4828 0 2983 3288 0 Enter;Portal;34748 1 +3044 4822 0 2784 4843 0 Exit-through;Mind rift;25382 +2792 4827 0 2980 3511 0 Enter;Portal;34749 1 +3039 4821 0 2520 4848 0 Exit-through;Body rift;25382 +2521 4834 0 3050 3442 0 Enter;Portal;34753 1 +3031 4825 0 2660 4843 0 Exit-through;Earth rift;25382 +3029 4830 0 2587 4836 0 Exit-through;Fire rift;25382 +2575 4849 0 3310 3252 0 Use;Portal;34752 1 +3027 4834 0 3229 4834 0 Exit-through;Blood rift;25382 Sins of the Father +3240 4832 0 3559 9779 0 Use;Portal;43478 1 +3224 4832 0 3559 9779 0 Use;Portal;43478 1 +3028 4837 0 2142 4836 0 Exit-through;Cosmic rift;25382 Lost City +2122 4833 0 2405 4381 0 Use;Portal;34754 1 +2142 4853 0 2405 4381 0 Use;Portal;34754 1 +2162 4833 0 2405 4381 0 Use;Portal;34754 1 +2142 4813 0 2405 4381 0 Use;Portal;34754 1 +3035 4842 0 2400 4844 0 Exit-through;Nature rift;25382 +2400 4835 0 2865 3022 0 Use;Portal;34756 1 +2824 10169 0 2615 4966 0 Talk-to;Dondakan the Dwarf;4891 4567 Between a Rock... 4 +1633 4023 0 1631 4023 0 Jump;Gap;29326 60 Agility 2 +1631 4023 0 1629 4023 0 Jump;Gap;29326 60 Agility 2 +1629 4023 0 1627 4023 0 Jump;Gap;29326 60 Agility 2 +1631 4023 0 1633 4023 0 Jump;Gap;29326 60 Agility 2 +1629 4023 0 1631 4023 0 Jump;Gap;29326 60 Agility 2 +1627 4023 0 1629 4023 0 Jump;Gap;29326 60 Agility 2 +1627 3963 0 1630 3979 0 Enter;Door of Dinh;29322 50 Firemaking 1 +1628 3963 0 1630 3979 0 Enter;Door of Dinh;29322 50 Firemaking 1 +1629 3963 0 1630 3979 0 Enter;Door of Dinh;29322 50 Firemaking 1 +1630 3963 0 1630 3979 0 Enter;Door of Dinh;29322 50 Firemaking 1 +1631 3963 0 1630 3979 0 Enter;Door of Dinh;29322 50 Firemaking 1 +1632 3963 0 1630 3979 0 Enter;Door of Dinh;29322 50 Firemaking 1 +1633 3963 0 1630 3979 0 Enter;Door of Dinh;29322 50 Firemaking 1 +1627 3963 0 1630 3958 0 Enter;Door of Dinh;29322 1 +1628 3963 0 1630 3958 0 Enter;Door of Dinh;29322 1 +1629 3963 0 1630 3958 0 Enter;Door of Dinh;29322 1 +1630 3963 0 1630 3958 0 Enter;Door of Dinh;29322 1 +1631 3963 0 1630 3958 0 Enter;Door of Dinh;29322 1 +1632 3963 0 1630 3958 0 Enter;Door of Dinh;29322 1 +1633 3963 0 1630 3958 0 Enter;Door of Dinh;29322 1 +3633 9503 0 3637 9503 0 Climb;Rubble;43724 5 +3637 9503 0 3633 9503 0 Climb;Rubble;43726 5 +3613 9482 0 3613 9484 0 Quick-pass;Barrier;43700 5 +3614 9482 0 3614 9484 0 Quick-pass;Barrier;43700 5 +3615 9482 0 3615 9484 0 Quick-pass;Barrier;43700 5 +3616 9482 0 3616 9484 0 Quick-pass;Barrier;43700 5 +3617 9482 0 3617 9484 0 Quick-pass;Barrier;43700 5 +3613 9484 0 3613 9482 0 Quick-pass;Barrier;43700 5 +3614 9484 0 3614 9482 0 Quick-pass;Barrier;43700 5 +3615 9484 0 3615 9482 0 Quick-pass;Barrier;43700 5 +3616 9484 0 3616 9482 0 Quick-pass;Barrier;43700 5 +3617 9484 0 3617 9482 0 Quick-pass;Barrier;43700 5 +2775 10003 0 2773 10003 0 Jump-over;Strange floor;16544 43 Agility 10 +2773 10003 0 2775 10003 0 Jump-over;Strange floor;16544 43 Agility 10 +2770 10002 0 2768 10002 0 Jump-over;Strange floor;16544 43 Agility 10 +2768 10002 0 2770 10002 0 Jump-over;Strange floor;16544 43 Agility 10 +3230 9609 0 3313 9613 0 Mines;Kazgar;7301 The Lost Tribe 8 Mines +3230 9609 0 3245 9648 0 Watermill;Kazgar;7301 Death to the Dorgeshuun 8 Watermill +3317 9612 0 3232 9610 0 Cellar;Mistag;7299 The Lost Tribe 8 Cellar +3317 9612 0 3245 9648 0 Watermill;Mistag;7299 Death to the Dorgeshuun 8 Watermill +3246 9646 0 3313 9613 0 Mines;Dartog;7301 Death to the Dorgeshuun 8 Mines +3246 9646 0 3232 9610 0 Cellar;Dartog;997 Death to the Dorgeshuun 8 Cellar +2709 3498 0 2716 9888 0 Climb-down;Staircase;3415 1 +2716 9888 0 2709 3497 0 Climb-up;Staircase;3416 1 +2370 3621 0 2371 3620 0 Climb-over;Stile;19222 5 +2372 3621 0 2371 3620 0 Climb-over;Stile;19222 5 +2371 3619 0 2371 3621 0 Climb-over;Stile;19222 5 +2370 3620 0 2371 3621 0 Climb-over;Stile;19222 5 +2372 3620 0 2371 3621 0 Climb-over;Stile;19222 5 +2547 3422 0 2630 5071 0 Climb-down;Ladder;6560 4657 28329 28327 Desert Treasure I +2546 3421 0 2630 5071 0 Climb-down;Ladder;6560 4657 28329 28327 Desert Treasure I +2548 3421 0 2630 5071 0 Climb-down;Ladder;6560 4657 28329 28327 Desert Treasure I +2547 3420 0 2630 5071 0 Climb-down;Ladder;6560 4657 28329 28327 Desert Treasure I +2629 5073 0 2547 3422 0 Climb-up;Ladder;6450 Desert Treasure I +2628 5072 0 2547 3422 0 Climb-up;Ladder;6450 Desert Treasure I +2630 5072 0 2547 3422 0 Climb-up;Ladder;6450 Desert Treasure I +2629 5071 0 2547 3422 0 Climb-up;Ladder;6450 Desert Treasure I +2701 3407 0 2701 3407 1 Climb-up;Ladder;16683 +2700 3408 0 2701 3407 1 Climb-up;Ladder;16683 +2702 3408 0 2701 3407 1 Climb-up;Ladder;16683 +2701 3407 1 2701 3407 0 Climb-down;Ladder;16679 +2700 3408 1 2701 3407 0 Climb-down;Ladder;16679 +2702 3408 1 2701 3407 0 Climb-down;Ladder;16679 +2704 3404 1 2704 3404 2 Climb-up;Ladder;16683 +2703 3403 1 2704 3404 2 Climb-up;Ladder;16683 +2705 3403 1 2704 3404 2 Climb-up;Ladder;16683 +2704 3402 1 2704 3404 2 Climb-up;Ladder;16683 +2704 3404 2 2704 3404 1 Climb-down;Ladder;16679 +2703 3403 2 2704 3404 1 Climb-down;Ladder;16679 +2705 3403 2 2704 3404 1 Climb-down;Ladder;16679 +2704 3402 2 2704 3404 1 Climb-down;Ladder;16679 +2700 3405 2 2700 3405 3 Climb-up;Ladder;16683 +2699 3406 2 2700 3405 3 Climb-up;Ladder;16683 +2699 3404 2 2700 3405 3 Climb-up;Ladder;16683 +2700 3405 3 2700 3405 2 Climb-down;Ladder;16679 +2699 3406 3 2700 3405 2 Climb-down;Ladder;16679 +2699 3404 3 2700 3405 2 Climb-down;Ladder;16679 +1435 3128 0 1439 9509 1 Pass-through;Entrance;51375 Perilous Moons +1436 3128 0 1439 9509 1 Pass-through;Entrance;51375 Perilous Moons +1439 9509 1 1435 3128 0 Pass-through;Entrance;51375 Perilous Moons +2457 3186 0 2355 9394 0 Climb-down;Stairs;25432 +2458 3185 0 2355 9394 0 Climb-down;Stairs;25432 +2355 9394 0 2458 3185 0 Climb-up;Stairs;25429 +2335 9350 0 2439 3164 0 Climb-up;Stairs;25429 +2439 3164 0 2335 9350 0 Climb-down;Stairs;25434 +2438 3165 0 2335 9350 0 Climb-down;Stairs;25434 +2438 3163 0 2335 9350 0 Climb-down;Stairs;25434 +2444 3162 0 2442 3159 1 Climb-up;Stairs;25431 +2442 3159 1 2444 3162 0 Climb-down;Stairs;25437 +2443 3160 1 2444 3162 0 Climb-down;Stairs;25437 +2443 3158 1 2444 3162 0 Climb-down;Stairs;25437 +2826 2998 0 2838 9387 0 Climb-down;Ladder;23586 3598=1 +2825 2999 0 2838 9387 0 Climb-down;Ladder;23586 3598=1 +2824 2998 0 2838 9387 0 Climb-down;Ladder;23586 3598=1 +2825 2997 0 2838 9387 0 Climb-down;Ladder;23586 3598=1 +2838 9387 0 2826 2998 0 Climb-up;Ladder;23584 3598=1 +2839 9388 0 2826 2998 0 Climb-up;Ladder;23584 3598=1 +2484 2889 0 1971 9035 1 Enter;Cave;31766 6076=1 +1969 8987 1 1967 8987 1 Pass;Magical Barrier;31617 Dragon Slayer II +1969 8986 1 1967 8986 1 Pass;Magical Barrier;31617 Dragon Slayer II +1967 8987 1 1969 8987 1 Pass;Magical Barrier;31617 Dragon Slayer II +1967 8986 1 1969 8986 1 Pass;Magical Barrier;31617 Dragon Slayer II +2457 2839 0 2458 2839 1 Climb-up;Stairs;31627 Dragon Slayer II +2455 2839 1 2457 2839 0 Climb-down;Stairs;32206 Dragon Slayer II +2456 2839 1 2457 2839 0 Climb-down;Stairs;32206 Dragon Slayer II +2458 2839 1 2457 2839 0 Climb-down;Stairs;32206 Dragon Slayer II +2459 2839 1 2457 2839 0 Climb-down;Stairs;32206 Dragon Slayer II +2449 2847 1 2452 2847 2 Climb-up;Stairs;31609 Dragon Slayer II +2452 2847 2 2449 2847 1 Climb-down;Stairs;31610 Dragon Slayer II +2809 3161 0 2808 3162 1 Climb-up;Ladder;16683 +2809 3161 1 2808 3162 0 Climb-down;Ladder;16670 +2238 3386 0 3262 6135 0 Enter;City Gate;36518 Song of the Elves 4 +2241 3386 0 3265 6135 0 Enter;City Gate;36519 Song of the Elves 4 +3262 6135 0 2238 3386 0 Exit;City Gate;36522 Song of the Elves 4 +3265 6135 0 2241 3386 0 Exit;City Gate;36523 Song of the Elves 4 +2238 3269 0 3262 6024 0 Enter;City Gate;36518 Song of the Elves 4 +2241 3269 0 3265 6024 0 Enter;City Gate;36519 Song of the Elves 4 +3262 6024 0 2238 3269 0 Exit;City Gate;36522 Song of the Elves 4 +3265 6024 0 2241 3269 0 Exit;City Gate;36523 Song of the Elves 4 +2181 3326 0 3208 6078 0 Enter;City Gate;36518 Song of the Elves 4 +2181 3329 0 3208 6081 0 Enter;City Gate;36519 Song of the Elves 4 +3208 6078 0 2181 3326 0 Exit;City Gate;36522 Song of the Elves 4 +3208 6081 0 2181 3329 0 Exit;City Gate;36523 Song of the Elves 4 +2298 3326 0 3319 6078 0 Enter;City Gate;36518 Song of the Elves 4 +2298 3329 0 3319 6081 0 Enter;City Gate;36519 Song of the Elves 4 +3319 6078 0 2298 3326 0 Exit;City Gate;36522 Song of the Elves 4 +3319 6081 0 2298 3329 0 Exit;City Gate;36523 Song of the Elves 4 +2763 9103 0 2763 2703 0 Climb-up;Bamboo Ladder;4781 +2763 2703 0 2763 9103 0 Climb-down;Bamboo Ladder;4780 +2591 2851 1 2589 2851 0 Cross;Gangplank;31756 3 +2589 2851 0 2591 2851 1 Cross;Gangplank;31756 3 +1811 3679 1 1808 3679 0 Cross;Gangplank;50064 3 +1808 3679 0 1811 3679 1 Cross;Gangplank;50063 3 +3060 3000 1 3063 3000 0 Cross;Gangplank;60523 3 +3063 3000 0 3060 3000 1 Cross;Gangplank;60522 3 +3308 3491 0 3308 3493 0 Climb-over;Broken fence;2618 6 +3308 3493 0 3308 3491 0 Climb-over;Broken fence;2618 6 +2893 3507 0 2893 9907 0 Climb-down;Ladder;17374 1 +2893 9907 0 2893 3507 0 Climb-up;Ladder;17387 1 From b42c1f8b4e5e36299e6791517c42c94e6815f070 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 23:05:22 +0100 Subject: [PATCH 19/48] Doc: mark transports import + collision map done in comparison Update UPSTREAM_COMPARISON.md re-baseline: 768/778 routes imported, collision map refreshed (2663->2724 regions), exclusions and the isMembers caveat recorded. Docs only. Co-Authored-By: Claude Opus 4.8 --- .../plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md index 91327e9909..3314d7a7b6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md @@ -43,7 +43,9 @@ Microbot loads 22 TSVs (see `Transport.java`). File-level diff vs `skretzo/maste - Upstream 5140 distinct O→D pairs vs Microbot 4915. **778 upstream-only**, 553 Microbot-only. - Of the 778: only **14 named** transports; **764 anonymous route objects** (372 Climb, 137 Ladder, 123 Stairs, 43 Staircase, gates/doors/caves…). - **Not drift:** 737 distinct origins in the 778, of which only 24 overlap a Microbot origin — **713 are genuinely new origin tiles**. Concentrated central 2500–2999 (399), Varlamore/Kebos 1500–1999 (133), Misthalin 3000–3499 (131). -- **Verdict:** real coverage gap (new route objects + new areas Microbot's baseline predates), but **bulk import is risky**: upstream's space-separated multi-word action column doesn't map trivially to Microbot's `;`-separated `Currency`/`isMembers` schema, and importing into areas the bundled `collision-map.zip` predates can mislead the walker. Recommended as a scoped, validated per-region sync — not a blind paste. The 14 named ones (Mount Quidamortem/Shayzien cart routes, Varrock↔Civitas illa Fortis, Watermill/Mines/Cellar network) are the low-risk starting subset. +- **Verdict:** real coverage gap (new route objects + new areas Microbot's baseline predates). +- **✅ DONE (2026-07-20):** imported **768** of the 778 (`transports.tsv` 4949→5717), scripted + validated. Conversion: action `space`→`;` form; inserted `Currency`/`isMembers` columns; upstream named item variations + `|` OR-sets → Microbot numeric id-sets (`AXE`/`MACHETE`/`PICKAXE`/`ROPE` via `ItemVariations`→`ItemID`; `COINS=N`→Currency); fixed upstream typo `Shadows`→`Shadow of the Storm` (else the `Quest` gate silently drops). **Excluded:** 15 id-less rows (bare `Climb-up Staircase`, name-only walls/gates) unmatchable in Microbot's id-based format, and **2 Garden of Tranquillity trellis rows (obj 2149)** Microbot intentionally omits — caught by `testVarrockSewerPathAvoidsDisabledPalaceTrellisShortcut`. Paired with the **updated collision map** (`collision-map.zip` 2663→2724 regions) so new-area routes have collision coverage. Validated: shortestpath suite green (73 tests, incl. real cross-region pathfinding). +- **Caveat:** imported members-area routes carry an empty `isMembers` (upstream lacked that column) — same as upstream's own behaviour; harmless since F2P can't reach those origins anyway. ### Recommended next Stage-4 target **#3 POH coverage** is the one concrete, real upstream gap: diff `skretzo/master:src/main/resources/transports/teleportation_portals_poh.tsv` against Microbot's programmatic POH set and backfill. It's data-level (low engine risk) and testable. *(Done 2026-07-20 — see the #3 row above.)* From 3149b6b80e1c84a1d3aaf8d74685bac934f1dd4d Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 23:29:12 +0100 Subject: [PATCH 20/48] Reconcile stale 07fca57 sections in UPSTREAM_COMPARISON The legacy 2026-04-06 tables were misleading (showed many features as missing that are now present). Verified each against the live tree: - "Critical Bug Fixes Missing Locally" #1-6: all fixed - banner added. - Transport System table: corrected Local column. Actually present now: hot air balloons, magic mushtrees, seasonal transports, teleportation boxes (POH mounted), POH portals, Pendant of Ates, Kharedst's Memoir/ Book of the Dead, Great Conch (CJQ). Genuinely still missing (6): Cowbell Amulet, Sailors' Amulet, Laguna Aurorae spirit tree, bank-visit teleport discovery, per-transport-type cost tuning, currency-threshold cost avoidance (currency requirement filtering IS present). - POH section: granular PohPanel sub-panels present - obsolete-toggle description annotated. Docs only. Co-Authored-By: Claude Opus 4.8 --- .../shortestpath/UPSTREAM_COMPARISON.md | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md index 3314d7a7b6..b3af3ef23d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md @@ -54,6 +54,8 @@ Microbot loads 22 TSVs (see `Transport.java`). File-level diff vs `skretzo/maste ## Critical Bug Fixes Missing Locally +> ⚠️ **HISTORICAL (2026-04-06). All six below are now FIXED** — see the "Re-baseline" section at the top and `WEBWALKER_IMPROVEMENT_PLAN.md`: #1 rehash `return`→`continue` (done), #2 wilderness boundaries (done, byte-identical to upstream `WildernessChecker`), #3 `growBucket` overflow (done), #4 `onGameStateChanged` refresh (done), #5 minimap null guard (done), #6 boat world-view `fromLocalInstance` (done). Kept for provenance only. + ### 1. `PrimitiveIntHashMap.rehash()` — Data Loss Bug **File:** `PrimitiveIntHashMap.java:210` @@ -130,25 +132,27 @@ Upstream has `fromLocalInstance(Client client, Player localPlayer)` which handle ### Transport System -| Feature | Upstream | Local | +> ⚠️ **This table was the 2026-04-06 (`07fca57`) snapshot and was badly stale. Re-verified against the live tree 2026-07-20 — most rows were already present.** Corrected `Local` column below. + +| Feature | Upstream | Local (verified 2026-07-20) | |---------|----------|-------| -| Hot Air Balloons | Yes | No | -| Magic Mushtrees | Yes | No | -| Seasonal Transports | Yes | No | -| Teleportation Boxes | Yes | No | -| POH Teleportation Portals | Yes | No | -| Cowbell Amulet | Yes | No | -| Pendant of Ates (Kastori, Nemus) | Yes | No | -| Sailors' Amulet | Yes | No | -| Separate Kharedst's Memoir / Book of the Dead | Yes | No | -| Great Conch fairy ring (CJQ) | Yes | No | -| Laguna Aurorae spirit tree | Yes | No | -| Bank-visit teleport discovery | Yes | No | -| Per-transport-type cost tuning (18 thresholds) | Yes | No | -| Currency threshold (avoid expensive transports) | Yes | No | -| Transport data as TSV with parser package | Yes | Inline string parsing | - -Upstream's transport data model uses a dedicated parser package (`FieldParser`, `TransportRecord`, `TsvParser`, `WorldPointParser`, etc.) with a clean `TransportBuilder` pattern. Local parses TSV fields with raw string splitting directly in the `Transport` constructor. +| Hot Air Balloons | Yes | ✅ Yes — `hot_air_balloons.tsv` | +| Magic Mushtrees | Yes | ✅ Yes — `magic_mushtrees.tsv` | +| Seasonal Transports | Yes | ✅ Yes — `seasonal_transports.tsv` | +| Teleportation Boxes | Yes | ✅ Yes — POH mounted items (`Mounted{Glory,Xerics,Digsite,Mythical}`) | +| POH Teleportation Portals | Yes | ✅ Yes — `PohPortal` (40 dests after 2026-07-20 backfill) | +| Pendant of Ates (Kastori, Nemus) | Yes | ✅ Yes — in `teleportation_items.tsv` | +| Separate Kharedst's Memoir / Book of the Dead | Yes | ✅ Yes — in `teleportation_items.tsv` | +| Great Conch fairy ring (CJQ) | Yes | ✅ Yes — in `fairy_rings.tsv` | +| **Cowbell Amulet** | Yes | ❌ **Missing** (0 hits) | +| **Sailors' Amulet** | Yes | ❌ **Missing** (0 hits) | +| **Laguna Aurorae spirit tree** | Yes | ❌ **Missing** (not in `spirit_trees.tsv`) | +| **Bank-visit teleport discovery** | Yes | ❌ **Missing** — no `onItemContainerChanged` bank-knowledge tracking | +| **Per-transport-type cost tuning** | Yes (`TransportTypeConfig`) | ❌ **Missing** | +| **Currency *threshold*** (avoid expensive when low on gold) | Yes | ❌ **Missing** — note: currency *requirement* filtering (can-I-afford) **is** present (`PathfinderConfig.java:879`) | +| Transport data as TSV with parser package | Yes | Architectural difference (Microbot parses inline in `Transport`) — not a feature gap | + +**Net still-missing (verified):** Cowbell Amulet, Sailors' Amulet, Laguna Aurorae spirit tree, bank-visit teleport discovery, per-transport-type cost tuning, currency-threshold cost avoidance. Everything else in the original table is already present. ### Player-Owned House (POH) @@ -163,7 +167,7 @@ Upstream has granular POH support: - POH exit info display ("Nexus: Varrock", "Fairy Ring CIR", "Jewelry Box: Duel Arena") - POH transport origin remapping to landing tile `(1923, 5709, 0)` -Local has a single `usePoh` toggle with a `PohPanel` and `createMergedList()` approach, no POH-specific overlay handling. +> ⚠️ **Stale (2026-04-06).** Re-verified 2026-07-20: Microbot's `PohPanel` now has granular sub-panels — `portalPanel` (`PohPortal`), `nexusPanel` (`NexusPortal`), `checkboxPanel` (fairy ring / spirit tree / obelisk toggles), and `jewelleryBoxPanel` — plus `Mounted{Glory,Xerics,Digsite,Mythical}`. Most of the "granular POH" list above is present; the single-`usePoh`-toggle description is obsolete. ### Pathfinding & Performance From 7e1239a11c7a71486851c1df8c93943492693110 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 23:33:57 +0100 Subject: [PATCH 21/48] Backfill Cowbell Amulet, Sailors' Amulet, Laguna Aurorae from upstream Add the three transport data items that were genuinely missing vs upstream (7e7e5bf94b), sourced from upstream's data files: - Cowbell amulet (item 33104) -> teleportation_items.tsv (1 dest) - Sailors' amulet charged (item 32399) -> teleportation_items.tsv (3 dests: The Pandemonium, Port Roberts, Deepfin Point) - Laguna Aurorae spirit-tree destination -> spirit_trees.tsv, gated on the Pandemonium quest (resolves against RuneLite Quest.PANDEMONIUM) Converted to Microbot's column schemas (item '=qty' stripped; members Varlamore items marked isMembers=Y, Consumable=T, wildy 20 as upstream). Validated: shortestpath suite green (73 tests, 0 fail; both files parse). Co-Authored-By: Claude Opus 4.8 --- .../client/plugins/microbot/shortestpath/spirit_trees.tsv | 2 ++ .../plugins/microbot/shortestpath/teleportation_items.tsv | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/spirit_trees.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/spirit_trees.tsv index 2c1d87e20d..bbbb01759c 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/spirit_trees.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/spirit_trees.tsv @@ -171,3 +171,5 @@ # Tree Gnome Village;The Grand Tree 2 C: Your house # Poison Waste 2339 3109 0 Tree Gnome Village;The Grand Tree;The Path of Glouphrie 2 D: Poison Waste +# Laguna Aurorae (Varlamore) - backfilled 2026-07-20 from upstream + 1202 2785 0 Pandemonium 3 E: Laguna Aurorae diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_items.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_items.tsv index 9c355898ba..a1327e27c9 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_items.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/teleportation_items.tsv @@ -375,4 +375,10 @@ 1311 9497 0 31099;31101;31102;31103;31104;31105 The Final Dawn Y T 29 4 Mokhaiotl waystone: Channel #Varlemore Waystone -1439 9564 0 29090;29092;29093;29094;29095;29096;29097 Perilous Moons Y Y 29 4 Calcified moth: Crush \ No newline at end of file +1439 9564 0 29090;29092;29093;29094;29095;29096;29097 Perilous Moons Y Y 29 4 Calcified moth: Crush +# Cowbell amulet (Varlamore) - backfilled 2026-07-20 from upstream Skretzo/shortest-path +3259 3277 0 33104 Y T 20 4 Cowbell amulet +# Sailors amulet (charged, Varlamore) - backfilled 2026-07-20 from upstream +3058 2975 0 32399 Y T 20 4 Sailors' amulet: The Pandemonium +1889 3292 0 32399 Y T 20 4 Sailors' amulet: Port Roberts +1943 2757 0 32399 Y T 20 4 Sailors' amulet: Deepfin Point From d10aee8cd96682639c78719420e69a9f8896b34d Mon Sep 17 00:00:00 2001 From: infuse21 Date: Mon, 20 Jul 2026 23:34:17 +0100 Subject: [PATCH 22/48] Doc: mark Cowbell/Sailors'/Laguna Aurorae done in comparison table Docs only. Co-Authored-By: Claude Opus 4.8 --- .../plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md index b3af3ef23d..408d7d03d6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/UPSTREAM_COMPARISON.md @@ -144,15 +144,15 @@ Upstream has `fromLocalInstance(Client client, Player localPlayer)` which handle | Pendant of Ates (Kastori, Nemus) | Yes | ✅ Yes — in `teleportation_items.tsv` | | Separate Kharedst's Memoir / Book of the Dead | Yes | ✅ Yes — in `teleportation_items.tsv` | | Great Conch fairy ring (CJQ) | Yes | ✅ Yes — in `fairy_rings.tsv` | -| **Cowbell Amulet** | Yes | ❌ **Missing** (0 hits) | -| **Sailors' Amulet** | Yes | ❌ **Missing** (0 hits) | -| **Laguna Aurorae spirit tree** | Yes | ❌ **Missing** (not in `spirit_trees.tsv`) | +| Cowbell Amulet | Yes | ✅ Yes — `teleportation_items.tsv` (item 33104), backfilled 2026-07-20 | +| Sailors' Amulet | Yes | ✅ Yes — `teleportation_items.tsv` (item 32399, 3 dests), backfilled 2026-07-20 | +| Laguna Aurorae spirit tree | Yes | ✅ Yes — `spirit_trees.tsv` (Pandemonium-gated dest), backfilled 2026-07-20 | | **Bank-visit teleport discovery** | Yes | ❌ **Missing** — no `onItemContainerChanged` bank-knowledge tracking | | **Per-transport-type cost tuning** | Yes (`TransportTypeConfig`) | ❌ **Missing** | | **Currency *threshold*** (avoid expensive when low on gold) | Yes | ❌ **Missing** — note: currency *requirement* filtering (can-I-afford) **is** present (`PathfinderConfig.java:879`) | | Transport data as TSV with parser package | Yes | Architectural difference (Microbot parses inline in `Transport`) — not a feature gap | -**Net still-missing (verified):** Cowbell Amulet, Sailors' Amulet, Laguna Aurorae spirit tree, bank-visit teleport discovery, per-transport-type cost tuning, currency-threshold cost avoidance. Everything else in the original table is already present. +**Net still-missing (verified 2026-07-20):** bank-visit teleport discovery, per-transport-type cost tuning, currency-threshold cost avoidance. (Cowbell/Sailors'/Laguna Aurorae backfilled; everything else in the original table was already present.) The three remaining are feature work (config + event handling), not data adds. ### Player-Owned House (POH) From e31944c0db3120df916a2425b0b59eae958c0857 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 12:25:27 +0100 Subject: [PATCH 23/48] Fix walker route-click selection: line-of-sight clamping and anchor recovery The walker deviated wide, entered buildings, and backtracked near Varrock West Bank. Root cause was in click-target selection, not pathfinding or collision data (verified offline: the raw route is optimal and reaches the goal from every approach). Two defects compounded: 1. The anchored forward scan shared by every click predicate could start past the player's vicinity, breaking immediately on the Euclidean bound and returning null for ALL predicates (observed live as sel=none). Selection then fell through to a smoothed-waypoint Euclidean clamp, producing off-route clicks such as (3176,3428). 2. That clamp picks a target with no straight walkable line to it. A minimap click is resolved by the game's own pathing, so a no-line-of-sight target lets the game improvise a detour: cutting corners through open doors, looping around buildings, and trapping itself so it has to backtrack out. Changes: - Select route clicks by line-of-sight first: the furthest forward raw-path point the player can reach in a straight walkable line (CollisionMap.canStep line trace, mirroring PathSmoother.lineOfSight). Tiers: los > reach > walkable > offscene. - Retry selection anchored at the player's own closest raw tile when the anchored scan yields nothing, so a stale smoothed->raw anchor can no longer drop clicks onto the off-route clamp. - Guarantee selection never returns null while a raw route exists, so a click can no longer leave the planned route. - Consolidate every click path (main loop, idle-nudge/stall recovery, interim continuation, outside-clip route fallback) onto the same selector. Previously each had its own policy, so behaviour depended on which path happened to fire. - Gate the directional scaled-radius fallback and the wall-distance nudge on reachability; the nudge now prefers the neighbour reachable from and nearest to the player instead of an arbitrary tile from an unordered set. - Add bidirectional rejoin for off-path recovery, preferring forward points so normal progress is never sacrificed. - Tag click_candidate_found with the selection tier (sel=/fb=) for diagnosis. Also fixes two startup/pacing issues found while investigating: - The 2000ms wait for a non-null pathfinder expired mid PathfinderConfig.refresh() (measured 2.4-2.7s on a cache miss), sending the walker into recalculatePath() which cancelled the in-flight work and started a second refresh. Raised to 6s so recalculation stays a genuine failure path, and log slow refreshes at INFO. - Shortened the active-route idle-nudge window to a few ticks. Route continuation is one-shot, so when it is missed that window is the visible dead stop per hop. Measured on the reported route: the 41-tile leg now resolves to four straight clicks (3182,3432 -> 3172,3425 -> 3172,3399 -> 3173,3399), confirmed live as sel=los@player. Tests: Rs2WalkerUnitTest 96, LineOfSightClickRegressionTest 3 (new), ClientThreadGuardrailTest 1. Guardrail baseline regenerated (mostly lambda-index churn plus the changed getPointWithWallDistance signature). Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 70 +++ .../pathfinder/PathfinderConfig.java | 13 + .../microbot/util/walker/Rs2Walker.java | 405 +++++++++++++++--- .../microbot/util/walker/WebWalkLog.java | 8 + .../LineOfSightClickRegressionTest.java | 149 +++++++ .../util/walker/Rs2WalkerUnitTest.java | 98 +++++ .../client-thread-guardrail-baseline.txt | 62 +-- 7 files changed, 715 insertions(+), 90 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 235384a743..5e39e41c9e 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -400,3 +400,73 @@ When a gate can be crossed by either a quest unlock or a currency payment, do no **Where this applies:** `transports.tsv`, `blocked_edges.tsv`, `restrictions.tsv`, `PathfinderConfig`, and `Rs2Walker.handleTransports`. **Defensive check:** Add resource tests that assert both paid and quest-free transports load, the gate tiles are not quest-only restricted, and the gate edge is blocked without a usable transport. + +## 19. Gate minimap click targets on reachability, not walkability — and allow bidirectional rejoin + +A tile being *walkable* (`Rs2Tile.isWalkable`, i.e. not `BLOCK_MOVEMENT_FULL`) is not the same as being *reachable from the player*. Next to a wall the two diverge hard: a tile flush on the far side of a castle wall is walkable and Euclidean-close, but only reachable via a long detour. Any minimap click-target selection that filters on walkability/clip-visibility alone will happily pick the wrong side of the wall and stall. Select the next raw-route click point from the player's collision-**reachable** set (`Rs2Tile.getReachableTilesFromTile`, which honors edge flags) with a generous BFS depth (~2× the click radius) so real around-a-corner detours still qualify while the wrong side is excluded. Only fall back to a walkable/off-scene point when the target is genuinely off the loaded scene (collision can't be verified there). Likewise, `getPointWithWallDistance` computes tiles reachable *from the target*, so its nudge can land across a wall or inside a building — verify its result with `Rs2Tile.isTileReachable` before clicking it. + +Forward-only anchoring (introduced to stop the walker snapping back to already-travelled branches) overcorrects when the player is pushed *off* the path: if nothing ahead is reachable, forward-only recovery returns nothing and the walker stalls against the wall. Recovery must therefore be **bidirectional**: scan a bounded index window on both sides of the anchor and rejoin via the nearest reachable raw point, preferring the furthest-forward one so normal progress is never sacrificed. This is a rejoin path for the off-path case only; steady-state progress stays forward-only. + +**Why this matters:** Walking north up the west side of Varrock castle, the path runs flush against the wall. The selector picked a forward raw/nudged point on the far (east) side of the wall and clicked it, so the player pressed into the wall and stalled. The same mechanism clicks into houses (interior tile is walkable but unreachable) and produces "random far clicks" right after a teleport, when a stale smoothed waypoint or blind scaled-radius directional guess targets an unreachable tile. + +**Pattern to follow:** + +```java +// Primary: furthest-forward COLLISION-REACHABLE raw point (wrong side of wall excluded). +WorldPoint rawRouteTarget = selectRouteClickTarget(rawPath, playerLoc, reach, rawAnchorIndex); +if (rawRouteTarget != null) { + clickTarget = rawRouteTarget; +} else { + clickTarget = getPointWithWallDistance(targetWp); + if (!Rs2Tile.isTileReachable(clickTarget)) { + WorldPoint rejoin = findReachableRejoinRawPathPoint(rawPath, playerLoc, reach, rawAnchorIndex); + if (rejoin != null) clickTarget = rejoin; // step back onto the line if needed + } +} +// Directional scaled-radius guesses must also be reachability-gated: +if (!reachable.contains(scaledFallback)) continue; +``` + +**Where this applies:** `Rs2Walker.selectRouteClickTarget`, `Rs2Walker.findReachableRejoinRawPathPoint`, `Rs2Walker.walkMiniMapToward`, `getPointWithWallDistance` consumers, and any minimap click-target selector used while a raw route exists. + +**Defensive check:** Unit-test the rejoin core with an injected reachability predicate: (a) player pushed one tile off-path with nothing ahead reachable must return a point *behind* the anchor; (b) with points ahead reachable it must return the furthest-forward one inside the reach circle; (c) nothing reachable must return null so stall/recalc can take over. Live-repro: walk north flush against Varrock castle's west wall — the walker should round the corner instead of pressing into the wall, and a fresh teleport should not produce a click far off the route. + +## 20. Clamp minimap click targets to line-of-sight, not a Euclidean radius + +A minimap click is resolved by the **game's own pathing** to the clicked tile — not by our route. So the click target must be a tile the player can reach in a **straight walkable line** (line-of-sight). If the target is off a straight line (around a building corner, past an open door), the game improvises its own route to it and deviates: cutting the corner through the door, looping wide, or trapping itself so it has to backtrack out. Do **not** pick the click by clamping a far smoothed waypoint to a Euclidean radius (`clampToEuclideanRadius`) — that routinely overshoots the first line-of-sight waypoint into no-LOS territory. Select the furthest forward raw-path point with straight LOS from the player (`hasWalkableLineOfSight`, mirroring `PathSmoother.lineOfSight` over the pathfinder `CollisionMap`). LOS is naturally long on open roads (clicks stay long) and short only at corners/tight rooms (where short clicks are correct), so it does not over-click. + +**Why this matters:** Walking from `(3183,3435)` to `(3173,3399)` past the **Varrock West Bank**, the player has straight LOS only ~3 tiles (to the corner `(3182,3432)`), but the click layer clamped a far waypoint to a 10-tile radius and clicked `(3176,3428)` — off the raw path and with no LOS. The game then looped the player wide around the bank and it had to backtrack. The raw path itself is optimal (down the west side); the defect is purely the no-LOS click. LOS clamping turns the whole 41-tile leg into 4 clean straight clicks (`3182,3432 → 3172,3425 → 3172,3399 → 3173,3399`). + +**Pattern to follow:** + +```java +WorldPoint losTarget = findFurthestRawPathPointMatching(rawPath, playerLoc, reach, rawAnchor, + candidate -> hasWalkableLineOfSight(playerLoc, candidate)); +if (losTarget != null) return losTarget; // straight line — game can't deviate +// fall back to reachable / off-scene / rejoin only when no LOS point exists +``` + +**Where this applies:** `Rs2Walker.selectRouteClickTarget`, `Rs2Walker.hasWalkableLineOfSight`, and any minimap click-target selection that clamps to a Euclidean radius while a raw route exists. + +**Defensive check:** `LineOfSightClickRegressionTest` — from `(3183,3435)` to `(3173,3399)`, the old `(3176,3428)` click must have no LOS from the start, the LOS-clamped click must be on the raw route, and the greedy LOS chain must reach the goal in ≤ 8 straight clicks. + +## 21. Route continuation is one-shot — keep the idle-nudge window short + +`tryIssueRouteContinuationClick` only runs on the single pass where `clearInterimTargetIfReachedOrExpired` returns `true` (the transition where the interim checkpoint is cleared). If any guard blocks it on that exact pass — `isInteracting`, `isAnimating`, door/transport settling, or its own unresolved-door / upcoming-transport checks — the opportunity is lost and **nothing retries it**. The route then only resumes via the active-route idle nudge, so that stationary window is the visible dead stop between hops. Keep it to a few ticks; do not treat it as a rare recovery path, because in practice it is what continues normal routes. + +**Why this matters:** A 41-tile walk from `(3183,3435)` to `(3173,3399)` clicked correctly, walked to its checkpoint, then sat fully stopped for the whole `2500ms` idle window before issuing the next click — roughly a third of the total walk time spent standing still, once per hop. + +**Pattern to follow:** + +```java +// One-shot: only fires on the pass that clears the interim checkpoint. +if (clearedInterimTarget && !Rs2Player.isInteracting() && !Rs2Player.isAnimating() + && tryIssueRouteContinuationClick(rawPath, path, target)) { ... } + +// So the nudge window is the real continuation path — keep it a few ticks, not seconds. +private static final long ACTIVE_ROUTE_IDLE_NUDGE_MS = 1_200L; +``` + +**Where this applies:** `Rs2Walker.tryIssueRouteContinuationClick`, `clearInterimTargetIfReachedOrExpired`, `shouldIssueActiveRouteIdleNudge`, and `ACTIVE_ROUTE_IDLE_NUDGE_MS` / `ACTIVE_ROUTE_IDLE_NUDGE_COOLDOWN_MS`. + +**Defensive check:** On a multi-hop route, the gap between `first_minimap_click` / route-fallback clicks and the next `active route idle nudge` should be roughly the walk time plus a few ticks — not walk time plus a full idle window. A repeating ~2.5s stationary gap per hop means continuation is being missed and only the nudge is driving the route. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java index 92855da1cd..8b99111191 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java @@ -102,6 +102,12 @@ public class PathfinderConfig { @Getter private volatile long calculationCutoffMillis; + + /** + * A {@link #refresh(WorldPoint)} slower than this is a user-visible cold start: the walker sits + * on a null pathfinder for its whole duration before the first click can be issued. + */ + private static final long SLOW_REFRESH_LOG_THRESHOLD_MS = 500L; @Getter private volatile boolean avoidWilderness; @Getter @@ -240,6 +246,13 @@ public void refresh(WorldPoint target) { WebWalkLog.cfg("refresh transports={}ms restr={}ms total={}ms", t1 - t0, t2 - t1, t2 - t0); + // The walker blocks on a null pathfinder for the whole of refresh(), so a slow refresh + // is a visible cold start at route start. Surface it at INFO (not DEBUG) when it is + // actually slow, so it shows up in normal logs without enabling debug logging. + if (t2 - t0 >= SLOW_REFRESH_LOG_THRESHOLD_MS) { + WebWalkLog.cfgSlow("slow refresh transports={}ms restr={}ms total={}ms", + t1 - t0, t2 - t1, t2 - t0); + } //END microbot variables } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index e1f52d2234..91e079c020 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -19,6 +19,7 @@ import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.globval.enums.InterfaceTab; import net.runelite.client.plugins.microbot.shortestpath.*; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; @@ -172,10 +173,33 @@ public static WorldPoint getCurrentTarget() { private static final int STALL_RECOVERY_MINIMAP_REACH_EUCLIDEAN = 10; private static final int NORMAL_MINIMAP_REACH_EUCLIDEAN = 11; private static final int UNREACHABLE_RECOVERY_FORWARD_SCAN_TILES = 24; - private static final long ACTIVE_ROUTE_IDLE_NUDGE_MS = 2_500L; + /** + * Stationary window before an active route issues a recovery nudge. + *

    + * {@link #tryIssueRouteContinuationClick} is one-shot: it only runs on the pass where the interim + * checkpoint is cleared. If a guard (interacting/animating/door or transport settling, or a + * pending route object) blocks it on that single pass, nothing retries and the route only resumes + * via this nudge — so this window is the visible dead stop between hops. Keep it to a few ticks + * (movement.md #13) rather than the old 2500ms. The nudge already requires the player to be + * genuinely still (not moving/animating/interacting) on the same tile, and + * {@link #ACTIVE_ROUTE_IDLE_NUDGE_COOLDOWN_MS} still prevents click spam. + */ + private static final long ACTIVE_ROUTE_IDLE_NUDGE_MS = 1_200L; private static final long ACTIVE_ROUTE_IDLE_NUDGE_COOLDOWN_MS = 2_000L; private static final long POST_TRANSPORT_PATH_TMARK_WINDOW_MS = 15_000L; private static final int ROUTE_PROGRESS_FORWARD_SEARCH_TILES = 40; + + /** + * How long to wait for {@code Rs2PathApi.getPathfinder()} to become non-null at route start. + *

    + * The pathfinder is only published after {@code PathfinderConfig.refresh()} completes + * (see {@code Rs2WalkerLifecycleRuntime.restartPathfinding}), and a cache-missing refresh has been + * measured at 2.4-2.7s. The previous 2000ms cap expired mid-refresh, sending the walker into + * {@code recalculatePath()} — which cancels the in-flight work and starts a second refresh, making + * the cold start worse instead of recovering from it. Wait comfortably past the observed refresh + * cost so recalculation stays a genuine failure path. + */ + private static final int PATHFINDER_NULL_WAIT_MS = 6_000; private static final long POST_TRANSPORT_OFFPATH_WAIT_BUDGET_MS = 2_500L; private static final int POST_TRANSPORT_OFFPATH_WAIT_SLICE_MS = 450; private static final int TRANSPORT_DEST_MATCH_CHEBYSHEV = 1; @@ -1230,8 +1254,8 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part Pathfinder pathfinder = Rs2PathApi.getPathfinder(); if (pathfinder == null) { markStartupPhase("pf_wait_enter", target, "reason=pathfinder_null"); - walkerDiag("pathfinder null; waiting up to 2000ms"); - pathfinder = sleepUntilNotNull(Rs2PathApi::getPathfinder, 2_000); + walkerDiag("pathfinder null; waiting up to %dms", PATHFINDER_NULL_WAIT_MS); + pathfinder = sleepUntilNotNull(Rs2PathApi::getPathfinder, PATHFINDER_NULL_WAIT_MS); if (walkCancelledDiag(target, "processWalk:after-wait-pathfinder", processWalkTail)) { return WalkerState.EXIT; } @@ -2161,25 +2185,35 @@ && walkFastCanvas(recoverTarget)) { WorldPoint posBefore = playerLoc; int rawAnchorIndex = rawIndexForSmoothedIndex(i, smoothedToRaw, rawPath); - WorldPoint rawRouteTarget = inInstance ? null : findFurthestRawPathPointMatching( - rawPath, - playerLoc, - MINIMAP_REACH_EUCLIDEAN - 1, - rawAnchorIndex, - Rs2Walker::isKnownWalkableOrUnloaded); + // Prefer a collision-REACHABLE raw-route point. "Walkable" (tile not fully + // blocked) is not the same as "reachable from the player": a tile flush on the + // far side of a castle wall is walkable yet only reachable via a long detour, so + // a Euclidean-close click there sends the player into the wall. Reachability + // gating excludes the wrong side outright. See movement.md #19. + WorldPoint rawRouteTarget = inInstance ? null + : selectRouteClickTarget(rawPath, playerLoc, MINIMAP_REACH_EUCLIDEAN - 1, rawAnchorIndex); WorldPoint clickTarget; + String fallbackTag = "-"; if (rawRouteTarget != null && !rawRouteTarget.equals(playerLoc)) { targetWp = rawRouteTarget; clickTarget = rawRouteTarget; } else { - clickTarget = inInstance ? targetWp : getPointWithWallDistance(targetWp); - } - if (!inInstance && rawRouteTarget == null) { - WorldPoint rawReachableTarget = findFurthestReachableRawPathPoint(rawPath, playerLoc, - MINIMAP_REACH_EUCLIDEAN - 1, rawAnchorIndex); - if (!Rs2Tile.isTileReachable(clickTarget) && rawReachableTarget != null) { - targetWp = rawReachableTarget; - clickTarget = rawReachableTarget; + clickTarget = inInstance ? targetWp : getPointWithWallDistance(targetWp, playerLoc); + // getPointWithWallDistance computes tiles reachable FROM THE TARGET, so its + // wall nudge can land on the far side of a wall or inside a building; a stale + // smoothed waypoint right after a teleport can also be unreachable. If the + // resulting click is not reachable, rejoin the route via the nearest reachable + // raw point on EITHER side of the anchor rather than clicking a wrong-side / + // random-far tile. + fallbackTag = "wallnudge"; + if (!inInstance && !Rs2Tile.isTileReachable(clickTarget)) { + WorldPoint rejoin = findReachableRejoinRawPathPoint(rawPath, playerLoc, + MINIMAP_REACH_EUCLIDEAN - 1, rawAnchorIndex); + if (rejoin != null && !rejoin.equals(playerLoc)) { + targetWp = rejoin; + clickTarget = rejoin; + fallbackTag = "rejoin"; + } } } if (!inInstance && handlePendingDoorBeforeRouteClick(rawPath, path, i, targetIdx, @@ -2199,7 +2233,9 @@ && walkFastCanvas(recoverTarget)) { posBefore, "to=" + compactWorldPoint(clickTarget)); } - markStartupPhase("click_candidate_found", target, "to=" + compactWorldPoint(clickTarget)); + markStartupPhase("click_candidate_found", target, + "to=" + compactWorldPoint(clickTarget) + + " sel=" + lastRouteClickTier + " fb=" + fallbackTag); WorldPoint clickedTarget = clickMiniMapOrFallback(rawPath, clickTarget, playerLoc, MINIMAP_REACH_EUCLIDEAN - 1, rawPath == null || rawPath.isEmpty(), rawAnchorIndex); boolean clicked = clickedTarget != null; @@ -2539,20 +2575,38 @@ public static void walkNextToInstance(GameObject target) { } public static WorldPoint getPointWithWallDistance(WorldPoint target) { + return getPointWithWallDistance(target, null); + } + + /** + * Nudges a click target off a wall edge onto an open neighbour. The candidate set + * ({@link Rs2Tile#getReachableTilesFromTile} radius 1) is an unordered {@link Set}, so returning + * the first clean tile picks an arbitrary side — that is how the walker ends up clicking the far + * side of a wall or into a building. When {@code playerLoc} is supplied, choose the clean + * neighbour reachable from the player and nearest to the player, keeping the nudge on the + * player's side (the road). See movement.md #19. + */ + public static WorldPoint getPointWithWallDistance(WorldPoint target, WorldPoint playerLoc) { var tiles = Rs2Tile.getReachableTilesFromTile(target, 1); - var localPoint = LocalPoint.fromWorld(Microbot.getClient().getTopLevelWorldView(), target); - if (Microbot.getClient().getTopLevelWorldView().getCollisionMaps() != null && localPoint != null) { - int[][] flags = Microbot.getClient().getTopLevelWorldView().getCollisionMaps()[Microbot.getClient().getTopLevelWorldView().getPlane()].getFlags(); + var wv = Microbot.getClient().getTopLevelWorldView(); + var localPoint = LocalPoint.fromWorld(wv, target); + if (wv.getCollisionMaps() != null && localPoint != null) { + int[][] flags = wv.getCollisionMaps()[wv.getPlane()].getFlags(); - if (hasMinimapRelevantMovementFlag(localPoint, flags)) { - for (var tile : tiles.keySet()) { - var localTilePoint = LocalPoint.fromWorld(Microbot.getClient().getTopLevelWorldView(), tile); - if (localTilePoint == null) - continue; + Set reachableFromPlayer = playerLoc == null + ? Collections.emptySet() + : Rs2Tile.getReachableTilesFromTile(playerLoc, + Math.max(2, NORMAL_MINIMAP_REACH_EUCLIDEAN)).keySet(); - if (!hasMinimapRelevantMovementFlag(localTilePoint, flags)) - return tile; + if (hasMinimapRelevantMovementFlag(localPoint, flags)) { + WorldPoint best = bestWallDistanceNeighbor(tiles.keySet(), playerLoc, reachableFromPlayer, + tile -> { + var lp = LocalPoint.fromWorld(wv, tile); + return lp != null && !hasMinimapRelevantMovementFlag(lp, flags); + }); + if (best != null) { + return best; } } @@ -2564,16 +2618,16 @@ public static WorldPoint getPointWithWallDistance(WorldPoint target) { || movementFlags.contains(MovementFlag.BLOCK_MOVEMENT_WEST) || movementFlags.contains(MovementFlag.BLOCK_MOVEMENT_NORTH) || movementFlags.contains(MovementFlag.BLOCK_MOVEMENT_SOUTH)) { - for (var tile : tiles.keySet()) { - var localTilePoint = LocalPoint.fromWorld(Microbot.getClient().getTopLevelWorldView(), tile); - if (localTilePoint == null) - continue; - - int tileData = flags[localTilePoint.getSceneX()][localTilePoint.getSceneY()]; - Set tileFlags = MovementFlag.getSetFlags(tileData); - - if (tileFlags.isEmpty()) - return tile; + WorldPoint best = bestWallDistanceNeighbor(tiles.keySet(), playerLoc, reachableFromPlayer, + tile -> { + var lp = LocalPoint.fromWorld(wv, tile); + if (lp == null) { + return false; + } + return MovementFlag.getSetFlags(flags[lp.getSceneX()][lp.getSceneY()]).isEmpty(); + }); + if (best != null) { + return best; } } } @@ -2581,6 +2635,39 @@ public static WorldPoint getPointWithWallDistance(WorldPoint target) { return target; } + /** + * Picks the wall-distance neighbour that best keeps the click on the player's side of the wall: + * prefer tiles reachable from the player, then the one nearest the player. Falls back to the + * first clean tile when the player position is unknown, preserving the original behaviour. + */ + private static WorldPoint bestWallDistanceNeighbor(Collection candidates, + WorldPoint playerLoc, + Set reachableFromPlayer, + Predicate isClean) { + WorldPoint best = null; + boolean bestReachable = false; + int bestDist = Integer.MAX_VALUE; + for (WorldPoint tile : candidates) { + if (tile == null || !isClean.test(tile)) { + continue; + } + if (playerLoc == null) { + return tile; // no player context: preserve original "first clean tile" behaviour + } + boolean reachable = reachableFromPlayer.contains(tile); + int dist = tile.distanceTo2D(playerLoc); + boolean better = best == null + || (reachable && !bestReachable) + || (reachable == bestReachable && dist < bestDist); + if (better) { + best = tile; + bestReachable = reachable; + bestDist = dist; + } + } + return best; + } + private static boolean isKnownWalkableOrUnloaded(WorldPoint target) { if (target == null) { return false; @@ -2801,6 +2888,12 @@ static boolean walkMiniMapToward(WorldPoint target, WorldPoint playerLoc, int ma } int cappedRadius = Math.max(2, maxEuclidean); + // The scaled-radius points below are geometric guesses toward an off-clip target. Right + // after a teleport (or when the target sits behind a wall) that guess can be an unreachable + // tile far off the route, producing the "random click far from the path" behaviour. Only + // click a guess that is actually reachable from the player. + Set reachable = Rs2Tile + .getReachableTilesFromTile(playerLoc, Math.max(2, cappedRadius)).keySet(); int[] radii = new int[] {cappedRadius, 10, 8, 6, 4}; for (int radius : radii) { if (radius >= distance) { @@ -2815,6 +2908,9 @@ static boolean walkMiniMapToward(WorldPoint target, WorldPoint playerLoc, int ma if (fallback.equals(playerLoc)) { continue; } + if (!reachable.contains(fallback)) { + continue; + } if (Rs2Walker.walkMiniMap(fallback)) { log.info("[Walker] Minimap click target {} was outside clip; used fallback {}", target, fallback); return true; @@ -2844,23 +2940,6 @@ && euclideanSq(tile, target) < currentDistance) .orElse(false); } - static WorldPoint findFurthestReachableRawPathPoint(List rawPath, - WorldPoint playerLoc, - int maxEuclidean) { - return findFurthestReachableRawPathPoint(rawPath, playerLoc, maxEuclidean, -1); - } - - static WorldPoint findFurthestReachableRawPathPoint(List rawPath, - WorldPoint playerLoc, - int maxEuclidean, - int rawAnchorIndex) { - Set reachable = playerLoc == null - ? Collections.emptySet() - : Rs2Tile.getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean)).keySet(); - return findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, - reachable::contains); - } - static WorldPoint findFurthestRawPathPointMatching(List rawPath, WorldPoint playerLoc, int maxEuclidean, @@ -2900,6 +2979,200 @@ static WorldPoint findFurthestRawPathPointMatching(List rawPath, return best; } + /** + * Selects the next minimap click target from the raw route, gated on collision reachability. + *

    + * Preference order: + *

      + *
    1. Furthest-forward raw point that is collision-reachable from the player. A point on the + * far side of a wall is Euclidean-close but not reachable within the sampled area, so it is + * excluded — this is what stops the walker clicking through castle walls / into buildings.
    2. + *
    3. Furthest-forward raw point that is off the loaded scene. Collision cannot be verified for + * unloaded tiles, but a minimap click toward a distant route point is still correct, so long + * outdoor routes keep flowing.
    4. + *
    + * Returns {@code null} when neither exists; the caller then falls back to wall-distance nudging + * plus {@link #findReachableRejoinRawPathPoint} rejoin handling. + */ + private static WorldPoint selectRouteClickTarget(List rawPath, WorldPoint playerLoc, + int maxEuclidean, int rawAnchorIndex) { + if (rawPath == null || rawPath.isEmpty() || playerLoc == null) { + lastRouteClickTier = "norawpath"; + return null; + } + WorldPoint selected = selectRouteClickTargetAnchored(rawPath, playerLoc, maxEuclidean, rawAnchorIndex); + if (selected == null && rawAnchorIndex >= 0) { + // The smoothed->raw anchor can point past the player's vicinity (stale mapping, sparse + // smoothing, or a replanned route). The anchored forward scan then breaks immediately on + // the Euclidean bound and yields nothing for EVERY predicate — which is exactly the + // sel=none case that dropped route clicks onto the off-route wall-nudge clamp. Retry + // anchored at the player's own closest raw tile before giving up. + selected = selectRouteClickTargetAnchored(rawPath, playerLoc, maxEuclidean, -1); + if (selected != null) { + lastRouteClickTier = lastRouteClickTier + "@player"; + } + } + return selected; + } + + private static WorldPoint selectRouteClickTargetAnchored(List rawPath, WorldPoint playerLoc, + int maxEuclidean, int rawAnchorIndex) { + // 1. Prefer the furthest forward raw point the player can reach in a STRAIGHT walkable line + // (line-of-sight). A minimap click is resolved by the GAME's own pathing; if the target + // is not on a straight walkable line, the game improvises its own route to it — cutting + // corners, deviating wide, or trapping itself against a building (e.g. clicking a tile + // ~10 tiles out past the Varrock West Bank corner, which it reaches by looping). Clicking + // only LOS targets keeps the game walking exactly our route. See movement.md #19. + WorldPoint losTarget = null; + try { + losTarget = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, + rawAnchorIndex, candidate -> hasWalkableLineOfSight(playerLoc, candidate)); + } catch (Exception ex) { + log.debug("[Walker] LOS click selection failed, falling back: {}", ex.getMessage()); + } + if (losTarget != null && !losTarget.equals(playerLoc)) { + lastRouteClickTier = "los"; + return losTarget; + } + // 2. No LOS point (tight spot / just off-path): fall back to the furthest forward + // collision-REACHABLE raw point. Depth is generous (2x the click radius) so legitimate + // around-a-corner detours to a Euclidean-close point are still admitted, while the wrong + // side of a wall is not. + Set reachable = Rs2Tile + .getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean * 2)).keySet(); + WorldPoint forwardReachable = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, + rawAnchorIndex, reachable::contains); + if (forwardReachable != null) { + lastRouteClickTier = "reach"; + return forwardReachable; + } + // 3. Last resort WHILE A RAW ROUTE EXISTS: furthest forward walkable/unloaded raw point. + // This tier can essentially always answer, which is the point — it guarantees selection + // never falls through to the caller's smoothed-waypoint Euclidean clamp, which is what + // produced the off-route click (3176,3428) that the game then detoured to. Worst case we + // click a slightly-too-far tile that is still ON the planned route. + WorldPoint walkable = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, + rawAnchorIndex, Rs2Walker::isKnownWalkableOrUnloaded); + if (walkable != null && !walkable.equals(playerLoc)) { + lastRouteClickTier = "walkable"; + return walkable; + } + // 4. Long route leaving the loaded area: furthest forward off-scene raw point. + WorldPoint offScene = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, + candidate -> isOffSceneOrUnloaded(candidate) && isMiniMapClickable(candidate, 5)); + lastRouteClickTier = offScene != null ? "offscene" : "none"; + return offScene; + } + + /** + * Which tier of {@link #selectRouteClickTarget} produced the most recent click target + * ({@code los} / {@code reach} / {@code offscene} / {@code none}, or {@code wallnudge} / + * {@code rejoin} when selection fell through). Surfaced in the {@code click_candidate_found} + * tmark so a log alone shows which selection path a click came from. + */ + private static volatile String lastRouteClickTier = "none"; + + private static boolean isOffSceneOrUnloaded(WorldPoint point) { + if (point == null) { + return false; + } + return LocalPoint.fromWorld(Microbot.getClient().getTopLevelWorldView(), point) == null; + } + + /** + * True if the player can walk from {@code from} to {@code to} in a straight (Bresenham-style) + * line without a collision-blocked step, per the pathfinder collision map that produced the raw + * path. A minimap click is resolved by the game's own pathing, so handing it a target that is + * NOT on a straight walkable line lets it improvise a detour (corner-cut through an open door, + * loop around a building). Restricting click targets to LOS keeps the game on our route. + * Mirrors {@code PathSmoother.lineOfSight} (collision only; transport-edge blocks are rare on a + * short click line and are handled by the route-object layer). + */ + static boolean hasWalkableLineOfSight(WorldPoint from, WorldPoint to) { + if (from == null || to == null || from.getPlane() != to.getPlane()) { + return false; + } + PathfinderConfig cfg = Rs2PathApi.getPathfinderConfig(); + if (cfg == null) { + return false; + } + CollisionMap map = cfg.getMap(); + if (map == null) { + return false; + } + int x = from.getX(); + int y = from.getY(); + final int z = from.getPlane(); + final int tx = to.getX(); + final int ty = to.getY(); + int guard = 0; + while ((x != tx || y != ty) && guard++ < 128) { + int dx = Integer.signum(tx - x); + int dy = Integer.signum(ty - y); + if (!map.canStep(x, y, z, dx, dy)) { + return false; + } + x += dx; + y += dy; + } + return x == tx && y == ty; + } + + /** + * Finds a reachable raw-path point to rejoin the route after the player has been pushed off it + * (stuck against a wall, knocked back, or landed off-path after a teleport). Unlike the primary + * forward-only selection, this scans a bounded index window on BOTH sides of the anchor so the + * walker can step slightly backward onto the path line when nothing ahead is reachable. Forward + * points are still preferred (highest index first), so normal progress is never sacrificed and + * the walker cannot snap all the way back to an already-travelled branch. + */ + private static WorldPoint findReachableRejoinRawPathPoint(List rawPath, WorldPoint playerLoc, + int maxEuclidean, int rawAnchorIndex) { + if (playerLoc == null) { + return null; + } + Set reachable = Rs2Tile + .getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean * 2)).keySet(); + return findReachableRejoinRawPathPoint(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, + reachable::contains); + } + + /** + * Testable core of {@link #findReachableRejoinRawPathPoint(List, WorldPoint, int, int)} with an + * injectable reachability predicate (so it can be exercised without a live client). + */ + static WorldPoint findReachableRejoinRawPathPoint(List rawPath, WorldPoint playerLoc, + int maxEuclidean, int rawAnchorIndex, + Predicate isReachable) { + if (rawPath == null || rawPath.isEmpty() || playerLoc == null || isReachable == null) { + return null; + } + int anchor = rawPathForwardAnchorIndex(rawPath, playerLoc, rawAnchorIndex); + if (anchor < 0) { + return null; + } + int window = maxEuclidean + 2; + int lo = Math.max(0, anchor - window); + int hi = Math.min(rawPath.size() - 1, anchor + window); + int maxSq = maxEuclidean * maxEuclidean; + // Highest index first => prefer the furthest-forward reachable point; only fall back to + // points behind the anchor when nothing ahead in the window is reachable. + for (int idx = hi; idx >= lo; idx--) { + WorldPoint candidate = rawPath.get(idx); + if (candidate == null || candidate.getPlane() != playerLoc.getPlane() + || candidate.equals(playerLoc)) { + continue; + } + if (euclideanSq(candidate, playerLoc) > maxSq) { + continue; + } + if (isReachable.test(candidate)) { + return candidate; + } + } + return null; + } + static WorldPoint findFurthestVisibleKnownRawPathPoint(List rawPath, WorldPoint playerLoc, int maxEuclidean) { @@ -2914,6 +3187,17 @@ static WorldPoint findFurthestVisibleKnownRawPathPoint(List rawPath, return null; } + // Prefer a straight-walkable (line-of-sight) route point here too, so the outside-clip + // route fallback follows the same policy as primary selection instead of handing the game a + // target it can only reach by detouring. + WorldPoint losFallback = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, + rawAnchorIndex, candidate -> !candidate.equals(playerLoc) + && hasWalkableLineOfSight(playerLoc, candidate) + && isMiniMapClickable(candidate, 5)); + if (losFallback != null) { + return losFallback; + } + return findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, candidate -> !candidate.equals(playerLoc) && isKnownWalkableOrUnloaded(candidate) @@ -3033,12 +3317,11 @@ private static boolean tryIssueRouteMovementClick(List rawPath, int[] routeSmoothedToRaw = mapSmoothedToRaw(path, rawPath); int rawAnchorIndex = rawIndexForSmoothedIndex(targetIdx, routeSmoothedToRaw, rawPath); - WorldPoint clickTarget = findFurthestRawPathPointMatching( - rawPath, - playerLoc, - maxEuclidean, - rawAnchorIndex, - Rs2Walker::isKnownWalkableOrUnloaded); + // Use the SAME line-of-sight-first selector as the main route loop. Recovery/idle-nudge and + // interim continuation clicks previously had their own walkable-only selection, so which + // policy applied depended on which path happened to fire (timing-dependent, e.g. a slow + // pathfinder makes the idle nudge issue the first click instead of the main loop). + WorldPoint clickTarget = selectRouteClickTarget(rawPath, playerLoc, maxEuclidean, rawAnchorIndex); if (clickTarget == null) { int clickableIdx = findFurthestForwardClickableIndex(path, startIdx, playerLoc, wp -> { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java index 63d7d7c4d1..86072d1956 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/WebWalkLog.java @@ -101,6 +101,14 @@ public static void cfg(String fmt, Object... args) { LOG.debug("[WebWalk] cfg | " + fmt, args); } + /** + * Config work slow enough to be a user-visible stall (e.g. a pathfinder-config refresh that the + * walker blocks on at route start). INFO so it appears without enabling debug logging. + */ + public static void cfgSlow(String fmt, Object... args) { + LOG.info("[WebWalk] cfg | " + fmt, args); + } + public static void leagues(String fmt, Object... args) { LOG.debug("[WebWalk] leagues | " + fmt, args); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java new file mode 100644 index 0000000000..b6c04e37e1 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java @@ -0,0 +1,149 @@ +package net.runelite.client.plugins.microbot.shortestpath; + +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Regression for the "walker deviates wide / traps itself near Varrock West Bank" bug. + * + *

    Root cause: the click layer overshot the first line-of-sight waypoint by clamping the click to + * a Euclidean radius (~10 tiles), landing on a tile with no straight walkable line-of-sight from the + * player. A minimap click is resolved by the game's own pathing, so a no-LOS target let the game + * improvise a detour around the bank. The fix restricts click targets to raw-path points the player + * has straight walkable line-of-sight to (see {@code Rs2Walker.hasWalkableLineOfSight} / + * {@code selectRouteClickTarget}). + * + *

    This test pins the collision-map behaviour the fix relies on, using the same + * {@code CollisionMap.canStep} line-walk the runtime helper uses. + */ +public class LineOfSightClickRegressionTest { + + private static SplitFlagMap collisionMap; + + private static final WorldPoint START = new WorldPoint(3183, 3435, 0); + private static final WorldPoint GOAL = new WorldPoint(3173, 3399, 0); + // The tile the old click layer selected: ~10 tiles out, off the raw path, NO LOS from start. + private static final WorldPoint OLD_DEVIATING_CLICK = new WorldPoint(3176, 3428, 0); + + @BeforeClass + public static void load() { + collisionMap = SplitFlagMap.fromResources(); + } + + /** Straight walkable line check — mirrors Rs2Walker.hasWalkableLineOfSight / PathSmoother.lineOfSight. */ + private static boolean los(CollisionMap map, WorldPoint from, WorldPoint to) { + if (from.getPlane() != to.getPlane()) { + return false; + } + int x = from.getX(), y = from.getY(), z = from.getPlane(), tx = to.getX(), ty = to.getY(); + int guard = 0; + while ((x != tx || y != ty) && guard++ < 128) { + int dx = Integer.signum(tx - x); + int dy = Integer.signum(ty - y); + if (!map.canStep(x, y, z, dx, dy)) { + return false; + } + x += dx; + y += dy; + } + return x == tx && y == ty; + } + + private static List rawPath(WorldPoint start, WorldPoint goal) { + HashMap> transports = Transport.loadAllFromResources(); + PathfinderConfig config = new PathfinderConfig(collisionMap, transports, + Collections.emptyList(), null, null); + try { + java.lang.reflect.Field f = PathfinderConfig.class.getDeclaredField("calculationCutoffMillis"); + f.setAccessible(true); + f.setLong(config, 10000); + for (Map.Entry> e : transports.entrySet()) { + if (e.getKey() == null) continue; + config.getTransports().put(e.getKey(), e.getValue()); + config.getTransportsPacked().put(WorldPointUtil.packWorldPoint(e.getKey()), e.getValue()); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + Pathfinder pf = new Pathfinder(config, start, goal); + pf.run(); + return pf.getPath(); + } + + @Test + public void oldDeviatingClickHasNoLineOfSightFromStart() { + CollisionMap map = new CollisionMap(collisionMap); + assertFalse("The old ~10-tile click (3176,3428) must NOT have straight LOS from the start — " + + "that is exactly why the game improvised a detour around the bank", + los(map, START, OLD_DEVIATING_CLICK)); + } + + @Test + public void losClampSelectsAnOnRouteTileNotTheDeviatingClick() { + CollisionMap map = new CollisionMap(collisionMap); + List raw = rawPath(START, GOAL); + assertFalse("raw path should not be empty", raw.isEmpty()); + + // Furthest forward raw point with straight LOS from the start = the LOS-clamped first click. + WorldPoint losClick = null; + for (WorldPoint p : raw) { + if (los(map, START, p)) { + losClick = p; + } + } + assertTrue("There must be at least one raw point with LOS from the start", losClick != null); + assertTrue("The LOS-clamped click must be on the raw route", raw.contains(losClick)); + assertFalse("The LOS-clamped click must not be the deviating off-route tile", + losClick.equals(OLD_DEVIATING_CLICK)); + } + + @Test + public void greedyLosChainReachesGoalInFewStraightClicks() { + CollisionMap map = new CollisionMap(collisionMap); + List raw = rawPath(START, GOAL); + + // Greedy LOS-clamp: from current tile, jump to the furthest raw tile with straight LOS, repeat. + List clicks = new ArrayList<>(); + int cur = 0; + int guard = 0; + while (cur < raw.size() - 1 && guard++ < 60) { + int next = cur; + for (int i = cur + 1; i < raw.size(); i++) { + if (los(map, raw.get(cur), raw.get(i))) { + next = i; + } + } + if (next == cur) { + next = cur + 1; // no LOS even to the neighbour: step one tile (shouldn't happen here) + } + // Every issued click must be a straight walkable line from where the click is issued. + assertTrue("click " + clicks.size() + " must have LOS from the previous stop", + los(map, raw.get(cur), raw.get(next))); + clicks.add(raw.get(next)); + cur = next; + } + + assertEquals("Greedy LOS chain must end exactly on the goal", + GOAL, clicks.get(clicks.size() - 1)); + // The 41-tile route collapses to a handful of straight clicks (measured: 4). Guard against a + // regression that shatters it into many tiny clicks (which would look botlike / be slow). + assertTrue("LOS clamp must not over-click a mostly-straight 41-tile route, got " + clicks.size(), + clicks.size() <= 8); + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index b117cae7f6..53be200210 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -439,6 +439,104 @@ public void findFurthest_nullPredicate_treatsAsNoTransport() { assertEquals("null predicate must not NPE and must allow full scan", 2, idx); } + /** + * The anchored forward scan is shared by every route-click predicate (line-of-sight, reachable, + * walkable, off-scene). If the smoothed->raw anchor points past the player's vicinity, the scan + * breaks immediately on the Euclidean bound and returns null for ALL of them — observed live as + * {@code sel=none}, which dropped route clicks onto the off-route wall-nudge clamp. Selection + * must therefore retry anchored at the player's own closest raw tile. + */ + @Test + public void rawPathScan_staleAnchorPastPlayerYieldsNothingForEveryPredicate() { + WorldPoint player = new WorldPoint(3183, 3435, 0); + List raw = new java.util.ArrayList<>(); + for (int i = 0; i < 40; i++) { + raw.add(new WorldPoint(3183, 3435 - i, 0)); // 40-tile route running south + } + + assertNotNull("anchored at the player, the scan must find a forward route point", + Rs2Walker.findFurthestRawPathPointMatching(raw, player, 10, 0, wp -> true)); + + assertNull("a stale anchor near the goal must yield nothing even for an always-true predicate", + Rs2Walker.findFurthestRawPathPointMatching(raw, player, 10, 38, wp -> true)); + } + + /** + * Off-path recovery must be able to step BACKWARD onto the route. When the player is pushed off + * the path (e.g. stuck flush against a castle wall) and nothing ahead is reachable, the rejoin + * helper picks the nearest reachable raw point even if it sits behind the anchor. Forward-only + * selection would return null here and the walker would stall. + */ + @Test + public void findReachableRejoin_stepsBackwardWhenNothingAheadReachable() { + WorldPoint player = new WorldPoint(3203, 3201, 0); // one tile off the line, beside the wall + List path = Arrays.asList( + new WorldPoint(3200, 3200, 0), // 0 + new WorldPoint(3201, 3200, 0), // 1 + new WorldPoint(3202, 3200, 0), // 2 + new WorldPoint(3203, 3200, 0), // 3 (anchor) + new WorldPoint(3204, 3200, 0), // 4 + new WorldPoint(3205, 3200, 0), // 5 + new WorldPoint(3206, 3200, 0)); // 6 + // Only the tiles behind the anchor are reachable; the wall blocks everything ahead. + Set reachable = new HashSet<>(Arrays.asList( + new WorldPoint(3200, 3200, 0), + new WorldPoint(3201, 3200, 0), + new WorldPoint(3202, 3200, 0))); + + WorldPoint rejoin = Rs2Walker.findReachableRejoinRawPathPoint(path, player, 10, 3, reachable::contains); + + assertEquals("must rejoin the route by stepping back onto the nearest reachable raw tile", + new WorldPoint(3202, 3200, 0), rejoin); + } + + /** + * When points ahead of the anchor are reachable, rejoin must prefer the furthest-forward one so + * recovery never sacrifices progress or snaps back to an already-travelled branch. + */ + @Test + public void findReachableRejoin_prefersFurthestForwardReachable() { + WorldPoint player = new WorldPoint(3203, 3201, 0); + List path = Arrays.asList( + new WorldPoint(3200, 3200, 0), // 0 + new WorldPoint(3201, 3200, 0), // 1 + new WorldPoint(3202, 3200, 0), // 2 + new WorldPoint(3203, 3200, 0), // 3 (anchor) + new WorldPoint(3204, 3200, 0), // 4 + new WorldPoint(3205, 3200, 0), // 5 + new WorldPoint(3206, 3200, 0)); // 6 + Set reachable = new HashSet<>(path); // everything reachable + + // maxEuclidean = 3 -> (3206,3200) is Euclidean sqrt(10) > 3 and must be rejected; + // (3205,3200) is sqrt(5) <= 3 and is the furthest-forward admissible point. + WorldPoint rejoin = Rs2Walker.findReachableRejoinRawPathPoint(path, player, 3, 3, reachable::contains); + + assertEquals("rejoin must prefer the furthest-forward reachable raw tile inside the reach circle", + new WorldPoint(3205, 3200, 0), rejoin); + } + + @Test + public void findReachableRejoin_returnsNullWhenNothingReachable() { + WorldPoint player = new WorldPoint(3203, 3201, 0); + List path = Arrays.asList( + new WorldPoint(3202, 3200, 0), + new WorldPoint(3203, 3200, 0), + new WorldPoint(3204, 3200, 0)); + + assertNull("no reachable raw point => null (caller lets stall/recalc take over)", + Rs2Walker.findReachableRejoinRawPathPoint(path, player, 10, 1, wp -> false)); + } + + @Test + public void findReachableRejoin_nullInputsAreSafe() { + WorldPoint player = new WorldPoint(3203, 3201, 0); + List path = Collections.singletonList(new WorldPoint(3203, 3200, 0)); + assertNull(Rs2Walker.findReachableRejoinRawPathPoint(null, player, 10, 0, wp -> true)); + assertNull(Rs2Walker.findReachableRejoinRawPathPoint(path, null, 10, 0, wp -> true)); + assertNull(Rs2Walker.findReachableRejoinRawPathPoint(path, player, 10, 0, null)); + assertNull(Rs2Walker.findReachableRejoinRawPathPoint(Collections.emptyList(), player, 10, 0, wp -> true)); + } + @Test public void stabilizeRouteProgressIndex_doesNotJumpBackToEarlierNearbyBranch() { WorldPoint target = new WorldPoint(3200, 3201, 0); diff --git a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt index dab8036f3b..b014ddde1d 100644 --- a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt +++ b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt @@ -732,11 +732,11 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#findCharterDestinatio net.runelite.client.plugins.microbot.util.walker.Rs2Walker#findCharterDestinationTextWidget(Widget, String): Widget -> net.runelite.api.widgets.Widget#isHidden(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#findClickableCharterWidget(Widget, Widget): Widget -> net.runelite.api.widgets.Widget#getParent(): Widget net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getFirstWidgetAction(Widget): String -> net.runelite.api.widgets.Widget#getActions(): String[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.CollisionData#getFlags(): int[][] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.WorldView#getCollisionMaps(): CollisionData[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.WorldView#getPlane(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint): WorldPoint -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint, WorldPoint): WorldPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint, WorldPoint): WorldPoint -> net.runelite.api.CollisionData#getFlags(): int[][] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint, WorldPoint): WorldPoint -> net.runelite.api.WorldView#getCollisionMaps(): CollisionData[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint, WorldPoint): WorldPoint -> net.runelite.api.WorldView#getPlane(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getPointWithWallDistance(WorldPoint, WorldPoint): WorldPoint -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getTile(WorldPoint): Tile -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getTile(WorldPoint): Tile -> net.runelite.api.Scene#getTiles(): Tile[][][] net.runelite.client.plugins.microbot.util.walker.Rs2Walker#getTile(WorldPoint): Tile -> net.runelite.api.WorldView#getScene(): Scene @@ -794,36 +794,40 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isDoorLikeSceneObject net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isDoorOnSegment(TileObject, WorldPoint, WorldPoint): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isKnownWalkableOrUnloaded(WorldPoint): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isKnownWalkableOrUnloaded(WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isOffSceneOrUnloaded(WorldPoint): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isOffSceneOrUnloaded(WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.ObjectComposition#getName(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.ObjectComposition#getName(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$41(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$42(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$39(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$40(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$187(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$156(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$158(String): boolean -> net.runelite.api.widgets.Widget#getText(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$134(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$140(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$140(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$141(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$141(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$22(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$113(int, boolean, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$113(int, boolean, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$115(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$116(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$117(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$118(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$121(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$148(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$149(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$46(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$47(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$getPointWithWallDistance$13(WorldView, int[][], WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$getPointWithWallDistance$14(WorldView, int[][], WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$44(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$45(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$192(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$161(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$163(String): boolean -> net.runelite.api.widgets.Widget#getText(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$139(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$145(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$145(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$146(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$146(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$27(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$118(int, boolean, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$118(int, boolean, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$121(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$122(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$123(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$125(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$126(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$153(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$154(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$2(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$3(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$69(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$74(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.WorldView#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint From 9c378d307416e09ad2f7af8137c107f2abac3bb6 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 12:45:34 +0100 Subject: [PATCH 24/48] Attribute per-handler cost in the raw-path scene scan A post-transport raw scene scan was measured at 5640ms returning handled=false (Lumbridge -> Corsair Cove, after the Port Sarim ship). The skip guard behaved correctly there: a charter ship was a genuine upcoming nearby transport, so "no_nearby_planned_transport" did not apply and the scan legitimately ran. The cost is inside the scan itself. Each raw index probes two offsets, and each probe does several client-thread scene lookups (wall exact + adjacency fallback, game object exact + adjacency fallback, plus composition resolution), so a ~14 index window can issue hundreds of client-thread round trips and return nothing. Time each handler separately (doors, door-candidate, rockfall, transports) and log the breakdown at INFO when a scan exceeds 500ms, so the dominant call is identified from one run instead of by guessing. Instrumentation only; no behaviour change. Co-Authored-By: Claude Opus 4.8 --- .../microbot/util/walker/Rs2Walker.java | 102 ++++++++++++------ 1 file changed, 70 insertions(+), 32 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 91e079c020..2c24a14abf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -4459,47 +4459,85 @@ private static boolean handleNearbyRawPathSceneObjects(List rawPath, int start = Math.max(0, rawStart - 2); int endExclusive = Math.min(rawPath.size() - 1, rawStart + 12); - for (int i = start; i < endExclusive; i++) { - WorldPoint currentWorldPoint = rawPath.get(i); - if (currentWorldPoint == null - || currentWorldPoint.getPlane() != playerLoc.getPlane() - || currentWorldPoint.distanceTo2D(playerLoc) > handlerRange) { - continue; - } - - if (allowTransportHandlers && hasExplicitTransportStep(rawPath, i)) { - WorldPoint before = Rs2Player.getWorldLocation(); - WorldPoint expectedDestination = i + 1 < rawPath.size() ? rawPath.get(i + 1) : null; - if (handleTransports(rawPath, i)) { - if (!didCurrentTileTransportProgress(before, expectedDestination, target)) { - WebWalkLog.spInfo("raw_path_transport_no_progress", - "at=%s expected=%s target=%s", - before, expectedDestination, target); - } else { - log.info("[Walker] Raw path transport handler resolved obstacle near {}", playerLoc); - return true; + // Per-stage timing: this scan has been measured at 5.6s returning handled=false after a + // transport (each probe does several client-thread scene lookups). Attribute the cost so a + // single log line shows which handler dominates instead of needing another repro round. + final long scanStartMs = System.currentTimeMillis(); + int scannedIdx = 0; + long transportMs = 0L; + long doorMs = 0L; + long doorCandidateMs = 0L; + long rockfallMs = 0L; + boolean resolved = false; + try { + for (int i = start; i < endExclusive; i++) { + WorldPoint currentWorldPoint = rawPath.get(i); + if (currentWorldPoint == null + || currentWorldPoint.getPlane() != playerLoc.getPlane() + || currentWorldPoint.distanceTo2D(playerLoc) > handlerRange) { + continue; + } + scannedIdx++; + + if (allowTransportHandlers && hasExplicitTransportStep(rawPath, i)) { + WorldPoint before = Rs2Player.getWorldLocation(); + WorldPoint expectedDestination = i + 1 < rawPath.size() ? rawPath.get(i + 1) : null; + long t = System.currentTimeMillis(); + boolean handledTransport = handleTransports(rawPath, i); + transportMs += System.currentTimeMillis() - t; + if (handledTransport) { + if (!didCurrentTileTransportProgress(before, expectedDestination, target)) { + WebWalkLog.spInfo("raw_path_transport_no_progress", + "at=%s expected=%s target=%s", + before, expectedDestination, target); + } else { + log.info("[Walker] Raw path transport handler resolved obstacle near {}", playerLoc); + resolved = true; + return true; + } } } - } - if (handleDoors(rawPath, i, true)) { - log.info("[Walker] Raw path door handler resolved obstacle near {}", playerLoc); - return true; - } - if (hasDoorCandidateOnRawSegment(rawPath, i)) { - setRawScanDoorFocus(i); - return false; + long t0 = System.currentTimeMillis(); + boolean handledDoor = handleDoors(rawPath, i, true); + doorMs += System.currentTimeMillis() - t0; + if (handledDoor) { + log.info("[Walker] Raw path door handler resolved obstacle near {}", playerLoc); + resolved = true; + return true; + } + long t1 = System.currentTimeMillis(); + boolean doorCandidate = hasDoorCandidateOnRawSegment(rawPath, i); + doorCandidateMs += System.currentTimeMillis() - t1; + if (doorCandidate) { + setRawScanDoorFocus(i); + return false; + } + + long t2 = System.currentTimeMillis(); + boolean handledRockfall = handleRockfall(rawPath, i); + rockfallMs += System.currentTimeMillis() - t2; + if (handledRockfall) { + log.info("[Walker] Raw path rockfall handler resolved obstacle near {}", playerLoc); + resolved = true; + return true; + } } - if (handleRockfall(rawPath, i)) { - log.info("[Walker] Raw path rockfall handler resolved obstacle near {}", playerLoc); - return true; + return false; + } finally { + long totalMs = System.currentTimeMillis() - scanStartMs; + if (totalMs >= SLOW_RAW_SCENE_SCAN_LOG_MS) { + log.info("[Walker] slow raw scene scan: total={}ms idx={} doors={}ms doorCand={}ms rockfall={}ms transports={}ms resolved={} allowTransports={}", + totalMs, scannedIdx, doorMs, doorCandidateMs, rockfallMs, transportMs, + resolved, allowTransportHandlers); } } - - return false; } + /** A raw-scene scan slower than this is user-visible dead time between route clicks. */ + private static final long SLOW_RAW_SCENE_SCAN_LOG_MS = 500L; + private static boolean hasDoorCandidateOnRawSegment(List rawPath, int index) { if (rawPath == null || index < 0 || index >= rawPath.size() - 1) { return false; From 651dc5e8ca0bb74f1e8ce7c926e074b792f6e66b Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 14:09:15 +0100 Subject: [PATCH 25/48] Snapshot the scene once per raw-path scan instead of querying per probe Instrumentation attributed the stall precisely: slow raw scene scan: total=5539ms idx=12 doors=4564ms doorCand=974ms rockfall=1ms transports=0ms resolved=false handleDoors was 82% of a 5.5s scan that resolved nothing - about 380ms per raw index. Each probe issued up to four bounded scene queries (wall exact, wall adjacency, game object exact, game object adjacency), and a scan walks ~12 raw indices x 2 offsets x several probes, so a single no-op scan could cost hundreds of client-thread round trips. Take one bounded snapshot of wall and game objects up front (radius handlerRange+2, a superset of what the per-probe queries could reach, since probes stay within handlerRange+1 of the player and only match objects within one tile of a probe) and resolve probes against it in memory. Two queries per scan instead of hundreds. Exact-tile match is still preferred over the one-tile adjacency fallback, so door selection is unchanged. The snapshot is scoped to one scan and cleared in a finally block; outside a scan it is null and every other handleDoors caller keeps the original query-per-probe path. Guardrail baseline regenerated: the resolver entries are the same off-thread getWorldLocation reads relocated out of handleDoors (24 added, 23 removed), plus lambda-index renumbering in untouched methods. Not yet validated live - the next walk past a transport should show the scan drop well under the 500ms slow-scan threshold. Co-Authored-By: Claude Opus 4.8 --- .../microbot/util/walker/Rs2Walker.java | 95 +++++++++++++++++-- .../client-thread-guardrail-baseline.txt | 47 ++++----- 2 files changed, 109 insertions(+), 33 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 2c24a14abf..e756eff6d2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -4469,6 +4469,12 @@ private static boolean handleNearbyRawPathSceneObjects(List rawPath, long doorCandidateMs = 0L; long rockfallMs = 0L; boolean resolved = false; + // Probes stay within handlerRange+1 of the player (the loop skips indices beyond + // handlerRange) and only match objects within one tile of a probe, so a handlerRange+2 + // radius is a superset of what the per-probe queries could have found. + final int snapshotRadius = handlerRange + 2; + rawScanWallSnapshot = Rs2GameObject.getWallObjects(o -> true, playerLoc, snapshotRadius); + rawScanGameObjectSnapshot = Rs2GameObject.getGameObjects(o -> true, playerLoc, snapshotRadius); try { for (int i = start; i < endExclusive; i++) { WorldPoint currentWorldPoint = rawPath.get(i); @@ -4526,6 +4532,8 @@ private static boolean handleNearbyRawPathSceneObjects(List rawPath, return false; } finally { + rawScanWallSnapshot = null; + rawScanGameObjectSnapshot = null; long totalMs = System.currentTimeMillis() - scanStartMs; if (totalMs >= SLOW_RAW_SCENE_SCAN_LOG_MS) { log.info("[Walker] slow raw scene scan: total={}ms idx={} doors={}ms doorCand={}ms rockfall={}ms transports={}ms resolved={} allowTransports={}", @@ -4538,6 +4546,81 @@ private static boolean handleNearbyRawPathSceneObjects(List rawPath, /** A raw-scene scan slower than this is user-visible dead time between route clicks. */ private static final long SLOW_RAW_SCENE_SCAN_LOG_MS = 500L; + /** + * Scene snapshot scoped to one {@link #handleNearbyRawPathSceneObjects} pass. + *

    + * Door probing previously issued up to four bounded scene queries per probe, and a scan + * walks ~12 raw indices x 2 offsets x several probes — hundreds of client-thread round trips. + * Measured live at 4564ms of a 5539ms scan that resolved nothing. Taking one bounded snapshot up + * front and matching probes against it in memory collapses that to two queries per scan. + *

    + * Null outside a raw scan, so every other {@code handleDoors} caller keeps the original + * query-per-probe behaviour. + */ + private static volatile List rawScanWallSnapshot = null; + private static volatile List rawScanGameObjectSnapshot = null; + + /** + * Exact-tile match first, then a one-tile adjacency fallback — the same preference order the + * previous pair of bounded queries produced. + */ + private static WallObject resolveProbeWallObject(WorldPoint probe) { + List snapshot = rawScanWallSnapshot; + if (snapshot != null) { + WallObject adjacent = null; + for (WallObject candidate : snapshot) { + if (candidate == null) { + continue; + } + WorldPoint loc = candidate.getWorldLocation(); + if (loc == null) { + continue; + } + if (loc.equals(probe)) { + return candidate; + } + if (adjacent == null && loc.distanceTo2D(probe) <= 1) { + adjacent = candidate; + } + } + return adjacent; + } + WallObject wall = Rs2GameObject.getWallObject(o -> o.getWorldLocation().equals(probe), probe, 3); + if (wall == null) { + wall = Rs2GameObject.getWallObject(o -> o.getWorldLocation().distanceTo2D(probe) <= 1, probe, 3); + } + return wall; + } + + /** @see #resolveProbeWallObject(WorldPoint) */ + private static TileObject resolveProbeGameObject(WorldPoint probe) { + List snapshot = rawScanGameObjectSnapshot; + if (snapshot != null) { + GameObject adjacent = null; + for (GameObject candidate : snapshot) { + if (candidate == null) { + continue; + } + WorldPoint loc = candidate.getWorldLocation(); + if (loc == null) { + continue; + } + if (loc.equals(probe)) { + return candidate; + } + if (adjacent == null && loc.distanceTo2D(probe) <= 1) { + adjacent = candidate; + } + } + return adjacent; + } + TileObject object = Rs2GameObject.getGameObject(o -> o.getWorldLocation().equals(probe), probe, 3); + if (object == null) { + object = Rs2GameObject.getGameObject(o -> o.getWorldLocation().distanceTo2D(probe) <= 1, probe, 3); + } + return object; + } + private static boolean hasDoorCandidateOnRawSegment(List rawPath, int index) { if (rawPath == null || index < 0 || index >= rawPath.size() - 1) { return false; @@ -5139,17 +5222,9 @@ private static boolean handleDoors(List path, int index, boolean all // WallObjects can report their world location as an adjacent tile depending on // orientation / scene representation. Use exact match first, then allow a small // adjacency fallback so door handling triggers reliably. - WallObject wall = Rs2GameObject.getWallObject(o -> o.getWorldLocation().equals(probe), probe, 3); - if (wall == null) { - wall = Rs2GameObject.getWallObject(o -> o.getWorldLocation().distanceTo2D(probe) <= 1, probe, 3); - } + WallObject wall = resolveProbeWallObject(probe); - TileObject object = (wall != null) - ? wall - : Rs2GameObject.getGameObject(o -> o.getWorldLocation().equals(probe), probe, 3); - if (object == null) { - object = Rs2GameObject.getGameObject(o -> o.getWorldLocation().distanceTo2D(probe) <= 1, probe, 3); - } + TileObject object = (wall != null) ? wall : resolveProbeGameObject(probe); if (object == null) continue; if (!isDoorInteractionWithinRange(object, probe, fromWp, toWp, playerLoc, HANDLER_RANGE)) { Telemetry.recordDoorReject("door-out-of-range"); diff --git a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt index b014ddde1d..1881543c3b 100644 --- a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt +++ b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt @@ -800,34 +800,34 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObj net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.ObjectComposition#getName(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$46(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$47(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$48(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$49(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$getPointWithWallDistance$13(WorldView, int[][], WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$getPointWithWallDistance$14(WorldView, int[][], WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$44(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleDoors$45(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$192(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$161(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$163(String): boolean -> net.runelite.api.widgets.Widget#getText(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$139(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$145(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$145(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$146(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$146(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$194(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$163(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$165(String): boolean -> net.runelite.api.widgets.Widget#getText(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$141(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$147(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$147(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$148(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$148(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$27(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$118(int, boolean, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$118(int, boolean, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$121(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$122(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$123(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$125(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$126(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$153(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$154(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(int, boolean, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(int, boolean, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$122(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$123(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$124(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$125(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$127(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$128(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$155(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$156(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$2(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$3(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$74(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$resolveProbeGameObject$37(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$resolveProbeGameObject$38(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$76(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.WorldView#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint @@ -843,6 +843,7 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#processWalk(WorldPoin net.runelite.client.plugins.microbot.util.walker.Rs2Walker#resolveDoorSegment(List, int): WorldPoint[] -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#resolveDoorSegment(List, int): WorldPoint[] -> net.runelite.api.Scene#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#resolveDoorSegment(List, int): WorldPoint[] -> net.runelite.api.WorldView#getScene(): Scene +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#resolveProbeGameObject(WorldPoint): TileObject -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#setTarget(WorldPoint, String): void -> net.runelite.api.Client#getLocalPlayer(): Player net.runelite.client.plugins.microbot.util.walker.Rs2Walker#staminaThreshold(): int -> net.runelite.api.Client#getLocalPlayer(): Player net.runelite.client.plugins.microbot.util.walker.Rs2Walker#staminaThreshold(): int -> net.runelite.api.Player#getName(): String From db9e191afd2710ecc2277f1e282aeeb57420aa7b Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 14:36:02 +0100 Subject: [PATCH 26/48] Attribute transport-refresh cache misses and slow stages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pathfinder cold start the walker blocks on was measured at "slow refresh transports=2639ms restr=1ms total=2640ms" — essentially all of it is refreshTransports re-evaluating every transport on a cache miss. The per-stage breakdown (merge/cache/filter/useTrans/similar plus per-type stats) already existed but only at DEBUG, and nothing recorded why the cache missed. - Log the miss reason: "key" (cache key changed — items, coins, toggles) vs "verify" (items identical, game state moved — skills/varbits/varplayers/quests) vs "no_snapshot". - Include the inventory/equipment/bank fingerprint and the previous refresh's value, so an item-driven miss is visible directly. The fingerprint hashes item quantity, so spending coins on a charter fare or toll gate changes it and invalidates the key on its own — this makes that testable rather than assumed. - Promote the existing stage breakdown to INFO when a refresh is slow enough to be the visible cold start. Instrumentation only; no behaviour change. Co-Authored-By: Claude Opus 4.8 --- .../pathfinder/PathfinderConfig.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java index 8b99111191..c74dd18331 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java @@ -108,6 +108,16 @@ public class PathfinderConfig { * on a null pathfinder for its whole duration before the first click can be issued. */ private static final long SLOW_REFRESH_LOG_THRESHOLD_MS = 500L; + + /** + * Inventory/equipment/bank fingerprint from the most recent cache-key computation, and the value + * carried over from the previous refresh. The fingerprint hashes item quantity, so + * spending coins (a charter ship fare, a toll gate) changes it and invalidates the transport + * cache key — forcing a full re-evaluation of every transport. Tracked so a cache miss can say + * whether the items changed or the game state did. + */ + private volatile int lastComputedInvFingerprint; + private volatile int previousRefreshInvFingerprint; @Getter private volatile boolean avoidWilderness; @Getter @@ -348,10 +358,27 @@ private void refreshTransports(WorldPoint target) { filterSimilarTransports(target); } WebWalkLog.cfg("refresh_transports cache_hit key={}", refreshCacheKeyHash); + previousRefreshInvFingerprint = lastComputedInvFingerprint; return; } } + // Cache miss => full re-evaluation of every transport, which is the pathfinder cold start the + // walker blocks on. Attribute it: "key" means the cache key changed (items/coins/toggles), + // "verify" means items were identical but game state moved (skills/varbits/varplayers/quests). + // invFp vs prevInvFp isolates the common case of spending coins on a fare or toll. + String cacheMissReason = transportRefreshSnapshot == null + ? "no_snapshot" + : (transportRefreshSnapshot.cacheKeyHash != refreshCacheKeyHash ? "key" : "verify"); + WebWalkLog.cfgSlow("refresh_transports cache_miss reason={} key={} prevKey={} invFp={} prevInvFp={} invChanged={}", + cacheMissReason, + refreshCacheKeyHash, + transportRefreshSnapshot == null ? 0 : transportRefreshSnapshot.cacheKeyHash, + lastComputedInvFingerprint, + previousRefreshInvFingerprint, + lastComputedInvFingerprint != previousRefreshInvFingerprint); + previousRefreshInvFingerprint = lastComputedInvFingerprint; + transports.clear(); transportsPacked.clear(); blockedTransportEdgesPacked.clear(); @@ -482,6 +509,20 @@ private void refreshTransports(WorldPoint target) { mergeTime, cacheTime, filterTime, useTransportTimeNanos / 1_000_000, similarTime, totalTransports, checkedTransports, usableTeleports.size(), varbitIds.size(), varplayerIds.size()); + // Surface the same breakdown at INFO when the miss is slow enough to be the visible cold + // start, so the dominant stage is identifiable without enabling debug logging. + long refreshTransportsTotalMs = mergeTime + cacheTime + filterTime + similarTime; + if (refreshTransportsTotalMs >= SLOW_REFRESH_LOG_THRESHOLD_MS) { + WebWalkLog.cfgSlow("slow refresh_transports merge={}ms cache={}ms filter={}ms useTrans={}ms similar={}ms total/chk={}/{} vb={} vp={}", + mergeTime, cacheTime, filterTime, useTransportTimeNanos / 1_000_000, similarTime, + totalTransports, checkedTransports, varbitIds.size(), varplayerIds.size()); + typeStats.entrySet().stream() + .sorted((a, b) -> Integer.compare(b.getValue()[2], a.getValue()[2])) + .limit(3) + .forEach(e -> WebWalkLog.cfgSlow("slow refresh_transports type {} cnt={} passed={} timeMs={}", + e.getKey(), e.getValue()[0], e.getValue()[1], e.getValue()[2] / 1000)); + } + typeStats.entrySet().stream() .sorted((a, b) -> Integer.compare(b.getValue()[2], a.getValue()[2])) .limit(5) @@ -1473,6 +1514,7 @@ private String getTransportTypeName(Transport transport) { private int computeTransportRefreshCacheKeyHash(WorldPoint target, Rs2LeaguesTransport.LeaguesContext leaguesCtx) { assert leaguesCtx != null; int invFp = fingerprintInventoryEquipmentBank(); + lastComputedInvFingerprint = invFp; int members = (client != null && client.getWorldType().contains(WorldType.MEMBERS)) ? 1 : 0; int preferTp = (config != null && config.preferTransportToTarget()) ? 1 : 0; int maxSimilar = config != null ? config.maxSimilarTransportDistance() : 0; From ce268fde2beac5a6e5f61d3c9309f32ff1bcb561 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 15:02:10 +0100 Subject: [PATCH 27/48] Hash only transport-gating skills in the transport refresh verification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cache-miss attribution showed a miss with an identical cache key AND identical inventory fingerprint: refresh_transports cache_miss reason=verify key=76240725 prevKey=76240725 invFp=31671802 prevInvFp=31671802 invChanged=false The verification gate hashed Arrays.hashCode(boostedLevels) over SKILLS = Skill.values(), i.e. all 23 skills including HITPOINTS and PRAYER. Those move constantly from HP regen and prayer drain, so the transport cache was invalidated during ordinary play regardless of items — forcing the full re-evaluation the walker blocks on at route start (measured 2652ms, of which useTransport() over 5714 plain transports is 2290ms). No transport gates on hitpoints, so hitpoints cannot change any transport's usability and must not participate in the hash. Collect the skills some transport actually requires (hasRequiredLevels treats level > 0 as a requirement) and hash only those, mirroring how varbits/varplayers are already collected from the merged transport list. The skill set is carried on the snapshot so the cache-hit probe checks the same subset, which also removes 23 per-probe client-thread getBoostedSkillLevel calls. Payment-driven misses are unaffected and still correct: spending coins changes the inventory fingerprint, which is part of the cache key, not this hash. Tests: HP regen / prayer drain must not invalidate; a required skill (agility) still must; out-of-range ordinals are ignored. Co-Authored-By: Claude Opus 4.8 --- .../pathfinder/PathfinderConfig.java | 73 ++++++++++++++--- ...hfinderConfigTransportRefreshHashTest.java | 80 +++++++++++++++++-- 2 files changed, 134 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java index c74dd18331..7abcc4b033 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java @@ -345,13 +345,21 @@ private void refreshTransports(WorldPoint target) { TransportRefreshSnapshot snap = transportRefreshSnapshot; if (snap != null && snap.cacheKeyHash == refreshCacheKeyHash && client != null) { int[] boostedProbe = new int[SKILLS.length]; + final int[] probeOrdinals = snap.sortedSkillOrdinals; Microbot.getClientThread().runOnClientThreadOptional(() -> { - for (int i = 0; i < SKILLS.length; i++) { - boostedProbe[i] = client.getBoostedSkillLevel(SKILLS[i]); + // Only the skills some transport gates on; probing all 23 both cost client-thread + // time and let hitpoints/prayer drift invalidate an otherwise valid cache. + if (probeOrdinals != null) { + for (int ordinal : probeOrdinals) { + if (ordinal >= 0 && ordinal < SKILLS.length) { + boostedProbe[ordinal] = client.getBoostedSkillLevel(SKILLS[ordinal]); + } + } } return true; }); - int verProbe = computeTransportRefreshVerificationHash(boostedProbe, snap.sortedVarbits, snap.sortedVarplayers, snap.sortedQuestIds); + int verProbe = computeTransportRefreshVerificationHash(boostedProbe, snap.sortedSkillOrdinals, + snap.sortedVarbits, snap.sortedVarplayers, snap.sortedQuestIds); if (verProbe == snap.verificationHash) { snap.restoreInto(this); if (useBankItems && config != null && config.maxSimilarTransportDistance() > 0) { @@ -400,10 +408,22 @@ private void refreshTransports(WorldPoint target) { Set varbitIds = new HashSet<>(); Set varplayerIds = new HashSet<>(); + // Skills that some transport actually gates on (see hasRequiredLevels: a level > 0 is a + // requirement). Only these may participate in the verification hash — otherwise hitpoints + // regenerating invalidates the whole transport cache. + Set requiredSkillOrdinals = new HashSet<>(); for (Set ts : mergedList.values()) { for (Transport t : ts) { t.getVarbits().forEach(v -> varbitIds.add(v.getVarbitId())); t.getVarplayers().forEach(v -> varplayerIds.add(v.getVarplayerId())); + int[] required = t.getSkillLevels(); + if (required != null) { + for (int i = 0; i < required.length; i++) { + if (required[i] > 0) { + requiredSkillOrdinals.add(i); + } + } + } } } @@ -490,9 +510,12 @@ private void refreshTransports(WorldPoint target) { .distinct() .sorted() .toArray(); - int verificationHash = computeTransportRefreshVerificationHash(refreshBoostedLevels, sortedVarbits, sortedVarplayers, sortedQuestIds); + int[] sortedSkillOrdinals = requiredSkillOrdinals.stream().mapToInt(Integer::intValue).sorted().toArray(); + int verificationHash = computeTransportRefreshVerificationHash(refreshBoostedLevels, sortedSkillOrdinals, + sortedVarbits, sortedVarplayers, sortedQuestIds); transportRefreshSnapshot = TransportRefreshSnapshot.capture( - refreshCacheKeyHash, verificationHash, sortedVarbits, sortedVarplayers, sortedQuestIds, transports, usableTeleports); + refreshCacheKeyHash, verificationHash, sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds, + transports, usableTeleports); long similarStart = System.currentTimeMillis(); if (useBankItems && config.maxSimilarTransportDistance() > 0) { @@ -1615,17 +1638,38 @@ private int fingerprintInventoryEquipmentBank() { return h[0]; } - private static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds) { - return computeTransportRefreshVerificationHash(boostedLevels, sortedVarbits, sortedVarplayers, sortedQuestIds, questId -> { + private static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedSkillOrdinals, + int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds) { + return computeTransportRefreshVerificationHash(boostedLevels, sortedSkillOrdinals, sortedVarbits, sortedVarplayers, + sortedQuestIds, questId -> { Quest quest = resolveQuestById(questId); return quest == null ? QuestState.NOT_STARTED : Rs2Player.getQuestState(quest); }); } - static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedVarbits, int[] sortedVarplayers, + /** + * @param sortedSkillOrdinals skills that some transport actually gates on. Hashing every skill + * (the previous {@code Arrays.hashCode(boostedLevels)}) meant + * hitpoints regenerating or prayer draining invalidated the transport + * cache, forcing a full ~2.6s re-evaluation on most walks. A skill no + * transport requires cannot change any transport's usability, so it + * must not participate — mirroring how varbits/varplayers are already + * collected from the transports themselves. + */ + static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedSkillOrdinals, + int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds, IntFunction questStateProvider) { assert boostedLevels != null; - int h = Arrays.hashCode(boostedLevels); + int h = 1; + if (sortedSkillOrdinals != null) { + for (int ordinal : sortedSkillOrdinals) { + if (ordinal < 0 || ordinal >= boostedLevels.length) { + continue; + } + h = 31 * h + ordinal; + h = 31 * h + boostedLevels[ordinal]; + } + } for (int id : sortedVarbits) { h = 31 * h + id; h = 31 * h + Microbot.getVarbitValue(id); @@ -1674,17 +1718,20 @@ private static Quest resolveQuestById(int questId) { private static final class TransportRefreshSnapshot { private final int cacheKeyHash; private final int verificationHash; + private final int[] sortedSkillOrdinals; private final int[] sortedVarbits; private final int[] sortedVarplayers; private final int[] sortedQuestIds; private final Map> transportsData; private final Set usableData; - private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] sortedVarbits, int[] sortedVarplayers, + private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] sortedSkillOrdinals, + int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds, Map> transportsData, Set usableData) { this.cacheKeyHash = cacheKeyHash; this.verificationHash = verificationHash; + this.sortedSkillOrdinals = sortedSkillOrdinals; this.sortedVarbits = sortedVarbits; this.sortedVarplayers = sortedVarplayers; this.sortedQuestIds = sortedQuestIds; @@ -1692,7 +1739,8 @@ private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] s this.usableData = usableData; } - static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, int[] sortedVarbits, int[] sortedVarplayers, + static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, int[] sortedSkillOrdinals, + int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds, Map> srcTransports, Set srcUsable) { assert srcTransports != null && srcUsable != null; @@ -1701,7 +1749,8 @@ static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, copy.put(e.getKey(), new HashSet<>(e.getValue())); } Set usableCopy = new HashSet<>(srcUsable); - return new TransportRefreshSnapshot(cacheKeyHash, verificationHash, sortedVarbits, sortedVarplayers, sortedQuestIds, copy, usableCopy); + return new TransportRefreshSnapshot(cacheKeyHash, verificationHash, sortedSkillOrdinals, sortedVarbits, + sortedVarplayers, sortedQuestIds, copy, usableCopy); } void restoreInto(PathfinderConfig c) { diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java index d974eed41a..01a44a4146 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java @@ -2,25 +2,30 @@ import net.runelite.api.Quest; import net.runelite.api.QuestState; +import net.runelite.api.Skill; import org.junit.Test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; public class PathfinderConfigTransportRefreshHashTest { + private static final int[] NO_VARBITS = new int[0]; + private static final int[] NO_VARPLAYERS = new int[0]; + @Test public void verificationHashDiffersForNotStartedVsInProgressQuestState() { - int[] boostedLevels = new int[]{1, 50, 99}; - int[] sortedVarbits = new int[0]; - int[] sortedVarplayers = new int[0]; + int[] boostedLevels = new int[Skill.values().length]; + int[] sortedSkillOrdinals = new int[0]; int trackedQuestId = 987654; int clientOfKourendId = Quest.CLIENT_OF_KOUREND.getId(); int[] sortedQuestIds = new int[]{trackedQuestId, clientOfKourendId}; int hashNotStarted = PathfinderConfig.computeTransportRefreshVerificationHash( boostedLevels, - sortedVarbits, - sortedVarplayers, + sortedSkillOrdinals, + NO_VARBITS, + NO_VARPLAYERS, sortedQuestIds, questId -> { if (questId == trackedQuestId) { @@ -34,8 +39,9 @@ public void verificationHashDiffersForNotStartedVsInProgressQuestState() { int hashInProgress = PathfinderConfig.computeTransportRefreshVerificationHash( boostedLevels, - sortedVarbits, - sortedVarplayers, + sortedSkillOrdinals, + NO_VARBITS, + NO_VARPLAYERS, sortedQuestIds, questId -> { if (questId == trackedQuestId) { @@ -50,4 +56,64 @@ public void verificationHashDiffersForNotStartedVsInProgressQuestState() { assertNotEquals("Quest state transition should invalidate cached transport refresh snapshot", hashNotStarted, hashInProgress); } + + private static int hashWithLevels(int[] sortedSkillOrdinals, int[] boostedLevels) { + return PathfinderConfig.computeTransportRefreshVerificationHash( + boostedLevels, + sortedSkillOrdinals, + NO_VARBITS, + NO_VARPLAYERS, + new int[0], + questId -> QuestState.NOT_STARTED); + } + + /** + * Hitpoints regenerating (or prayer draining) must not invalidate the transport cache. No + * transport gates on those skills, so they cannot change any transport's usability — yet hashing + * every skill meant a single point of HP regen forced a full ~2.6s re-evaluation of all + * transports, which the walker blocks on at route start. + */ + @Test + public void hitpointsAndPrayerDriftDoNotInvalidateWhenNoTransportRequiresThem() { + int[] sortedSkillOrdinals = new int[]{Skill.AGILITY.ordinal()}; + + int[] before = new int[Skill.values().length]; + before[Skill.AGILITY.ordinal()] = 70; + before[Skill.HITPOINTS.ordinal()] = 45; + before[Skill.PRAYER.ordinal()] = 43; + + int[] after = before.clone(); + after[Skill.HITPOINTS.ordinal()] = 46; // regenerated a point + after[Skill.PRAYER.ordinal()] = 41; // prayer drained + + assertEquals("HP regen / prayer drain must not invalidate the transport refresh cache", + hashWithLevels(sortedSkillOrdinals, before), + hashWithLevels(sortedSkillOrdinals, after)); + } + + /** A skill a transport does gate on must still invalidate — e.g. an agility boost/drain. */ + @Test + public void requiredSkillChangeStillInvalidates() { + int[] sortedSkillOrdinals = new int[]{Skill.AGILITY.ordinal()}; + + int[] before = new int[Skill.values().length]; + before[Skill.AGILITY.ordinal()] = 70; + + int[] after = before.clone(); + after[Skill.AGILITY.ordinal()] = 72; // boosted past a shortcut requirement + + assertNotEquals("A boosted level for a skill transports require must invalidate the cache", + hashWithLevels(sortedSkillOrdinals, before), + hashWithLevels(sortedSkillOrdinals, after)); + } + + /** Ordinals outside the supplied levels array must be ignored rather than throwing. */ + @Test + public void outOfRangeSkillOrdinalsAreIgnored() { + int[] boostedLevels = new int[]{1, 2, 3}; + int[] sortedSkillOrdinals = new int[]{-1, 1, 9999}; + + assertEquals(hashWithLevels(sortedSkillOrdinals, boostedLevels), + hashWithLevels(new int[]{1}, boostedLevels)); + } } From 8aee47d8c6c70a5ac26f09e5e66c34e494993a97 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 15:45:03 +0100 Subject: [PATCH 28/48] Compute the LOS regression route once per class Both tests called rawPath(START, GOAL) independently. Each call reloaded all 6292 transports and ran a full Pathfinder, and Pathfinder -> CollisionMap.getCachedRegionId calls Rs2Player.getWorldLocation(), which has no client thread under test and blocks for its full 10s timeout before being swallowed. Compute the route once in @BeforeClass and share it. Full unit suite drops from ~70s to 47s (1106 tests, 0 failures) and the duplicate transport load is gone. Two client-thread timeouts remain inside the single Pathfinder run: the region id is cached for only 5s per CollisionMap, and the timeouts themselves push the run past that window, so it re-queries. Removing those entirely would mean not running the real pathfinder in this test, which would cost the route coverage the greedy LOS-chain assertion depends on. Co-Authored-By: Claude Opus 4.8 --- .../LineOfSightClickRegressionTest.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java index b6c04e37e1..b34ac11a84 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java @@ -41,9 +41,19 @@ public class LineOfSightClickRegressionTest { // The tile the old click layer selected: ~10 tiles out, off the raw path, NO LOS from start. private static final WorldPoint OLD_DEVIATING_CLICK = new WorldPoint(3176, 3428, 0); + /** + * The raw path is computed once for the whole class. Each {@code Pathfinder.run()} reloads all + * transports and, via {@code CollisionMap.getCachedRegionId}, calls + * {@code Rs2Player.getWorldLocation()} — which has no client thread under test and blocks for its + * full 10s timeout. Computing per-test cost the suite ~20s and printed two alarming (harmless) + * TimeoutException stack traces into CI output. + */ + private static List sharedRawPath; + @BeforeClass public static void load() { collisionMap = SplitFlagMap.fromResources(); + sharedRawPath = computeRawPath(START, GOAL); } /** Straight walkable line check — mirrors Rs2Walker.hasWalkableLineOfSight / PathSmoother.lineOfSight. */ @@ -65,7 +75,7 @@ private static boolean los(CollisionMap map, WorldPoint from, WorldPoint to) { return x == tx && y == ty; } - private static List rawPath(WorldPoint start, WorldPoint goal) { + private static List computeRawPath(WorldPoint start, WorldPoint goal) { HashMap> transports = Transport.loadAllFromResources(); PathfinderConfig config = new PathfinderConfig(collisionMap, transports, Collections.emptyList(), null, null); @@ -97,7 +107,7 @@ public void oldDeviatingClickHasNoLineOfSightFromStart() { @Test public void losClampSelectsAnOnRouteTileNotTheDeviatingClick() { CollisionMap map = new CollisionMap(collisionMap); - List raw = rawPath(START, GOAL); + List raw = sharedRawPath; assertFalse("raw path should not be empty", raw.isEmpty()); // Furthest forward raw point with straight LOS from the start = the LOS-clamped first click. @@ -116,7 +126,7 @@ public void losClampSelectsAnOnRouteTileNotTheDeviatingClick() { @Test public void greedyLosChainReachesGoalInFewStraightClicks() { CollisionMap map = new CollisionMap(collisionMap); - List raw = rawPath(START, GOAL); + List raw = sharedRawPath; // Greedy LOS-clamp: from current tile, jump to the furthest raw tile with straight LOS, repeat. List clicks = new ArrayList<>(); From 337d51dc88f23f169aff62999fa9e5551047cb14 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 15:55:37 +0100 Subject: [PATCH 29/48] Suppress the inverse adjacent transport when the landing check fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live log near (3150..3151, 3363): the walker used an agility shortcut, crossed to the far side, then immediately used the opposing entry to come back and could not recover — about 19s of a 2m26s walk. post-handleObject adjacent landing failed | dest=3150,3363 at=3154,3363 post-handleObject landing unresolved | dest=3150,3363 at=3154,3363 post-handleObject landing unresolved | dest=3151,3363 at=3149,3363 <- crossed local reachability miss / route-backed local recovery click The two destinations are adjacent tiles: the same shortcut catalogued as two opposing entries. markAdjacentSamePlaneTransportHandled ran only when waitForPostHandleObjectLanding succeeded. Adjacent same-plane transports require landing on the exact destination tile (maxInclusive == 0) and agility shortcuts routinely land a tile off it, so the crossing succeeded physically while the check reported failure. Nothing was suppressed, so the inverse entry stayed immediately eligible. Suppress both tiles whenever the player is no longer on the origin, regardless of the landing verdict. The landing result is unchanged - it still returns false and replans; this only stops the walker re-crossing straight back. Suppression is already type-agnostic (adjacency and plane only), so shortcuts and doors are covered alike. Adds a unit test that an adjacent same-plane AGILITY_SHORTCUT yields both tiles as suppression points, plus movement.md #22. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 23 +++++ .../pathfinder/PathfinderConfig.java | 87 +++++++++++++++++-- .../microbot/util/walker/Rs2Walker.java | 17 +++- .../util/walker/Rs2WalkerUnitTest.java | 27 ++++++ 4 files changed, 147 insertions(+), 7 deletions(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 5e39e41c9e..c6cba89205 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -470,3 +470,26 @@ private static final long ACTIVE_ROUTE_IDLE_NUDGE_MS = 1_200L; **Where this applies:** `Rs2Walker.tryIssueRouteContinuationClick`, `clearInterimTargetIfReachedOrExpired`, `shouldIssueActiveRouteIdleNudge`, and `ACTIVE_ROUTE_IDLE_NUDGE_MS` / `ACTIVE_ROUTE_IDLE_NUDGE_COOLDOWN_MS`. **Defensive check:** On a multi-hop route, the gap between `first_minimap_click` / route-fallback clicks and the next `active route idle nudge` should be roughly the walk time plus a few ticks — not walk time plus a full idle window. A repeating ~2.5s stationary gap per hop means continuation is being missed and only the nudge is driving the route. + +## 22. Suppress the inverse adjacent transport even when the landing check fails + +Gotcha #5 suppresses the inverse of an adjacent same-plane transport after a crossing, but only on the success path. Adjacent same-plane transports require landing on the *exact* destination tile, and agility shortcuts routinely deposit the player a tile off it — so a crossing can physically succeed while the landing check reports failure. On that path nothing was suppressed, leaving the inverse entry immediately eligible. Record the suppression whenever the player is no longer on the origin, regardless of the landing verdict; the landing result itself should stay unchanged so the route still replans. + +**Why this matters:** Near `(3150..3151, 3363)` the walker crossed an `AGILITY_SHORTCUT`, landed a tile off the catalogued destination, logged `post-handleObject landing unresolved`, then immediately took the opposing entry back across and stranded itself — roughly 19s of a 2m26s walk spent bouncing and recovering. + +**Pattern to follow:** + +```java +boolean landed = waitForPostHandleObjectLanding(transport, destWait, maxInclusive); +if (!landed) { + WorldPoint after = Rs2Player.getWorldLocation(); + // Off the origin => we crossed, even though the strict landing check failed. + if (isAdjacentSamePlaneTransport(transport) && after != null && !after.equals(transport.getOrigin())) { + markAdjacentSamePlaneTransportHandled(transport, object); + } +} +``` + +**Where this applies:** `Rs2Walker.handleTransports` object interactions, `waitForPostHandleObjectLanding` callers, `markAdjacentSamePlaneTransportHandled`, and any adjacent same-plane transport regardless of `TransportType` — suppression is deliberately type-agnostic, so shortcuts and doors are covered alike. + +**Defensive check:** A crossed shortcut should produce at most one `post-handleObject landing unresolved` followed by route progress away from the shortcut — not a second interaction with the opposing entry at an adjacent destination tile (`dest=3150,3363` then `dest=3151,3363`). diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java index 7abcc4b033..08abe16ae0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java @@ -118,6 +118,8 @@ public class PathfinderConfig { */ private volatile int lastComputedInvFingerprint; private volatile int previousRefreshInvFingerprint; + /** Which verification component moved on the most recent verify-miss; see the miss log. */ + private volatile String lastVerifyMissDetail = ""; @Getter private volatile boolean avoidWilderness; @Getter @@ -360,6 +362,21 @@ private void refreshTransports(WorldPoint target) { }); int verProbe = computeTransportRefreshVerificationHash(boostedProbe, snap.sortedSkillOrdinals, snap.sortedVarbits, snap.sortedVarplayers, snap.sortedQuestIds); + if (verProbe != snap.verificationHash) { + // Name the component that moved. "reason=verify" alone cannot distinguish a boosted + // skill from a varbit/varplayer/quest, and guessing which one has already cost a + // round trip. Reuse the probe we just read rather than re-querying. + int[] now = computeTransportRefreshVerificationComponents(boostedProbe, snap.sortedSkillOrdinals, + snap.sortedVarbits, snap.sortedVarplayers, snap.sortedQuestIds); + int[] was = snap.verificationComponents; + lastVerifyMissDetail = was == null || was.length != now.length + ? " changed=unknown" + : " changed=" + + (now[0] != was[0] ? "skills," : "") + + (now[1] != was[1] ? "varbits," : "") + + (now[2] != was[2] ? "varplayers," : "") + + (now[3] != was[3] ? "quests," : ""); + } if (verProbe == snap.verificationHash) { snap.restoreInto(this); if (useBankItems && config != null && config.maxSimilarTransportDistance() > 0) { @@ -378,14 +395,16 @@ private void refreshTransports(WorldPoint target) { String cacheMissReason = transportRefreshSnapshot == null ? "no_snapshot" : (transportRefreshSnapshot.cacheKeyHash != refreshCacheKeyHash ? "key" : "verify"); - WebWalkLog.cfgSlow("refresh_transports cache_miss reason={} key={} prevKey={} invFp={} prevInvFp={} invChanged={}", + WebWalkLog.cfgSlow("refresh_transports cache_miss reason={} key={} prevKey={} invFp={} prevInvFp={} invChanged={}{}", cacheMissReason, refreshCacheKeyHash, transportRefreshSnapshot == null ? 0 : transportRefreshSnapshot.cacheKeyHash, lastComputedInvFingerprint, previousRefreshInvFingerprint, - lastComputedInvFingerprint != previousRefreshInvFingerprint); + lastComputedInvFingerprint != previousRefreshInvFingerprint, + "verify".equals(cacheMissReason) ? lastVerifyMissDetail : ""); previousRefreshInvFingerprint = lastComputedInvFingerprint; + lastVerifyMissDetail = ""; transports.clear(); transportsPacked.clear(); @@ -513,8 +532,11 @@ private void refreshTransports(WorldPoint target) { int[] sortedSkillOrdinals = requiredSkillOrdinals.stream().mapToInt(Integer::intValue).sorted().toArray(); int verificationHash = computeTransportRefreshVerificationHash(refreshBoostedLevels, sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds); + int[] verificationComponents = computeTransportRefreshVerificationComponents(refreshBoostedLevels, + sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds); transportRefreshSnapshot = TransportRefreshSnapshot.capture( - refreshCacheKeyHash, verificationHash, sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds, + refreshCacheKeyHash, verificationHash, verificationComponents, + sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds, transports, usableTeleports); long similarStart = System.currentTimeMillis(); @@ -1690,6 +1712,55 @@ static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] so return h; } + /** + * The verification hash split into its four independent parts + * {skills, varbits, varplayers, quests}, so a verify-miss can name what actually changed instead + * of only reporting that something did. + */ + static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, int[] sortedSkillOrdinals, + int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds) { + return computeTransportRefreshVerificationComponents(boostedLevels, sortedSkillOrdinals, sortedVarbits, + sortedVarplayers, sortedQuestIds, questId -> { + Quest quest = resolveQuestById(questId); + return quest == null ? QuestState.NOT_STARTED : Rs2Player.getQuestState(quest); + }); + } + + static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, int[] sortedSkillOrdinals, + int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds, + IntFunction questStateProvider) { + int skills = 1; + if (boostedLevels != null && sortedSkillOrdinals != null) { + for (int ordinal : sortedSkillOrdinals) { + if (ordinal < 0 || ordinal >= boostedLevels.length) continue; + skills = 31 * skills + ordinal; + skills = 31 * skills + boostedLevels[ordinal]; + } + } + int varbits = 1; + if (sortedVarbits != null) { + for (int id : sortedVarbits) { + varbits = 31 * varbits + id; + varbits = 31 * varbits + Microbot.getVarbitValue(id); + } + } + int varplayers = 1; + if (sortedVarplayers != null) { + for (int id : sortedVarplayers) { + varplayers = 31 * varplayers + id; + varplayers = 31 * varplayers + Microbot.getVarbitPlayerValue(id); + } + } + int quests = 1; + if (sortedQuestIds != null) { + for (int questId : sortedQuestIds) { + quests = 31 * quests + questId; + quests = 31 * quests + questStateHashCode(questStateProvider.apply(questId)); + } + } + return new int[]{skills, varbits, varplayers, quests}; + } + private static int questStateHashCode(QuestState state) { if (state == null) { return -1; @@ -1719,19 +1790,22 @@ private static final class TransportRefreshSnapshot { private final int cacheKeyHash; private final int verificationHash; private final int[] sortedSkillOrdinals; + private final int[] verificationComponents; private final int[] sortedVarbits; private final int[] sortedVarplayers; private final int[] sortedQuestIds; private final Map> transportsData; private final Set usableData; - private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] sortedSkillOrdinals, + private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] verificationComponents, + int[] sortedSkillOrdinals, int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds, Map> transportsData, Set usableData) { this.cacheKeyHash = cacheKeyHash; this.verificationHash = verificationHash; this.sortedSkillOrdinals = sortedSkillOrdinals; + this.verificationComponents = verificationComponents; this.sortedVarbits = sortedVarbits; this.sortedVarplayers = sortedVarplayers; this.sortedQuestIds = sortedQuestIds; @@ -1739,7 +1813,8 @@ private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] s this.usableData = usableData; } - static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, int[] sortedSkillOrdinals, + static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, int[] verificationComponents, + int[] sortedSkillOrdinals, int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds, Map> srcTransports, Set srcUsable) { @@ -1749,7 +1824,7 @@ static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, copy.put(e.getKey(), new HashSet<>(e.getValue())); } Set usableCopy = new HashSet<>(srcUsable); - return new TransportRefreshSnapshot(cacheKeyHash, verificationHash, sortedSkillOrdinals, sortedVarbits, + return new TransportRefreshSnapshot(cacheKeyHash, verificationHash, verificationComponents, sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds, copy, usableCopy); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index e756eff6d2..287e0852a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -8491,11 +8491,26 @@ && recentlyOpenedStationaryDoorOnSegment(path.get(indexOfStartPoint), path.get(i } boolean landedAfterObject = waitForPostHandleObjectLanding(transport, destWait, maxInclusive); if (!landedAfterObject) { + WorldPoint afterInteraction = Rs2Player.getWorldLocation(); + // Adjacent same-plane transports demand landing on the EXACT destination + // tile (maxInclusive == 0), and agility shortcuts routinely deposit the + // player a tile off it — so a crossing can physically succeed while this + // check still fails. Suppression previously ran only on the success path, + // which left the inverse transport immediately eligible: the walker + // crossed, took the same shortcut straight back, and stranded itself. If + // we are no longer on the origin we did cross, so suppress both tiles + // regardless of the landing verdict. The landing result itself is + // unchanged — this still returns false and replans. + if (isAdjacentSamePlaneTransport(transport) + && afterInteraction != null + && !afterInteraction.equals(transport.getOrigin())) { + markAdjacentSamePlaneTransportHandled(transport, object); + } WebWalkLog.spWarn( "post-handleObject landing unresolved (timeout={}ms) dest={} at={}", POST_HANDLE_OBJECT_LANDING_WAIT_MS, compactWorldPoint(destWait), - compactWorldPoint(Rs2Player.getWorldLocation())); + compactWorldPoint(afterInteraction)); } if (landedAfterObject) { markAdjacentSamePlaneTransportHandled(transport, object); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index 53be200210..79fd55200d 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -74,6 +74,33 @@ public void adjacentTransportSuppression_onlyAdjacentSamePlaneTransports() { Rs2Walker.adjacentSamePlaneTransportSuppressionPoints(door, null)); } + /** + * Agility shortcuts catalogued as two opposing adjacent entries must be suppressible like doors. + * Observed live near (3150..3151, 3363): the walker crossed the shortcut, the strict landing + * check failed because it landed a tile off the catalogued destination, so suppression was + * skipped — leaving the inverse entry immediately eligible. It took the same shortcut straight + * back and could not recover. Suppression is deliberately type-agnostic; only adjacency and + * plane matter. + */ + @Test + public void adjacentTransportSuppression_coversAgilityShortcuts() { + Transport shortcut = new Transport( + new WorldPoint(3151, 3363, 0), + new WorldPoint(3150, 3363, 0), + "Shortcut", + TransportType.AGILITY_SHORTCUT, + false, + "Climb-over", + "Stile", + 0); + + assertEquals("An adjacent same-plane agility shortcut must yield both tiles for suppression", + new HashSet<>(Arrays.asList( + new WorldPoint(3151, 3363, 0), + new WorldPoint(3150, 3363, 0))), + Rs2Walker.adjacentSamePlaneTransportSuppressionPoints(shortcut, null)); + } + @Test public void adjacentTransportSuppression_ignoresNonAdjacentTransports() { Transport ladder = new Transport( From a4072101d55a4f43ab1b2bf6bbe14a7d88d203a8 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 17:06:35 +0100 Subject: [PATCH 30/48] Hash varplayer condition verdicts instead of raw values Component attribution showed the teleport stall was self-inflicted: transport_handoff_enter type=TELEPORTATION_SPELL post_transport_segment_handler handled=true i=0 ms=16562 refresh_transports cache_miss reason=verify ... changed=varplayers, LAST_HOME_TELEPORT appears exactly once in the transport data - the Home Teleport cooldown in teleportation_spells.tsv - and is one of the 8 varplayers in the verification hash. Casting the spell writes that varplayer, so the teleport invalidated the transport cache by being used, forcing a full ~2.9s re-evaluation of all 12666 transports inside its own 16.5s handling window. It is also structurally wrong independent of teleporting: COOLDOWN_MINUTES compares against wall-clock minutes, so the raw value advances continuously and can never match a stored one. Hash the condition verdict (TransportVarPlayer.matches) plus the condition identity (id, operator, threshold) rather than the raw varplayer value. The verdict flips exactly once - when the cooldown expires and the transport genuinely becomes usable - so an expiring cooldown still invalidates while a ticking one does not. Condition identity is included so adding or changing a condition still invalidates. Same rule as the skills fix: only inputs that can flip a transport's usability may participate in the cache key. The value provider is injectable so the behaviour is unit-testable: two different raw values inside one cooldown window hash identically, crossing the threshold does not, and the condition encoding is order-independent and deduplicated. Adds movement.md #23. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 25 ++++ .../pathfinder/PathfinderConfig.java | 121 +++++++++++++----- ...hfinderConfigTransportRefreshHashTest.java | 55 ++++++++ 3 files changed, 172 insertions(+), 29 deletions(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index c6cba89205..8a5c8f7118 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -493,3 +493,28 @@ if (!landed) { **Where this applies:** `Rs2Walker.handleTransports` object interactions, `waitForPostHandleObjectLanding` callers, `markAdjacentSamePlaneTransportHandled`, and any adjacent same-plane transport regardless of `TransportType` — suppression is deliberately type-agnostic, so shortcuts and doors are covered alike. **Defensive check:** A crossed shortcut should produce at most one `post-handleObject landing unresolved` followed by route progress away from the shortcut — not a second interaction with the opposing entry at an adjacent destination tile (`dest=3150,3363` then `dest=3151,3363`). + +## 23. Never hash a raw cooldown timer into the transport cache key + +The transport refresh verification hash must contain values that change only when a transport's *usability* changes. A `COOLDOWN_MINUTES` varplayer compares against wall-clock minutes, so its raw value advances continuously — hashing it guarantees cache misses forever. Worse, casting Home Teleport writes `LAST_HOME_TELEPORT`, which is one of the hashed varplayers, so **the teleport invalidated the transport cache simply by being used**, forcing a full re-evaluation of every transport (~2.6s) immediately after the teleport it had just performed. Hash the condition *verdict* (`TransportVarPlayer.matches`) plus the condition identity instead of the raw value: the verdict flips exactly once, when the cooldown expires and the transport actually becomes usable. + +This is the same rule as #19's skill fix: only inputs that can flip a transport's usability may participate. Timers, regenerating stats, and other monotonically-drifting values must not. + +**Why this matters:** A Camelot -> Draynor walk beginning with a Home Teleport logged +`transport_handoff ... ms=16562` with `refresh_transports cache_miss reason=verify ... changed=varplayers` firing inside that window — about 2.9s of a 16.5s teleport was the teleport invalidating its own cache. + +**Pattern to follow:** + +```java +// Wrong: raw value ticks every minute, and casting the spell writes it. +h = 31 * h + Microbot.getVarbitPlayerValue(id); + +// Right: only a usability flip participates. +boolean satisfied = new TransportVarPlayer(id, value, operator).matches(actualValue); +h = 31 * h + id; h = 31 * h + operatorOrdinal; h = 31 * h + value; +h = 31 * h + (satisfied ? 1 : 0); +``` + +**Where this applies:** `PathfinderConfig.hashVarplayerConditionVerdicts`, `computeTransportRefreshVerificationHash`, the transport refresh snapshot, and any future cache key covering varbits/varplayers/skills. + +**Defensive check:** `refresh_transports cache_miss reason=verify ... changed=varplayers` should not appear immediately after a teleport. Unit-test that two different raw values inside the same cooldown window hash identically, and that crossing the threshold does not. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java index 08abe16ae0..736e46eb51 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java @@ -361,13 +361,13 @@ private void refreshTransports(WorldPoint target) { return true; }); int verProbe = computeTransportRefreshVerificationHash(boostedProbe, snap.sortedSkillOrdinals, - snap.sortedVarbits, snap.sortedVarplayers, snap.sortedQuestIds); + snap.sortedVarbits, snap.sortedVarplayerConditions, snap.sortedQuestIds); if (verProbe != snap.verificationHash) { // Name the component that moved. "reason=verify" alone cannot distinguish a boosted // skill from a varbit/varplayer/quest, and guessing which one has already cost a // round trip. Reuse the probe we just read rather than re-querying. int[] now = computeTransportRefreshVerificationComponents(boostedProbe, snap.sortedSkillOrdinals, - snap.sortedVarbits, snap.sortedVarplayers, snap.sortedQuestIds); + snap.sortedVarbits, snap.sortedVarplayerConditions, snap.sortedQuestIds); int[] was = snap.verificationComponents; lastVerifyMissDetail = was == null || was.length != now.length ? " changed=unknown" @@ -427,6 +427,7 @@ private void refreshTransports(WorldPoint target) { Set varbitIds = new HashSet<>(); Set varplayerIds = new HashSet<>(); + List varplayerConditions = new ArrayList<>(); // Skills that some transport actually gates on (see hasRequiredLevels: a level > 0 is a // requirement). Only these may participate in the verification hash — otherwise hitpoints // regenerating invalidates the whole transport cache. @@ -434,7 +435,10 @@ private void refreshTransports(WorldPoint target) { for (Set ts : mergedList.values()) { for (Transport t : ts) { t.getVarbits().forEach(v -> varbitIds.add(v.getVarbitId())); - t.getVarplayers().forEach(v -> varplayerIds.add(v.getVarplayerId())); + t.getVarplayers().forEach(v -> { + varplayerIds.add(v.getVarplayerId()); + varplayerConditions.add(new int[]{v.getVarplayerId(), v.getOperator().ordinal(), v.getValue()}); + }); int[] required = t.getSkillLevels(); if (required != null) { for (int i = 0; i < required.length; i++) { @@ -517,7 +521,7 @@ private void refreshTransports(WorldPoint target) { long filterTime = System.currentTimeMillis() - filterStart; int[] sortedVarbits = varbitIds.stream().mapToInt(Integer::intValue).sorted().toArray(); - int[] sortedVarplayers = varplayerIds.stream().mapToInt(Integer::intValue).sorted().toArray(); + int[] sortedVarplayerConditions = encodeSortedVarplayerConditions(varplayerConditions); int[] sortedQuestIds = mergedList.values().stream() .flatMap(Set::stream) .filter(Objects::nonNull) @@ -531,12 +535,12 @@ private void refreshTransports(WorldPoint target) { .toArray(); int[] sortedSkillOrdinals = requiredSkillOrdinals.stream().mapToInt(Integer::intValue).sorted().toArray(); int verificationHash = computeTransportRefreshVerificationHash(refreshBoostedLevels, sortedSkillOrdinals, - sortedVarbits, sortedVarplayers, sortedQuestIds); + sortedVarbits, sortedVarplayerConditions, sortedQuestIds); int[] verificationComponents = computeTransportRefreshVerificationComponents(refreshBoostedLevels, - sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds); + sortedSkillOrdinals, sortedVarbits, sortedVarplayerConditions, sortedQuestIds); transportRefreshSnapshot = TransportRefreshSnapshot.capture( refreshCacheKeyHash, verificationHash, verificationComponents, - sortedSkillOrdinals, sortedVarbits, sortedVarplayers, sortedQuestIds, + sortedSkillOrdinals, sortedVarbits, sortedVarplayerConditions, sortedQuestIds, transports, usableTeleports); long similarStart = System.currentTimeMillis(); @@ -1661,8 +1665,8 @@ private int fingerprintInventoryEquipmentBank() { } private static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds) { - return computeTransportRefreshVerificationHash(boostedLevels, sortedSkillOrdinals, sortedVarbits, sortedVarplayers, + int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds) { + return computeTransportRefreshVerificationHash(boostedLevels, sortedSkillOrdinals, sortedVarbits, sortedVarplayerConditions, sortedQuestIds, questId -> { Quest quest = resolveQuestById(questId); return quest == null ? QuestState.NOT_STARTED : Rs2Player.getQuestState(quest); @@ -1679,7 +1683,7 @@ private static int computeTransportRefreshVerificationHash(int[] boostedLevels, * collected from the transports themselves. */ static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayers, + int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds, IntFunction questStateProvider) { assert boostedLevels != null; int h = 1; @@ -1696,10 +1700,7 @@ static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] so h = 31 * h + id; h = 31 * h + Microbot.getVarbitValue(id); } - for (int id : sortedVarplayers) { - h = 31 * h + id; - h = 31 * h + Microbot.getVarbitPlayerValue(id); - } + h = 31 * h + hashVarplayerConditionVerdicts(sortedVarplayerConditions); for (int questId : sortedQuestIds) { h = 31 * h + questId; h = 31 * h + questStateHashCode(questStateProvider.apply(questId)); @@ -1718,16 +1719,16 @@ static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] so * of only reporting that something did. */ static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds) { + int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds) { return computeTransportRefreshVerificationComponents(boostedLevels, sortedSkillOrdinals, sortedVarbits, - sortedVarplayers, sortedQuestIds, questId -> { + sortedVarplayerConditions, sortedQuestIds, questId -> { Quest quest = resolveQuestById(questId); return quest == null ? QuestState.NOT_STARTED : Rs2Player.getQuestState(quest); }); } static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayers, int[] sortedQuestIds, + int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds, IntFunction questStateProvider) { int skills = 1; if (boostedLevels != null && sortedSkillOrdinals != null) { @@ -1744,13 +1745,7 @@ static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, varbits = 31 * varbits + Microbot.getVarbitValue(id); } } - int varplayers = 1; - if (sortedVarplayers != null) { - for (int id : sortedVarplayers) { - varplayers = 31 * varplayers + id; - varplayers = 31 * varplayers + Microbot.getVarbitPlayerValue(id); - } - } + int varplayers = hashVarplayerConditionVerdicts(sortedVarplayerConditions); int quests = 1; if (sortedQuestIds != null) { for (int questId : sortedQuestIds) { @@ -1761,6 +1756,74 @@ static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, return new int[]{skills, varbits, varplayers, quests}; } + + /** + * Deterministic {varplayerId, operatorOrdinal, value} triples for every varplayer condition any + * transport declares, deduplicated and sorted. + */ + static int[] encodeSortedVarplayerConditions(List conditions) { + if (conditions == null || conditions.isEmpty()) { + return new int[0]; + } + java.util.TreeSet sorted = new java.util.TreeSet<>((a, b) -> { + if (a[0] != b[0]) return Integer.compare(a[0], b[0]); + if (a[1] != b[1]) return Integer.compare(a[1], b[1]); + return Integer.compare(a[2], b[2]); + }); + sorted.addAll(conditions); + int[] out = new int[sorted.size() * 3]; + int i = 0; + for (int[] c : sorted) { + out[i++] = c[0]; + out[i++] = c[1]; + out[i++] = c[2]; + } + return out; + } + + /** + * Hashes varplayer condition VERDICTS rather than raw varplayer values. + *

    + * A {@code COOLDOWN_MINUTES} condition compares against wall-clock minutes, so its raw value + * advances continuously and would invalidate the transport cache forever. Worse, casting Home + * Teleport writes {@code LAST_HOME_TELEPORT} — one of the hashed varplayers — so a teleport + * invalidated the cache simply by being used, forcing a full re-evaluation of every transport + * (~2.6s) immediately after the teleport it had just performed. + *

    + * Only a flip in whether a condition is satisfied can change a transport's usability, so that is + * what participates. The condition identity is hashed too, so adding/removing a condition still + * invalidates, and an expiring cooldown flips the verdict exactly once. + */ + static int hashVarplayerConditionVerdicts(int[] conditions) { + return hashVarplayerConditionVerdicts(conditions, Microbot::getVarbitPlayerValue); + } + + /** @param varplayerValueProvider injectable for tests; production reads the live varplayer. */ + static int hashVarplayerConditionVerdicts(int[] conditions, + java.util.function.IntUnaryOperator varplayerValueProvider) { + if (conditions == null || conditions.length < 3) { + return 1; + } + TransportVarPlayer.Operator[] operators = TransportVarPlayer.Operator.values(); + Map actualValues = new HashMap<>(); + int h = 1; + for (int i = 0; i + 2 < conditions.length; i += 3) { + int id = conditions[i]; + int opOrdinal = conditions[i + 1]; + int value = conditions[i + 2]; + h = 31 * h + id; + h = 31 * h + opOrdinal; + h = 31 * h + value; + boolean satisfied = false; + if (opOrdinal >= 0 && opOrdinal < operators.length) { + int actual = actualValues.computeIfAbsent(id, varplayerValueProvider::applyAsInt); + satisfied = new TransportVarPlayer(id, value, operators[opOrdinal]).matches(actual); + } + h = 31 * h + (satisfied ? 1 : 0); + } + return h; + } + private static int questStateHashCode(QuestState state) { if (state == null) { return -1; @@ -1792,14 +1855,14 @@ private static final class TransportRefreshSnapshot { private final int[] sortedSkillOrdinals; private final int[] verificationComponents; private final int[] sortedVarbits; - private final int[] sortedVarplayers; + private final int[] sortedVarplayerConditions; private final int[] sortedQuestIds; private final Map> transportsData; private final Set usableData; private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] verificationComponents, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayers, + int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds, Map> transportsData, Set usableData) { this.cacheKeyHash = cacheKeyHash; @@ -1807,7 +1870,7 @@ private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] v this.sortedSkillOrdinals = sortedSkillOrdinals; this.verificationComponents = verificationComponents; this.sortedVarbits = sortedVarbits; - this.sortedVarplayers = sortedVarplayers; + this.sortedVarplayerConditions = sortedVarplayerConditions; this.sortedQuestIds = sortedQuestIds; this.transportsData = transportsData; this.usableData = usableData; @@ -1815,7 +1878,7 @@ private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] v static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, int[] verificationComponents, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayers, + int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds, Map> srcTransports, Set srcUsable) { assert srcTransports != null && srcUsable != null; @@ -1825,7 +1888,7 @@ static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, } Set usableCopy = new HashSet<>(srcUsable); return new TransportRefreshSnapshot(cacheKeyHash, verificationHash, verificationComponents, sortedSkillOrdinals, sortedVarbits, - sortedVarplayers, sortedQuestIds, copy, usableCopy); + sortedVarplayerConditions, sortedQuestIds, copy, usableCopy); } void restoreInto(PathfinderConfig c) { diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java index 01a44a4146..5669bcddc8 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java @@ -3,8 +3,10 @@ import net.runelite.api.Quest; import net.runelite.api.QuestState; import net.runelite.api.Skill; +import net.runelite.client.plugins.microbot.shortestpath.TransportVarPlayer; import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -107,6 +109,59 @@ public void requiredSkillChangeStillInvalidates() { hashWithLevels(sortedSkillOrdinals, after)); } + /** + * A cooldown gate must not churn the cache while it ticks. {@code COOLDOWN_MINUTES} compares + * against wall-clock minutes, so hashing its raw varplayer value invalidated the transport cache + * continuously — and casting Home Teleport writes {@code LAST_HOME_TELEPORT}, so the teleport + * invalidated the cache simply by being used, costing a full ~2.6s re-evaluation right after + * every teleport. Only the satisfied/not-satisfied verdict may participate. + */ + @Test + public void cooldownVerdictIsStableWhileTicking_butFlipsWhenItExpires() { + int varplayerId = 12345; + int cooldownMinutes = 30; + int cooldownOp = TransportVarPlayer.Operator.COOLDOWN_MINUTES.ordinal(); + int[] conditions = new int[]{varplayerId, cooldownOp, cooldownMinutes}; + long nowMinutes = System.currentTimeMillis() / 60000L; + + // Two different raw values, both still inside the 30 minute cooldown => same verdict. + int justTeleported = PathfinderConfig.hashVarplayerConditionVerdicts( + conditions, id -> (int) (nowMinutes - 1)); + int fiveMinutesLater = PathfinderConfig.hashVarplayerConditionVerdicts( + conditions, id -> (int) (nowMinutes - 6)); + + assertEquals("a cooldown ticking must NOT invalidate the transport cache — this is what made " + + "casting Home Teleport invalidate the cache by writing LAST_HOME_TELEPORT", + justTeleported, fiveMinutesLater); + + // Past the threshold the transport becomes usable, so the verdict flips and must invalidate. + int cooldownExpired = PathfinderConfig.hashVarplayerConditionVerdicts( + conditions, id -> (int) (nowMinutes - (cooldownMinutes + 1))); + + assertNotEquals("an expiring cooldown changes usability and must invalidate", + justTeleported, cooldownExpired); + } + + /** Condition triples must be deduplicated and ordered so the hash is position-independent. */ + @Test + public void varplayerConditionEncodingIsDeterministicAndDeduplicated() { + java.util.List unordered = java.util.Arrays.asList( + new int[]{99, 1, 5}, + new int[]{10, 0, 2}, + new int[]{99, 1, 5}, // duplicate + new int[]{10, 0, 1}); + java.util.List shuffled = java.util.Arrays.asList( + new int[]{10, 0, 1}, + new int[]{99, 1, 5}, + new int[]{10, 0, 2}); + + int[] a = PathfinderConfig.encodeSortedVarplayerConditions(unordered); + int[] b = PathfinderConfig.encodeSortedVarplayerConditions(shuffled); + + assertArrayEquals("insertion order must not change the encoding", a, b); + assertEquals("duplicates must collapse (3 distinct conditions x 3 ints)", 9, a.length); + } + /** Ordinals outside the supplied levels array must be ignored rather than throwing. */ @Test public void outOfRangeSkillOrdinalsAreIgnored() { From d58ab1aa18ff23c3598a495bdd55f39ceb316591 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 17:16:00 +0100 Subject: [PATCH 31/48] Hash varbit condition verdicts instead of raw values The visible cold start is not the teleport - it is the gap between starting a walk and the walker doing anything at all: walk_start cache_miss reason=verify ... changed=varbits, slow refresh transports=2888ms pf_ready elapsed=2418ms transport_handoff_enter TELEPORTATION_SPELL <- only now does it act That first miss is attributed to varbits, a different cause from the varplayer cooldown fixed in the previous commit. TransportVarbit is structurally identical to TransportVarPlayer - same operators, same matches() - so it gets the same treatment: hash the condition verdict plus the condition identity rather than the raw varbit value. A varbit whose value moves without flipping any verdict cannot change a transport's usability, so it must not force a full re-evaluation the walker blocks on before its first action. Whether this removes the walk-start miss depends on whether that varbit's verdict genuinely flipped. If a miss still appears with changed=varbits it is a real usability change, and the remaining lever is the cost of a miss (~2.3s of useTransport over 5714 transports) rather than its frequency. The value provider is injectable, so the test asserts the real behaviour: 7 -> 9 against "> 5" does not invalidate, 7 -> 3 does. Extends movement.md #23 to cover varbits. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 2 +- .../pathfinder/PathfinderConfig.java | 95 ++++++++++++------- ...hfinderConfigTransportRefreshHashTest.java | 28 +++++- 3 files changed, 90 insertions(+), 35 deletions(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 8a5c8f7118..192f8feb8e 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -515,6 +515,6 @@ h = 31 * h + id; h = 31 * h + operatorOrdinal; h = 31 * h + value; h = 31 * h + (satisfied ? 1 : 0); ``` -**Where this applies:** `PathfinderConfig.hashVarplayerConditionVerdicts`, `computeTransportRefreshVerificationHash`, the transport refresh snapshot, and any future cache key covering varbits/varplayers/skills. +**Where this applies:** `PathfinderConfig.hashVarplayerConditionVerdicts`, `PathfinderConfig.hashVarbitConditionVerdicts`, `computeTransportRefreshVerificationHash`, the transport refresh snapshot, and any future cache key covering varbits/varplayers/skills. Varbits get the identical treatment: a raw varbit moving without flipping a condition verdict must not invalidate, which is what produced the ~2.4s dead time between pressing go and the first action. **Defensive check:** `refresh_transports cache_miss reason=verify ... changed=varplayers` should not appear immediately after a teleport. Unit-test that two different raw values inside the same cooldown window hash identically, and that crossing the threshold does not. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java index 736e46eb51..9bb584e261 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java @@ -361,13 +361,13 @@ private void refreshTransports(WorldPoint target) { return true; }); int verProbe = computeTransportRefreshVerificationHash(boostedProbe, snap.sortedSkillOrdinals, - snap.sortedVarbits, snap.sortedVarplayerConditions, snap.sortedQuestIds); + snap.sortedVarbitConditions, snap.sortedVarplayerConditions, snap.sortedQuestIds); if (verProbe != snap.verificationHash) { // Name the component that moved. "reason=verify" alone cannot distinguish a boosted // skill from a varbit/varplayer/quest, and guessing which one has already cost a // round trip. Reuse the probe we just read rather than re-querying. int[] now = computeTransportRefreshVerificationComponents(boostedProbe, snap.sortedSkillOrdinals, - snap.sortedVarbits, snap.sortedVarplayerConditions, snap.sortedQuestIds); + snap.sortedVarbitConditions, snap.sortedVarplayerConditions, snap.sortedQuestIds); int[] was = snap.verificationComponents; lastVerifyMissDetail = was == null || was.length != now.length ? " changed=unknown" @@ -426,6 +426,7 @@ private void refreshTransports(WorldPoint target) { } Set varbitIds = new HashSet<>(); + List varbitConditions = new ArrayList<>(); Set varplayerIds = new HashSet<>(); List varplayerConditions = new ArrayList<>(); // Skills that some transport actually gates on (see hasRequiredLevels: a level > 0 is a @@ -434,7 +435,10 @@ private void refreshTransports(WorldPoint target) { Set requiredSkillOrdinals = new HashSet<>(); for (Set ts : mergedList.values()) { for (Transport t : ts) { - t.getVarbits().forEach(v -> varbitIds.add(v.getVarbitId())); + t.getVarbits().forEach(v -> { + varbitIds.add(v.getVarbitId()); + varbitConditions.add(new int[]{v.getVarbitId(), v.getOperator().ordinal(), v.getValue()}); + }); t.getVarplayers().forEach(v -> { varplayerIds.add(v.getVarplayerId()); varplayerConditions.add(new int[]{v.getVarplayerId(), v.getOperator().ordinal(), v.getValue()}); @@ -520,8 +524,8 @@ private void refreshTransports(WorldPoint target) { Rs2LeaguesTransport.injectLeaguesTransports(this, leaguesCtx, usableTeleports, transports, transportsPacked, typeStats); long filterTime = System.currentTimeMillis() - filterStart; - int[] sortedVarbits = varbitIds.stream().mapToInt(Integer::intValue).sorted().toArray(); - int[] sortedVarplayerConditions = encodeSortedVarplayerConditions(varplayerConditions); + int[] sortedVarbitConditions = encodeSortedConditionTriples(varbitConditions); + int[] sortedVarplayerConditions = encodeSortedConditionTriples(varplayerConditions); int[] sortedQuestIds = mergedList.values().stream() .flatMap(Set::stream) .filter(Objects::nonNull) @@ -535,12 +539,12 @@ private void refreshTransports(WorldPoint target) { .toArray(); int[] sortedSkillOrdinals = requiredSkillOrdinals.stream().mapToInt(Integer::intValue).sorted().toArray(); int verificationHash = computeTransportRefreshVerificationHash(refreshBoostedLevels, sortedSkillOrdinals, - sortedVarbits, sortedVarplayerConditions, sortedQuestIds); + sortedVarbitConditions, sortedVarplayerConditions, sortedQuestIds); int[] verificationComponents = computeTransportRefreshVerificationComponents(refreshBoostedLevels, - sortedSkillOrdinals, sortedVarbits, sortedVarplayerConditions, sortedQuestIds); + sortedSkillOrdinals, sortedVarbitConditions, sortedVarplayerConditions, sortedQuestIds); transportRefreshSnapshot = TransportRefreshSnapshot.capture( refreshCacheKeyHash, verificationHash, verificationComponents, - sortedSkillOrdinals, sortedVarbits, sortedVarplayerConditions, sortedQuestIds, + sortedSkillOrdinals, sortedVarbitConditions, sortedVarplayerConditions, sortedQuestIds, transports, usableTeleports); long similarStart = System.currentTimeMillis(); @@ -1665,8 +1669,8 @@ private int fingerprintInventoryEquipmentBank() { } private static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds) { - return computeTransportRefreshVerificationHash(boostedLevels, sortedSkillOrdinals, sortedVarbits, sortedVarplayerConditions, + int[] sortedVarbitConditions, int[] sortedVarplayerConditions, int[] sortedQuestIds) { + return computeTransportRefreshVerificationHash(boostedLevels, sortedSkillOrdinals, sortedVarbitConditions, sortedVarplayerConditions, sortedQuestIds, questId -> { Quest quest = resolveQuestById(questId); return quest == null ? QuestState.NOT_STARTED : Rs2Player.getQuestState(quest); @@ -1683,7 +1687,7 @@ private static int computeTransportRefreshVerificationHash(int[] boostedLevels, * collected from the transports themselves. */ static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayerConditions, + int[] sortedVarbitConditions, int[] sortedVarplayerConditions, int[] sortedQuestIds, IntFunction questStateProvider) { assert boostedLevels != null; int h = 1; @@ -1696,10 +1700,7 @@ static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] so h = 31 * h + boostedLevels[ordinal]; } } - for (int id : sortedVarbits) { - h = 31 * h + id; - h = 31 * h + Microbot.getVarbitValue(id); - } + h = 31 * h + hashVarbitConditionVerdicts(sortedVarbitConditions); h = 31 * h + hashVarplayerConditionVerdicts(sortedVarplayerConditions); for (int questId : sortedQuestIds) { h = 31 * h + questId; @@ -1719,8 +1720,8 @@ static int computeTransportRefreshVerificationHash(int[] boostedLevels, int[] so * of only reporting that something did. */ static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds) { - return computeTransportRefreshVerificationComponents(boostedLevels, sortedSkillOrdinals, sortedVarbits, + int[] sortedVarbitConditions, int[] sortedVarplayerConditions, int[] sortedQuestIds) { + return computeTransportRefreshVerificationComponents(boostedLevels, sortedSkillOrdinals, sortedVarbitConditions, sortedVarplayerConditions, sortedQuestIds, questId -> { Quest quest = resolveQuestById(questId); return quest == null ? QuestState.NOT_STARTED : Rs2Player.getQuestState(quest); @@ -1728,7 +1729,7 @@ static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, } static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayerConditions, int[] sortedQuestIds, + int[] sortedVarbitConditions, int[] sortedVarplayerConditions, int[] sortedQuestIds, IntFunction questStateProvider) { int skills = 1; if (boostedLevels != null && sortedSkillOrdinals != null) { @@ -1738,13 +1739,7 @@ static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, skills = 31 * skills + boostedLevels[ordinal]; } } - int varbits = 1; - if (sortedVarbits != null) { - for (int id : sortedVarbits) { - varbits = 31 * varbits + id; - varbits = 31 * varbits + Microbot.getVarbitValue(id); - } - } + int varbits = hashVarbitConditionVerdicts(sortedVarbitConditions); int varplayers = hashVarplayerConditionVerdicts(sortedVarplayerConditions); int quests = 1; if (sortedQuestIds != null) { @@ -1758,10 +1753,10 @@ static int[] computeTransportRefreshVerificationComponents(int[] boostedLevels, /** - * Deterministic {varplayerId, operatorOrdinal, value} triples for every varplayer condition any + * Deterministic {id, operatorOrdinal, value} triples for every varbit/varplayer condition any * transport declares, deduplicated and sorted. */ - static int[] encodeSortedVarplayerConditions(List conditions) { + static int[] encodeSortedConditionTriples(List conditions) { if (conditions == null || conditions.isEmpty()) { return new int[0]; } @@ -1794,6 +1789,42 @@ static int[] encodeSortedVarplayerConditions(List conditions) { * what participates. The condition identity is hashed too, so adding/removing a condition still * invalidates, and an expiring cooldown flips the verdict exactly once. */ + static int hashVarbitConditionVerdicts(int[] conditions) { + return hashVarbitConditionVerdicts(conditions, Microbot::getVarbitValue); + } + + /** + * Varbit counterpart of {@link #hashVarplayerConditionVerdicts}. Same rule: only a flip in + * whether a condition is satisfied can change a transport's usability, so a raw varbit moving + * without changing any verdict must not invalidate the cache. + * + * @param varbitValueProvider injectable for tests; production reads the live varbit. + */ + static int hashVarbitConditionVerdicts(int[] conditions, + java.util.function.IntUnaryOperator varbitValueProvider) { + if (conditions == null || conditions.length < 3) { + return 1; + } + TransportVarbit.Operator[] operators = TransportVarbit.Operator.values(); + Map actualValues = new HashMap<>(); + int h = 1; + for (int i = 0; i + 2 < conditions.length; i += 3) { + int id = conditions[i]; + int opOrdinal = conditions[i + 1]; + int value = conditions[i + 2]; + h = 31 * h + id; + h = 31 * h + opOrdinal; + h = 31 * h + value; + boolean satisfied = false; + if (opOrdinal >= 0 && opOrdinal < operators.length) { + int actual = actualValues.computeIfAbsent(id, varbitValueProvider::applyAsInt); + satisfied = new TransportVarbit(id, value, operators[opOrdinal]).matches(actual); + } + h = 31 * h + (satisfied ? 1 : 0); + } + return h; + } + static int hashVarplayerConditionVerdicts(int[] conditions) { return hashVarplayerConditionVerdicts(conditions, Microbot::getVarbitPlayerValue); } @@ -1854,7 +1885,7 @@ private static final class TransportRefreshSnapshot { private final int verificationHash; private final int[] sortedSkillOrdinals; private final int[] verificationComponents; - private final int[] sortedVarbits; + private final int[] sortedVarbitConditions; private final int[] sortedVarplayerConditions; private final int[] sortedQuestIds; private final Map> transportsData; @@ -1862,14 +1893,14 @@ private static final class TransportRefreshSnapshot { private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] verificationComponents, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayerConditions, + int[] sortedVarbitConditions, int[] sortedVarplayerConditions, int[] sortedQuestIds, Map> transportsData, Set usableData) { this.cacheKeyHash = cacheKeyHash; this.verificationHash = verificationHash; this.sortedSkillOrdinals = sortedSkillOrdinals; this.verificationComponents = verificationComponents; - this.sortedVarbits = sortedVarbits; + this.sortedVarbitConditions = sortedVarbitConditions; this.sortedVarplayerConditions = sortedVarplayerConditions; this.sortedQuestIds = sortedQuestIds; this.transportsData = transportsData; @@ -1878,7 +1909,7 @@ private TransportRefreshSnapshot(int cacheKeyHash, int verificationHash, int[] v static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, int[] verificationComponents, int[] sortedSkillOrdinals, - int[] sortedVarbits, int[] sortedVarplayerConditions, + int[] sortedVarbitConditions, int[] sortedVarplayerConditions, int[] sortedQuestIds, Map> srcTransports, Set srcUsable) { assert srcTransports != null && srcUsable != null; @@ -1887,7 +1918,7 @@ static TransportRefreshSnapshot capture(int cacheKeyHash, int verificationHash, copy.put(e.getKey(), new HashSet<>(e.getValue())); } Set usableCopy = new HashSet<>(srcUsable); - return new TransportRefreshSnapshot(cacheKeyHash, verificationHash, verificationComponents, sortedSkillOrdinals, sortedVarbits, + return new TransportRefreshSnapshot(cacheKeyHash, verificationHash, verificationComponents, sortedSkillOrdinals, sortedVarbitConditions, sortedVarplayerConditions, sortedQuestIds, copy, usableCopy); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java index 5669bcddc8..18b0a629c7 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfigTransportRefreshHashTest.java @@ -4,6 +4,7 @@ import net.runelite.api.QuestState; import net.runelite.api.Skill; import net.runelite.client.plugins.microbot.shortestpath.TransportVarPlayer; +import net.runelite.client.plugins.microbot.shortestpath.TransportVarbit; import org.junit.Test; import static org.junit.Assert.assertArrayEquals; @@ -155,13 +156,36 @@ public void varplayerConditionEncodingIsDeterministicAndDeduplicated() { new int[]{99, 1, 5}, new int[]{10, 0, 2}); - int[] a = PathfinderConfig.encodeSortedVarplayerConditions(unordered); - int[] b = PathfinderConfig.encodeSortedVarplayerConditions(shuffled); + int[] a = PathfinderConfig.encodeSortedConditionTriples(unordered); + int[] b = PathfinderConfig.encodeSortedConditionTriples(shuffled); assertArrayEquals("insertion order must not change the encoding", a, b); assertEquals("duplicates must collapse (3 distinct conditions x 3 ints)", 9, a.length); } + /** + * The walk-start cold start was attributed to {@code changed=varbits}. A varbit whose raw value + * moves without flipping any condition verdict must not invalidate the transport cache — that is + * a full ~2.6s re-evaluation the walker blocks on before it can issue its first action. + */ + @Test + public void varbitValueChangeWithoutVerdictFlipDoesNotInvalidate() { + int varbitId = 4242; + int threshold = 5; + int greaterThan = TransportVarbit.Operator.GREATER_THAN.ordinal(); + int[] conditions = new int[]{varbitId, greaterThan, threshold}; + + // 7 -> 9: both satisfy "> 5", so usability is unchanged. + assertEquals("a varbit moving without flipping its verdict must not invalidate", + PathfinderConfig.hashVarbitConditionVerdicts(conditions, id -> 7), + PathfinderConfig.hashVarbitConditionVerdicts(conditions, id -> 9)); + + // 7 -> 3 crosses the threshold, so the transport becomes unusable and must invalidate. + assertNotEquals("crossing the threshold changes usability and must invalidate", + PathfinderConfig.hashVarbitConditionVerdicts(conditions, id -> 7), + PathfinderConfig.hashVarbitConditionVerdicts(conditions, id -> 3)); + } + /** Ordinals outside the supplied levels array must be ignored rather than throwing. */ @Test public void outOfRangeSkillOrdinalsAreIgnored() { From 038c9e81fb02989d4dcbbc2826ebec8d36030a48 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 17:41:55 +0100 Subject: [PATCH 32/48] Revert line-of-sight click clamping; keep clicks on the raw route A minimap click is resolved by the game's own pathing, so line of sight is irrelevant to walking - a player clicks past a corner, through a doorway, or around a building and the server routes them there. Clamping click targets to a straight walkable line made the walker advance corner-to-corner, stopping at each corner to re-aim before issuing the next click. That is a visible behavioural tell and no human walks that way. It also bought no correctness. The off-route click (3176,3428) that motivated the clamp was not caused by a lack of line of sight: selection returned null on a stale anchor, so the caller fell through to clamping a far smoothed waypoint to a Euclidean radius, which landed off the planned route. The game then pathed to that off-route tile its own way. Once the anchor self-heal landed, selection returns a raw-route point by construction and the LOS tier was doing nothing but shortening clicks. The invariant that actually matters is that the target sits ON the raw route: then however the server walks there, we arrive on the planned path. - Primary selection is again the furthest forward raw-route point within minimap reach, with no LOS and no bounded-reachability requirement (the latter could also shorten clicks without protecting anything the route membership does not). - The outside-clip route fallback drops its LOS-preferring tier too. - Removes hasWalkableLineOfSight and isOffSceneOrUnloaded, now unused. - Retained: the anchor self-heal (the real fix), raw-route-only selection, the reachability guard on the wall-distance fallback branch, and the door/gate pre-click guards, which are what stop a click skipping a closed door. Replaces LineOfSightClickRegressionTest with RouteClickTargetRegressionTest, which pins the correct invariant - the historic click is not on the raw route, and the route offers long forward reach within minimap range so clicks are not shortened to the nearest corner. Rewrites movement.md #20 to record that LOS clamping was tried and reverted, so it is not reintroduced. Guardrail baseline regenerated: all 24 entries are lambda-index renumbering in untouched methods (26 removed, 24 added), no new non-lambda violations. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 19 ++- .../microbot/util/walker/Rs2Walker.java | 119 +++---------- .../LineOfSightClickRegressionTest.java | 159 ------------------ .../RouteClickTargetRegressionTest.java | 103 ++++++++++++ .../client-thread-guardrail-baseline.txt | 50 +++--- 5 files changed, 157 insertions(+), 293 deletions(-) delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/RouteClickTargetRegressionTest.java diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 192f8feb8e..4bc2ba0f3b 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -431,24 +431,25 @@ if (!reachable.contains(scaledFallback)) continue; **Defensive check:** Unit-test the rejoin core with an injected reachability predicate: (a) player pushed one tile off-path with nothing ahead reachable must return a point *behind* the anchor; (b) with points ahead reachable it must return the furthest-forward one inside the reach circle; (c) nothing reachable must return null so stall/recalc can take over. Live-repro: walk north flush against Varrock castle's west wall — the walker should round the corner instead of pressing into the wall, and a fresh teleport should not produce a click far off the route. -## 20. Clamp minimap click targets to line-of-sight, not a Euclidean radius +## 20. Keep minimap click targets on the raw route — do NOT clamp them to line-of-sight -A minimap click is resolved by the **game's own pathing** to the clicked tile — not by our route. So the click target must be a tile the player can reach in a **straight walkable line** (line-of-sight). If the target is off a straight line (around a building corner, past an open door), the game improvises its own route to it and deviates: cutting the corner through the door, looping wide, or trapping itself so it has to backtrack out. Do **not** pick the click by clamping a far smoothed waypoint to a Euclidean radius (`clampToEuclideanRadius`) — that routinely overshoots the first line-of-sight waypoint into no-LOS territory. Select the furthest forward raw-path point with straight LOS from the player (`hasWalkableLineOfSight`, mirroring `PathSmoother.lineOfSight` over the pathfinder `CollisionMap`). LOS is naturally long on open roads (clicks stay long) and short only at corners/tight rooms (where short clicks are correct), so it does not over-click. +A minimap click is resolved by the **game's own pathing**, so line of sight is irrelevant to walking: a player clicks past a corner, through a doorway, or around a building and the server routes them there. The invariant that matters is that the click target sits **on the raw route** — then wherever the server chooses to walk, we arrive on the planned path. Do not select the click by clamping a far smoothed waypoint to a Euclidean radius either; that is what produced an off-route target in the first place. -**Why this matters:** Walking from `(3183,3435)` to `(3173,3399)` past the **Varrock West Bank**, the player has straight LOS only ~3 tiles (to the corner `(3182,3432)`), but the click layer clamped a far waypoint to a 10-tile radius and clicked `(3176,3428)` — off the raw path and with no LOS. The game then looped the player wide around the bank and it had to backtrack. The raw path itself is optimal (down the west side); the defect is purely the no-LOS click. LOS clamping turns the whole 41-tile leg into 4 clean straight clicks (`3182,3432 → 3172,3425 → 3172,3399 → 3173,3399`). +**Why this matters:** Walking past the Varrock West Bank, selection returned null on a stale anchor (see #24), so the caller clamped a far smoothed waypoint to a ~10 tile radius and clicked `(3176,3428)` — a tile that is *not* on the raw route. The game pathed there its own way, deviating wide and backtracking. + +**Do not "fix" this with line-of-sight.** An earlier revision clamped clicks to a straight walkable line. It removed the symptom but made the walker advance corner-to-corner — stopping at every corner to re-aim, because it would only click as far as it could see in a straight line. That is a visible behavioural tell and it bought no correctness: an on-route target is safe regardless of how the server walks to it. It was reverted. **Pattern to follow:** ```java -WorldPoint losTarget = findFurthestRawPathPointMatching(rawPath, playerLoc, reach, rawAnchor, - candidate -> hasWalkableLineOfSight(playerLoc, candidate)); -if (losTarget != null) return losTarget; // straight line — game can't deviate -// fall back to reachable / off-scene / rejoin only when no LOS point exists +// Furthest forward point ON THE RAW ROUTE within minimap reach. No LOS requirement. +WorldPoint forward = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, + rawAnchorIndex, Rs2Walker::isKnownWalkableOrUnloaded); ``` -**Where this applies:** `Rs2Walker.selectRouteClickTarget`, `Rs2Walker.hasWalkableLineOfSight`, and any minimap click-target selection that clamps to a Euclidean radius while a raw route exists. +**Where this applies:** `Rs2Walker.selectRouteClickTarget`, `findFurthestVisibleKnownRawPathPoint`, and any minimap click selection while a raw route exists. Pending doors/gates are handled by `handlePendingDoorBeforeRouteClick` — not by shortening the click. -**Defensive check:** `LineOfSightClickRegressionTest` — from `(3183,3435)` to `(3173,3399)`, the old `(3176,3428)` click must have no LOS from the start, the LOS-clamped click must be on the raw route, and the greedy LOS chain must reach the goal in ≤ 8 straight clicks. +**Defensive check:** `RouteClickTargetRegressionTest` asserts the historic `(3176,3428)` is not on the raw route, and that the route offers several on-route candidates within minimap reach so a click is never artificially shortened to the nearest corner. ## 21. Route continuation is one-shot — keep the idle-nudge window short diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 287e0852a0..78ecf67a0a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -19,7 +19,6 @@ import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.globval.enums.InterfaceTab; import net.runelite.client.plugins.microbot.shortestpath.*; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; @@ -3017,51 +3016,27 @@ private static WorldPoint selectRouteClickTarget(List rawPath, World private static WorldPoint selectRouteClickTargetAnchored(List rawPath, WorldPoint playerLoc, int maxEuclidean, int rawAnchorIndex) { - // 1. Prefer the furthest forward raw point the player can reach in a STRAIGHT walkable line - // (line-of-sight). A minimap click is resolved by the GAME's own pathing; if the target - // is not on a straight walkable line, the game improvises its own route to it — cutting - // corners, deviating wide, or trapping itself against a building (e.g. clicking a tile - // ~10 tiles out past the Varrock West Bank corner, which it reaches by looping). Clicking - // only LOS targets keeps the game walking exactly our route. See movement.md #19. - WorldPoint losTarget = null; - try { - losTarget = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, - rawAnchorIndex, candidate -> hasWalkableLineOfSight(playerLoc, candidate)); - } catch (Exception ex) { - log.debug("[Walker] LOS click selection failed, falling back: {}", ex.getMessage()); - } - if (losTarget != null && !losTarget.equals(playerLoc)) { - lastRouteClickTier = "los"; - return losTarget; - } - // 2. No LOS point (tight spot / just off-path): fall back to the furthest forward - // collision-REACHABLE raw point. Depth is generous (2x the click radius) so legitimate - // around-a-corner detours to a Euclidean-close point are still admitted, while the wrong - // side of a wall is not. - Set reachable = Rs2Tile - .getReachableTilesFromTile(playerLoc, Math.max(2, maxEuclidean * 2)).keySet(); - WorldPoint forwardReachable = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, - rawAnchorIndex, reachable::contains); - if (forwardReachable != null) { - lastRouteClickTier = "reach"; - return forwardReachable; - } - // 3. Last resort WHILE A RAW ROUTE EXISTS: furthest forward walkable/unloaded raw point. - // This tier can essentially always answer, which is the point — it guarantees selection - // never falls through to the caller's smoothed-waypoint Euclidean clamp, which is what - // produced the off-route click (3176,3428) that the game then detoured to. Worst case we - // click a slightly-too-far tile that is still ON the planned route. - WorldPoint walkable = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, + // Click the furthest forward point ON THE RAW ROUTE that is within minimap reach. + // + // A minimap click is resolved by the GAME's own pathing, so line of sight is irrelevant to + // walking: a player clicks past a corner, through a doorway, or around a building and the + // server routes them there. Requiring straight LOS made the walker advance corner-to-corner, + // stopping at each one to re-aim — a visible tell, and it bought no correctness. The + // invariant that actually matters is that the target sits ON the planned route, so wherever + // the server routes us we still arrive on that route. + // + // The off-route click (3176,3428) that started this came from the caller's + // smoothed-waypoint Euclidean clamp after selection returned null on a stale anchor — not + // from a lack of line of sight. Pending doors/gates are handled by + // handlePendingDoorBeforeRouteClick, not by shortening the click. + WorldPoint forward = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, Rs2Walker::isKnownWalkableOrUnloaded); - if (walkable != null && !walkable.equals(playerLoc)) { - lastRouteClickTier = "walkable"; - return walkable; + if (forward != null && !forward.equals(playerLoc)) { + lastRouteClickTier = "route"; + return forward; } - // 4. Long route leaving the loaded area: furthest forward off-scene raw point. - WorldPoint offScene = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, - candidate -> isOffSceneOrUnloaded(candidate) && isMiniMapClickable(candidate, 5)); - lastRouteClickTier = offScene != null ? "offscene" : "none"; - return offScene; + lastRouteClickTier = "none"; + return null; } /** @@ -3072,51 +3047,8 @@ private static WorldPoint selectRouteClickTargetAnchored(List rawPat */ private static volatile String lastRouteClickTier = "none"; - private static boolean isOffSceneOrUnloaded(WorldPoint point) { - if (point == null) { - return false; - } - return LocalPoint.fromWorld(Microbot.getClient().getTopLevelWorldView(), point) == null; - } - /** - * True if the player can walk from {@code from} to {@code to} in a straight (Bresenham-style) - * line without a collision-blocked step, per the pathfinder collision map that produced the raw - * path. A minimap click is resolved by the game's own pathing, so handing it a target that is - * NOT on a straight walkable line lets it improvise a detour (corner-cut through an open door, - * loop around a building). Restricting click targets to LOS keeps the game on our route. - * Mirrors {@code PathSmoother.lineOfSight} (collision only; transport-edge blocks are rare on a - * short click line and are handled by the route-object layer). - */ - static boolean hasWalkableLineOfSight(WorldPoint from, WorldPoint to) { - if (from == null || to == null || from.getPlane() != to.getPlane()) { - return false; - } - PathfinderConfig cfg = Rs2PathApi.getPathfinderConfig(); - if (cfg == null) { - return false; - } - CollisionMap map = cfg.getMap(); - if (map == null) { - return false; - } - int x = from.getX(); - int y = from.getY(); - final int z = from.getPlane(); - final int tx = to.getX(); - final int ty = to.getY(); - int guard = 0; - while ((x != tx || y != ty) && guard++ < 128) { - int dx = Integer.signum(tx - x); - int dy = Integer.signum(ty - y); - if (!map.canStep(x, y, z, dx, dy)) { - return false; - } - x += dx; - y += dy; - } - return x == tx && y == ty; - } + /** * Finds a reachable raw-path point to rejoin the route after the player has been pushed off it @@ -3187,17 +3119,6 @@ static WorldPoint findFurthestVisibleKnownRawPathPoint(List rawPath, return null; } - // Prefer a straight-walkable (line-of-sight) route point here too, so the outside-clip - // route fallback follows the same policy as primary selection instead of handing the game a - // target it can only reach by detouring. - WorldPoint losFallback = findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, - rawAnchorIndex, candidate -> !candidate.equals(playerLoc) - && hasWalkableLineOfSight(playerLoc, candidate) - && isMiniMapClickable(candidate, 5)); - if (losFallback != null) { - return losFallback; - } - return findFurthestRawPathPointMatching(rawPath, playerLoc, maxEuclidean, rawAnchorIndex, candidate -> !candidate.equals(playerLoc) && isKnownWalkableOrUnloaded(candidate) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java deleted file mode 100644 index b34ac11a84..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/LineOfSightClickRegressionTest.java +++ /dev/null @@ -1,159 +0,0 @@ -package net.runelite.client.plugins.microbot.shortestpath; - -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Regression for the "walker deviates wide / traps itself near Varrock West Bank" bug. - * - *

    Root cause: the click layer overshot the first line-of-sight waypoint by clamping the click to - * a Euclidean radius (~10 tiles), landing on a tile with no straight walkable line-of-sight from the - * player. A minimap click is resolved by the game's own pathing, so a no-LOS target let the game - * improvise a detour around the bank. The fix restricts click targets to raw-path points the player - * has straight walkable line-of-sight to (see {@code Rs2Walker.hasWalkableLineOfSight} / - * {@code selectRouteClickTarget}). - * - *

    This test pins the collision-map behaviour the fix relies on, using the same - * {@code CollisionMap.canStep} line-walk the runtime helper uses. - */ -public class LineOfSightClickRegressionTest { - - private static SplitFlagMap collisionMap; - - private static final WorldPoint START = new WorldPoint(3183, 3435, 0); - private static final WorldPoint GOAL = new WorldPoint(3173, 3399, 0); - // The tile the old click layer selected: ~10 tiles out, off the raw path, NO LOS from start. - private static final WorldPoint OLD_DEVIATING_CLICK = new WorldPoint(3176, 3428, 0); - - /** - * The raw path is computed once for the whole class. Each {@code Pathfinder.run()} reloads all - * transports and, via {@code CollisionMap.getCachedRegionId}, calls - * {@code Rs2Player.getWorldLocation()} — which has no client thread under test and blocks for its - * full 10s timeout. Computing per-test cost the suite ~20s and printed two alarming (harmless) - * TimeoutException stack traces into CI output. - */ - private static List sharedRawPath; - - @BeforeClass - public static void load() { - collisionMap = SplitFlagMap.fromResources(); - sharedRawPath = computeRawPath(START, GOAL); - } - - /** Straight walkable line check — mirrors Rs2Walker.hasWalkableLineOfSight / PathSmoother.lineOfSight. */ - private static boolean los(CollisionMap map, WorldPoint from, WorldPoint to) { - if (from.getPlane() != to.getPlane()) { - return false; - } - int x = from.getX(), y = from.getY(), z = from.getPlane(), tx = to.getX(), ty = to.getY(); - int guard = 0; - while ((x != tx || y != ty) && guard++ < 128) { - int dx = Integer.signum(tx - x); - int dy = Integer.signum(ty - y); - if (!map.canStep(x, y, z, dx, dy)) { - return false; - } - x += dx; - y += dy; - } - return x == tx && y == ty; - } - - private static List computeRawPath(WorldPoint start, WorldPoint goal) { - HashMap> transports = Transport.loadAllFromResources(); - PathfinderConfig config = new PathfinderConfig(collisionMap, transports, - Collections.emptyList(), null, null); - try { - java.lang.reflect.Field f = PathfinderConfig.class.getDeclaredField("calculationCutoffMillis"); - f.setAccessible(true); - f.setLong(config, 10000); - for (Map.Entry> e : transports.entrySet()) { - if (e.getKey() == null) continue; - config.getTransports().put(e.getKey(), e.getValue()); - config.getTransportsPacked().put(WorldPointUtil.packWorldPoint(e.getKey()), e.getValue()); - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - Pathfinder pf = new Pathfinder(config, start, goal); - pf.run(); - return pf.getPath(); - } - - @Test - public void oldDeviatingClickHasNoLineOfSightFromStart() { - CollisionMap map = new CollisionMap(collisionMap); - assertFalse("The old ~10-tile click (3176,3428) must NOT have straight LOS from the start — " - + "that is exactly why the game improvised a detour around the bank", - los(map, START, OLD_DEVIATING_CLICK)); - } - - @Test - public void losClampSelectsAnOnRouteTileNotTheDeviatingClick() { - CollisionMap map = new CollisionMap(collisionMap); - List raw = sharedRawPath; - assertFalse("raw path should not be empty", raw.isEmpty()); - - // Furthest forward raw point with straight LOS from the start = the LOS-clamped first click. - WorldPoint losClick = null; - for (WorldPoint p : raw) { - if (los(map, START, p)) { - losClick = p; - } - } - assertTrue("There must be at least one raw point with LOS from the start", losClick != null); - assertTrue("The LOS-clamped click must be on the raw route", raw.contains(losClick)); - assertFalse("The LOS-clamped click must not be the deviating off-route tile", - losClick.equals(OLD_DEVIATING_CLICK)); - } - - @Test - public void greedyLosChainReachesGoalInFewStraightClicks() { - CollisionMap map = new CollisionMap(collisionMap); - List raw = sharedRawPath; - - // Greedy LOS-clamp: from current tile, jump to the furthest raw tile with straight LOS, repeat. - List clicks = new ArrayList<>(); - int cur = 0; - int guard = 0; - while (cur < raw.size() - 1 && guard++ < 60) { - int next = cur; - for (int i = cur + 1; i < raw.size(); i++) { - if (los(map, raw.get(cur), raw.get(i))) { - next = i; - } - } - if (next == cur) { - next = cur + 1; // no LOS even to the neighbour: step one tile (shouldn't happen here) - } - // Every issued click must be a straight walkable line from where the click is issued. - assertTrue("click " + clicks.size() + " must have LOS from the previous stop", - los(map, raw.get(cur), raw.get(next))); - clicks.add(raw.get(next)); - cur = next; - } - - assertEquals("Greedy LOS chain must end exactly on the goal", - GOAL, clicks.get(clicks.size() - 1)); - // The 41-tile route collapses to a handful of straight clicks (measured: 4). Guard against a - // regression that shatters it into many tiny clicks (which would look botlike / be slow). - assertTrue("LOS clamp must not over-click a mostly-straight 41-tile route, got " + clicks.size(), - clicks.size() <= 8); - } -} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/RouteClickTargetRegressionTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/RouteClickTargetRegressionTest.java new file mode 100644 index 0000000000..d21f4faeae --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/RouteClickTargetRegressionTest.java @@ -0,0 +1,103 @@ +package net.runelite.client.plugins.microbot.shortestpath; + +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Regression for the "walker deviates wide / traps itself near Varrock West Bank" bug. + * + *

    The click layer had overshot onto {@code (3176,3428)} — a tile that is not on the raw + * route — because route selection returned null on a stale anchor and the caller fell through + * to clamping a far smoothed waypoint to a Euclidean radius. The game then pathed to that off-route + * tile its own way, which is what produced the wide deviation and the backtracking. + * + *

    The invariant this pins is therefore "the click target is on the raw route", + * not "the click target is in line of sight". A minimap click is resolved by the game's own + * pathing, so line of sight is irrelevant to walking — a player clicks past a corner and lets the + * server route them. An earlier revision clamped clicks to line of sight; that made the walker + * advance corner-to-corner and was reverted. Do not reintroduce it: if a target sits on the planned + * route, it does not matter which way the server walks there, because we arrive on the route. + */ +public class RouteClickTargetRegressionTest { + + private static SplitFlagMap collisionMap; + + private static final WorldPoint START = new WorldPoint(3183, 3435, 0); + private static final WorldPoint GOAL = new WorldPoint(3173, 3399, 0); + /** The historic bad click: ~10 tiles out, and crucially NOT on the raw route. */ + private static final WorldPoint OLD_DEVIATING_CLICK = new WorldPoint(3176, 3428, 0); + + private static List sharedRawPath; + + @BeforeClass + public static void load() { + collisionMap = SplitFlagMap.fromResources(); + // Computed once: each Pathfinder.run() reloads all transports and, via + // CollisionMap.getCachedRegionId, calls Rs2Player.getWorldLocation(), which has no client + // thread under test and blocks for its full timeout. + sharedRawPath = computeRawPath(START, GOAL); + } + + private static List computeRawPath(WorldPoint start, WorldPoint goal) { + HashMap> transports = Transport.loadAllFromResources(); + PathfinderConfig config = new PathfinderConfig(collisionMap, transports, + Collections.emptyList(), null, null); + try { + java.lang.reflect.Field f = PathfinderConfig.class.getDeclaredField("calculationCutoffMillis"); + f.setAccessible(true); + f.setLong(config, 10000); + for (Map.Entry> e : transports.entrySet()) { + if (e.getKey() == null) continue; + config.getTransports().put(e.getKey(), e.getValue()); + config.getTransportsPacked().put(WorldPointUtil.packWorldPoint(e.getKey()), e.getValue()); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + Pathfinder pf = new Pathfinder(config, start, goal); + pf.run(); + return pf.getPath(); + } + + @Test + public void theHistoricDeviatingClickIsNotOnTheRawRoute() { + assertFalse("raw path should not be empty", sharedRawPath.isEmpty()); + assertFalse("(3176,3428) must not be on the raw route — selecting only on-route points is " + + "what prevents the game improvising a detour", + sharedRawPath.contains(OLD_DEVIATING_CLICK)); + } + + /** + * Route selection must be able to reach well past a corner in a single click, the way a player + * would. A line-of-sight clamp reduced the first click on this route to ~3 tiles (just the + * corner); the raw route offers far more forward reach than that within minimap range. + */ + @Test + public void rawRouteOffersLongForwardReachWithinMinimapRange() { + int minimapReach = 10; + int reachable = 0; + for (WorldPoint p : sharedRawPath) { + int dx = p.getX() - START.getX(); + int dy = p.getY() - START.getY(); + if (dx * dx + dy * dy <= minimapReach * minimapReach) { + reachable++; + } + } + assertTrue("the route should offer several on-route candidates within minimap reach, " + + "so a click is not artificially shortened to the nearest corner; got " + reachable, + reachable >= 6); + } +} diff --git a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt index 1881543c3b..2a5b2499b6 100644 --- a/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt +++ b/runelite-client/src/test/resources/threadsafety/client-thread-guardrail-baseline.txt @@ -794,40 +794,38 @@ net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isDoorLikeSceneObject net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isDoorOnSegment(TileObject, WorldPoint, WorldPoint): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isKnownWalkableOrUnloaded(WorldPoint): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isKnownWalkableOrUnloaded(WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isOffSceneOrUnloaded(WorldPoint): boolean -> net.runelite.api.Client#getTopLevelWorldView(): WorldView -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isOffSceneOrUnloaded(WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.ObjectComposition#getName(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isPendingRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.ObjectComposition#getName(): String net.runelite.client.plugins.microbot.util.walker.Rs2Walker#isUnresolvedRouteDoorObject(TileObject, WorldPoint, WorldPoint, WorldPoint, int): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$48(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$49(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$45(WorldPoint, WorldPoint, WorldPoint, List, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$findDoorNearSegment$46(WorldPoint, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$getPointWithWallDistance$13(WorldView, int[][], WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$getPointWithWallDistance$14(WorldView, int[][], WorldPoint): boolean -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$194(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$163(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$165(String): boolean -> net.runelite.api.widgets.Widget#getText(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$141(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$147(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$147(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$148(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$148(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$27(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(int, boolean, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(int, boolean, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$122(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$123(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$124(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$125(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$127(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$128(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$155(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$156(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleFairyRing$191(Transport, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$160(Widget, Object[]): boolean -> net.runelite.api.widgets.Widget#getOnOpListener(): Object[] +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleMinigameTeleport$162(String): boolean -> net.runelite.api.widgets.Widget#getText(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$138(int, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$144(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$144(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$145(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleObjectExceptions$145(WorldPoint, TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleRockfall$24(WorldPoint, Tile): boolean -> net.runelite.api.Tile#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$117(int, boolean, boolean, TileObject): boolean -> net.runelite.api.ObjectComposition#getName(): String +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$117(int, boolean, boolean, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$119(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$120(TileObject): boolean -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$121(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$122(Transport, Object): Integer -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$124(int, List, TileObject): boolean -> net.runelite.api.TileObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleTransports$125(Transport, TileObject): int -> net.runelite.api.TileObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$152(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$handleWildernessObelisk$153(Transport, GameObject): boolean -> net.runelite.api.GameObject#getId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$2(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$processWalk$3(): boolean -> net.runelite.api.widgets.Widget#getSpriteId(): int -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$resolveProbeGameObject$37(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$resolveProbeGameObject$38(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint -net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$76(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$resolveProbeGameObject$34(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$resolveProbeGameObject$35(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint +net.runelite.client.plugins.microbot.util.walker.Rs2Walker#lambda$tryHandleBlockingPathObjectsWithTimeout$73(WorldPoint, GameObject): boolean -> net.runelite.api.GameObject#getWorldLocation(): WorldPoint net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.Client#getTopLevelWorldView(): WorldView net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.WorldView#isInstance(): boolean net.runelite.client.plugins.microbot.util.walker.Rs2Walker#localPointForWorld(WorldPoint): LocalPoint -> net.runelite.api.coords.LocalPoint#fromWorld(WorldView, WorldPoint): LocalPoint From 2701c23368e9e3294ec1d6e5bb48112282379b33 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 17:44:13 +0100 Subject: [PATCH 33/48] Correct movement.md #19 after reverting reachability-gated primary selection #19 instructed selecting the primary click from the player's bounded reachable set "not walkability". The primary selector now uses isKnownWalkableOrUnloaded, so the entry contradicted the code it documents. Scope it to what is still true and still implemented: reachability gating belongs on click targets that are invented rather than taken from the route - the getPointWithWallDistance nudge and the scaled-radius directional fallback - plus the bidirectional rejoin. Records that gating primary selection was tried and reverted, since a BFS bounded by click radius can exclude legitimate around-a-corner points and shorten clicks for no benefit: a point taken from the raw route is safe by construction (#20). Documentation only. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 4bc2ba0f3b..f4bd2e2715 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -401,35 +401,40 @@ When a gate can be crossed by either a quest unlock or a currency payment, do no **Defensive check:** Add resource tests that assert both paid and quest-free transports load, the gate tiles are not quest-only restricted, and the gate edge is blocked without a usable transport. -## 19. Gate minimap click targets on reachability, not walkability — and allow bidirectional rejoin +## 19. Reachability-gate the FALLBACK click paths, and allow bidirectional rejoin -A tile being *walkable* (`Rs2Tile.isWalkable`, i.e. not `BLOCK_MOVEMENT_FULL`) is not the same as being *reachable from the player*. Next to a wall the two diverge hard: a tile flush on the far side of a castle wall is walkable and Euclidean-close, but only reachable via a long detour. Any minimap click-target selection that filters on walkability/clip-visibility alone will happily pick the wrong side of the wall and stall. Select the next raw-route click point from the player's collision-**reachable** set (`Rs2Tile.getReachableTilesFromTile`, which honors edge flags) with a generous BFS depth (~2× the click radius) so real around-a-corner detours still qualify while the wrong side is excluded. Only fall back to a walkable/off-scene point when the target is genuinely off the loaded scene (collision can't be verified there). Likewise, `getPointWithWallDistance` computes tiles reachable *from the target*, so its nudge can land across a wall or inside a building — verify its result with `Rs2Tile.isTileReachable` before clicking it. +A tile being *walkable* (`Rs2Tile.isWalkable`, i.e. not `BLOCK_MOVEMENT_FULL`) is not the same as being *reachable from the player*. Next to a wall the two diverge hard: a tile flush on the far side of a castle wall is walkable and Euclidean-close, but only reachable via a long detour. This matters for click targets that are **invented** rather than taken from the route: -Forward-only anchoring (introduced to stop the walker snapping back to already-travelled branches) overcorrects when the player is pushed *off* the path: if nothing ahead is reachable, forward-only recovery returns nothing and the walker stalls against the wall. Recovery must therefore be **bidirectional**: scan a bounded index window on both sides of the anchor and rejoin via the nearest reachable raw point, preferring the furthest-forward one so normal progress is never sacrificed. This is a rejoin path for the off-path case only; steady-state progress stays forward-only. +- `getPointWithWallDistance` picks a neighbour reachable *from the target*, from an unordered set, so its nudge can land on the far side of a wall or inside a building. Pass the player position so it prefers a neighbour reachable from and nearest to the player, and verify the result with `Rs2Tile.isTileReachable` before clicking it. +- The scaled-radius directional fallback in `walkMiniMapToward` invents a geometric point toward an off-clip target. Only click it if it is actually reachable, otherwise a fresh teleport produces clicks far off the route. -**Why this matters:** Walking north up the west side of Varrock castle, the path runs flush against the wall. The selector picked a forward raw/nudged point on the far (east) side of the wall and clicked it, so the player pressed into the wall and stalled. The same mechanism clicks into houses (interior tile is walkable but unreachable) and produces "random far clicks" right after a teleport, when a stale smoothed waypoint or blind scaled-radius directional guess targets an unreachable tile. +Forward-only anchoring (introduced to stop the walker snapping back to already-travelled branches) overcorrects when the player is pushed *off* the path: if nothing ahead is reachable, forward-only recovery returns nothing and the walker stalls. Recovery must therefore be **bidirectional**: scan a bounded index window on both sides of the anchor and rejoin via the nearest reachable raw point, preferring the furthest-forward one so normal progress is never sacrificed. This is a rejoin path for the off-path case only; steady-state progress stays forward-only. + +**Do NOT extend this to primary selection.** An earlier revision selected the primary click from the player's bounded reachable set. That was reverted: a BFS bounded by click radius can exclude legitimate around-a-corner points and shorten clicks for no benefit, because a point taken from the raw route is safe by construction regardless of how the server walks to it (see #20). Reachability gating belongs only on targets that are *not* route points. + +**Why this matters:** Walking past the Varrock West Bank, the wall-distance nudge and a stale-anchor fallback produced clicks that were off the planned route, so the game improvised a detour. The route-membership rule in #20 fixes the primary path; these guards fix the invented-target paths. **Pattern to follow:** ```java -// Primary: furthest-forward COLLISION-REACHABLE raw point (wrong side of wall excluded). +// Primary: an on-route point (see #20) — no reachability gate needed. WorldPoint rawRouteTarget = selectRouteClickTarget(rawPath, playerLoc, reach, rawAnchorIndex); if (rawRouteTarget != null) { clickTarget = rawRouteTarget; } else { - clickTarget = getPointWithWallDistance(targetWp); + // Invented target: now reachability matters. + clickTarget = getPointWithWallDistance(targetWp, playerLoc); if (!Rs2Tile.isTileReachable(clickTarget)) { WorldPoint rejoin = findReachableRejoinRawPathPoint(rawPath, playerLoc, reach, rawAnchorIndex); if (rejoin != null) clickTarget = rejoin; // step back onto the line if needed } } -// Directional scaled-radius guesses must also be reachability-gated: -if (!reachable.contains(scaledFallback)) continue; +if (!reachable.contains(scaledFallback)) continue; // directional guesses too ``` -**Where this applies:** `Rs2Walker.selectRouteClickTarget`, `Rs2Walker.findReachableRejoinRawPathPoint`, `Rs2Walker.walkMiniMapToward`, `getPointWithWallDistance` consumers, and any minimap click-target selector used while a raw route exists. +**Where this applies:** `Rs2Walker.findReachableRejoinRawPathPoint`, `Rs2Walker.walkMiniMapToward`, `getPointWithWallDistance` consumers. **Not** `selectRouteClickTarget`. -**Defensive check:** Unit-test the rejoin core with an injected reachability predicate: (a) player pushed one tile off-path with nothing ahead reachable must return a point *behind* the anchor; (b) with points ahead reachable it must return the furthest-forward one inside the reach circle; (c) nothing reachable must return null so stall/recalc can take over. Live-repro: walk north flush against Varrock castle's west wall — the walker should round the corner instead of pressing into the wall, and a fresh teleport should not produce a click far off the route. +**Defensive check:** Unit-test the rejoin core with an injected reachability predicate: (a) player pushed one tile off-path with nothing ahead reachable must return a point *behind* the anchor; (b) with points ahead reachable it must return the furthest-forward one inside the reach circle; (c) nothing reachable must return null so stall/recalc can take over. ## 20. Keep minimap click targets on the raw route — do NOT clamp them to line-of-sight From 1121e621c7917dcbc7e71799260f20fd06cd1b72 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 17:49:16 +0100 Subject: [PATCH 34/48] Audit movement.md gotchas: cross-reference #5 and add a reading guide Full audit of all 23 entries against the current source. Symbol check: every symbol named in a "Where this applies" line resolves. Five symbols (atTransportDestination, DIRECT_CLICK_MAX_DISTANCE, clickOptimisticRecoveryTarget, isRouteActive, playerIsIdleForShortWindow) appear only inside "Pattern to follow" blocks as illustrative pseudo-code, which is easy to mistake for a real API when grepping. Numeric claims are consistent with the code: #21 correctly describes 2500ms as the previous idle-nudge window and quotes the current 1200ms constant, and the walker lock #1 refers to exists. Two fixes: - #5 says to suppress the inverse adjacent transport after a *successful* crossing. That is incomplete in isolation: a reader following only #5 reproduces the bug #22 fixes, because adjacent transports require an exact-tile landing and a crossing can succeed while the landing check fails. Cross-referenced. - Added a reading guide noting that pattern blocks may be pseudo-code, that "Where this applies" is the authoritative symbol list, and that #19/#20 deliberately record reverted approaches. Documentation only. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index f4bd2e2715..7e560adf9b 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -1,5 +1,16 @@ # Movement Gotchas +> **How to read these.** Each entry records a failure mode observed while working on the walker. +> Two caveats for reviewers: +> +> - **"Pattern to follow" blocks are illustrative.** They may use shortened or pseudo-code names +> (`atTransportDestination`, `isRouteActive`, `clickOptimisticRecoveryTarget`, …) that do not exist +> verbatim in the source. The **"Where this applies"** line is the authoritative list of real symbols. +> - **Some entries record approaches that were tried and reverted** (#19, #20). They are kept +> deliberately so the reverted idea is not reintroduced from an older note. Where an entry cites a +> measured log line, that measurement is the evidence; where it does not, treat it as a hypothesis +> that happened to hold at the time of writing. + ## 1. Do not recurse on failed minimap clicks without changing the click target `Rs2Walker.processWalk` holds the walker lock while processing a path. If a minimap click is rejected because the calculated point is outside the minimap clip, immediately recursing with the same target can spin forever while still holding the lock. Shrink the click target toward the player or otherwise change the condition before retrying. @@ -81,7 +92,7 @@ If a previous minimap click is still moving the player, do not attribute that mo ## 5. Suppress the inverse adjacent transport after crossing a same-plane door -Some doors are represented in `transports.tsv` as two adjacent same-plane transports, one for each direction. After the walker clicks one side and arrives on the other, immediately accepting the inverse transport can bounce the player back through the same door instead of letting the next minimap step continue away from it. Mark both tiles of a successful adjacent same-plane transport as recently handled for a short window. +Some doors are represented in `transports.tsv` as two adjacent same-plane transports, one for each direction. After the walker clicks one side and arrives on the other, immediately accepting the inverse transport can bounce the player back through the same door instead of letting the next minimap step continue away from it. Mark both tiles of a successful adjacent same-plane transport as recently handled for a short window. **This is necessary but not sufficient — see #22:** suppression must also run when the landing check *fails*, because an adjacent transport requires landing on the exact destination tile and a crossing can succeed while that check reports failure. **Why this matters:** Leaving Draynor Manor through the east/back door can alternate between `3123,3360,0` and `3123,3361,0`, repeatedly logging raw-path/current-tile transport handling and burning the route timeout before walking back to Draynor. From 2892605fd9f6025b5ac9204d68203c213c0ae748 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 18:00:17 +0100 Subject: [PATCH 35/48] Jitter route click reach so clicks do not all cover the same tile span Route selection always returned the furthest candidate inside a fixed radius (MINIMAP_REACH_EUCLIDEAN - 1), so every click covered the same tile span. The existing randomisation nearby does not address this: nextWalkingDistance (9-12) gates whether a waypoint is far enough to be worth clicking, and proximityWake (2-4) gates the post-click wait, but neither varies the reach used to pick the tile. Jitter the reach per click via routeClickReach, applied inside selectRouteClickTarget so every click path picks it up rather than only the main route loop. Varying reach is the safe axis: it changes only how far along the route the target sits, never sideways, so the target stays on the planned route. Lateral tile offsets are the wrong axis - they leave the route, which is what produced clicks on the wrong side of a fence or inside a building, and route membership is what keeps the server's own pathing on our route. Lateral randomness belongs inside the tile, in click-point jitter. Bounds are load-bearing. The floor (7) stays clear of INTERIM_CLOSE_TILES (5) so a short click cannot land inside the interim-close threshold, clear the checkpoint immediately and cause click thrash. The ceiling is the caller's reach, already tuned to the minimap clip. A shortened reach also retries at full reach before giving up, so it can never be the reason selection returns null and drops the click onto the off-route wall-nudge clamp. Adds movement.md #24 and tests for the bounds, actual variation, and degenerate reach values. Not yet validated live. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 20 ++++++++++ .../microbot/util/walker/Rs2Walker.java | 38 ++++++++++++++++++- .../util/walker/Rs2WalkerUnitTest.java | 29 ++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 7e560adf9b..5b3e4436a5 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -535,3 +535,23 @@ h = 31 * h + (satisfied ? 1 : 0); **Where this applies:** `PathfinderConfig.hashVarplayerConditionVerdicts`, `PathfinderConfig.hashVarbitConditionVerdicts`, `computeTransportRefreshVerificationHash`, the transport refresh snapshot, and any future cache key covering varbits/varplayers/skills. Varbits get the identical treatment: a raw varbit moving without flipping a condition verdict must not invalidate, which is what produced the ~2.4s dead time between pressing go and the first action. **Defensive check:** `refresh_transports cache_miss reason=verify ... changed=varplayers` should not appear immediately after a teleport. Unit-test that two different raw values inside the same cooldown window hash identically, and that crossing the threshold does not. + +## 24. Vary click reach, not click direction + +Route selection otherwise always returns the furthest candidate inside a fixed radius, so every click covers the same tile span — a deterministic signature. Jitter the reach per click instead (`routeClickReach`), which only changes how far **along** the route the target sits. Do **not** offset the target sideways: a lateral tile offset leaves the planned route, which is what produces clicks on the wrong side of a fence or inside a building (#15), and route membership is the property that keeps the server's own pathing on our route (#20). Lateral randomness belongs *inside* the tile, in click-point jitter, where it changes the pixel without changing the destination. + +Two bounds are load-bearing. The floor must stay clear of `INTERIM_CLOSE_TILES`, or a short click lands inside the interim-close threshold, clears the checkpoint immediately and produces click thrash with visible stop-start movement. The ceiling is the caller's reach, already tuned to the minimap clip; above it clicks simply fall outside the clip and take the fallback path. A shortened reach must also never be the reason selection fails — retry at full reach before falling through, or the click drops onto the off-route wall-nudge clamp (#19). + +**Pattern to follow:** + +```java +int jitteredReach = routeClickReach(maxEuclidean); +WorldPoint selected = selectRouteClickTargetAnchored(rawPath, playerLoc, jitteredReach, rawAnchorIndex); +if (selected == null && jitteredReach < maxEuclidean) { + selected = selectRouteClickTargetAnchored(rawPath, playerLoc, maxEuclidean, rawAnchorIndex); +} +``` + +**Where this applies:** `Rs2Walker.routeClickReach`, `Rs2Walker.selectRouteClickTarget`, and any future click-target randomisation. + +**Defensive check:** Unit-test that the jittered reach never exceeds the caller's reach, never drops to the interim-close threshold, actually varies across calls, and passes a degenerate reach through unchanged. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 78ecf67a0a..41aad99c32 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -135,6 +135,13 @@ public static WorldPoint getCurrentTarget() { private static final long PARTIAL_TRANS_RECAL_COOLDOWN_MS = 3500L; private static final int INTERIM_CLOSE_TILES = 5; + + /** + * Floor for the jittered per-click route reach. Deliberately above {@link #INTERIM_CLOSE_TILES} + * so a short click cannot land inside the interim-close threshold, which would clear the + * checkpoint immediately and cause click thrash. + */ + private static final int ROUTE_CLICK_REACH_MIN_TILES = 7; private static final int INTERIM_PRECLICK_TILES = 6; private static final int INTERIM_RUN_PRECLICK_TILES = 8; private static final int INTERIM_MOVING_POLL_MS = 450; @@ -2999,7 +3006,19 @@ private static WorldPoint selectRouteClickTarget(List rawPath, World lastRouteClickTier = "norawpath"; return null; } - WorldPoint selected = selectRouteClickTargetAnchored(rawPath, playerLoc, maxEuclidean, rawAnchorIndex); + // Anti-ban: vary HOW FAR ALONG the route we click. Selection otherwise always returns the + // furthest candidate inside a fixed radius, so every click covers the same tile span — a + // deterministic signature. Varying the reach is the safe axis: it only changes how far + // forward we pick, never sideways, so the target stays on the planned route (#20). Lateral + // tile offsets are the wrong axis and were removed for exactly that reason (#15); lateral + // randomness belongs inside the tile (click-point jitter), not in tile selection. + int jitteredReach = routeClickReach(maxEuclidean); + WorldPoint selected = selectRouteClickTargetAnchored(rawPath, playerLoc, jitteredReach, rawAnchorIndex); + if (selected == null && jitteredReach < maxEuclidean) { + // A shortened reach must never be the reason selection fails — that would drop the click + // onto the caller's off-route wall-nudge clamp. Retry at full reach before giving up. + selected = selectRouteClickTargetAnchored(rawPath, playerLoc, maxEuclidean, rawAnchorIndex); + } if (selected == null && rawAnchorIndex >= 0) { // The smoothed->raw anchor can point past the player's vicinity (stale mapping, sparse // smoothing, or a replanned route). The anchored forward scan then breaks immediately on @@ -3014,6 +3033,23 @@ private static WorldPoint selectRouteClickTarget(List rawPath, World return selected; } + /** + * Per-click route reach, jittered below {@code maxEuclidean} so consecutive clicks do not all + * cover the same tile span. + *

    + * The floor matters: it must stay clear of {@link #INTERIM_CLOSE_TILES} or the interim + * checkpoint clears almost immediately and the walker re-clicks constantly, producing visible + * stop-start movement. The ceiling is the caller's reach, which is already tuned to the minimap + * clip — going above it just produces outside-clip fallbacks. + */ + static int routeClickReach(int maxEuclidean) { + int floor = Math.min(ROUTE_CLICK_REACH_MIN_TILES, maxEuclidean); + if (maxEuclidean <= floor) { + return maxEuclidean; + } + return Rs2Random.betweenInclusive(floor, maxEuclidean); + } + private static WorldPoint selectRouteClickTargetAnchored(List rawPath, WorldPoint playerLoc, int maxEuclidean, int rawAnchorIndex) { // Click the furthest forward point ON THE RAW ROUTE that is within minimap reach. diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index 79fd55200d..96b4db62c5 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -488,6 +488,35 @@ public void rawPathScan_staleAnchorPastPlayerYieldsNothingForEveryPredicate() { Rs2Walker.findFurthestRawPathPointMatching(raw, player, 10, 38, wp -> true)); } + /** + * Anti-ban: consecutive clicks must not all cover the same tile span, but the jittered reach has + * hard bounds. Too short and the click lands inside the interim-close threshold, clearing the + * checkpoint immediately and causing click thrash; too long and it falls outside the minimap + * clip. Varying reach is the safe axis because it only changes how far ALONG the route we click, + * never sideways — lateral tile offsets leave the route and were removed for that reason. + */ + @Test + public void routeClickReach_staysWithinSafeBandAndActuallyVaries() { + int max = 10; + java.util.Set seen = new HashSet<>(); + for (int i = 0; i < 400; i++) { + int reach = Rs2Walker.routeClickReach(max); + assertTrue("reach must never exceed the caller's minimap reach, got " + reach, reach <= max); + assertTrue("reach must stay clear of the interim-close threshold, got " + reach, reach >= 7); + seen.add(reach); + } + assertTrue("reach must actually vary between clicks, saw only " + seen, seen.size() > 1); + } + + /** A caller reach at or below the floor must be returned unchanged rather than inverted. */ + @Test + public void routeClickReach_degenerateBoundsAreSafe() { + for (int max : new int[]{0, 1, 5, 7}) { + int reach = Rs2Walker.routeClickReach(max); + assertEquals("a reach at/below the floor must pass through unchanged", max, reach); + } + } + /** * Off-path recovery must be able to step BACKWARD onto the route. When the player is pushed off * the path (e.g. stuck flush against a castle wall) and nothing ahead is reachable, the rejoin From 95e68a020422a465272565011de53fcb8c404ad2 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 19:18:20 +0100 Subject: [PATCH 36/48] Apply route click reach jitter on the player-anchored retry too The player-anchored retry ran at full reach, bypassing the jitter. That retry fires on most first clicks of a route (sel=route@player), so in practice the variation was skipped exactly where it is most visible: measured first-click distances clustered at 9.0-10.0 rather than spreading across the 7-10 band. Use the jittered reach there as well, keeping the full-reach fallback so a shortened reach still cannot be the reason selection returns null. Co-Authored-By: Claude Opus 4.8 --- .../client/plugins/microbot/util/walker/Rs2Walker.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 41aad99c32..ce6ef2df33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -3025,7 +3025,13 @@ private static WorldPoint selectRouteClickTarget(List rawPath, World // the Euclidean bound and yields nothing for EVERY predicate — which is exactly the // sel=none case that dropped route clicks onto the off-route wall-nudge clamp. Retry // anchored at the player's own closest raw tile before giving up. - selected = selectRouteClickTargetAnchored(rawPath, playerLoc, maxEuclidean, -1); + // Keep the jitter on this path too. The player-anchored retry fires on most first clicks + // of a route, so using full reach here bypassed the reach variation exactly where it is + // most visible — measured click distances clustered at 9.0-10.0 instead of spreading. + selected = selectRouteClickTargetAnchored(rawPath, playerLoc, jitteredReach, -1); + if (selected == null && jitteredReach < maxEuclidean) { + selected = selectRouteClickTargetAnchored(rawPath, playerLoc, maxEuclidean, -1); + } if (selected != null) { lastRouteClickTier = lastRouteClickTier + "@player"; } From d7bef88806059b742d6aa68483f62e6b8a57e7e1 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 19:58:26 +0100 Subject: [PATCH 37/48] Correct Rs2PathApi migration status: Stage 3 is done The class javadoc still said no consumers had been switched over yet and that this was still pending as Stage 3, but Stage 3 completed three commits later in this same branch (eb0e274d43 leaf consumers, 6ee086b835 walker-package helpers, e6e7f0c1fc Rs2Walker). A reviewer opening the facade was told the migration had not happened when it had. Records the end state instead, plus the grep that verifies it: the only remaining ShortestPathPlugin static references under microbot/util/ are the delegations in this class, which is the invariant that confines an upstream backport to this one file. Doc only; no behaviour change. Co-Authored-By: Claude Opus 4.8 --- .../plugins/microbot/util/walker/Rs2PathApi.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java index bd39058ff2..c22ee17ba0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2PathApi.java @@ -33,10 +33,14 @@ * {@code TransportType}, {@code WorldPointUtil}) are treated as the stable Microbot-facing path API * and are deliberately not re-wrapped — they are pure data / pure functions.

    * - *

    Migration status. No consumers have been switched over yet; that is Stage 3, done one - * package at a time with the walker last. Until then {@link ShortestPathPlugin}'s members remain - * public and binary-compatible. Do not add logic here — if a call needs new behaviour, put it - * behind the plugin and expose it through a matching delegate.

    + *

    Migration status. Stage 3 is complete: every consumer under {@code microbot/util/} now + * routes through this facade, so the only remaining references to {@link ShortestPathPlugin}'s + * static members outside the {@code shortestpath} package are the delegations below. That invariant + * is greppable, and is what keeps the blast radius of an upstream backport confined to this class: + *

    grep -rn "ShortestPathPlugin\." microbot/util/   # expect hits in Rs2PathApi only
    + * {@link ShortestPathPlugin}'s members remain public and binary-compatible for out-of-tree callers. + * Do not add logic here — if a call needs new behaviour, put it behind the plugin and expose it + * through a matching delegate.

    */ public final class Rs2PathApi { From 89c5df926975aeda425e0e8d68726a9d61250b87 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 20:36:33 +0100 Subject: [PATCH 38/48] Do not spend partial retries on iterations that made progress A walk to an underground goal reported UNREACHABLE while it was still advancing. Two defects combined. partialPath is recomputed every iteration as "path end is further than distance from the goal". The pathfinder stopped 31 tiles short of (3087,9720), so it was true from the first snapshot onward and the retry budget was armed for the whole walk rather than for a stuck stretch. The path loop also exits for good reasons. Opening a door ends the iteration and lands in the same branch as a failure to move, so it spent a retry. Observed: retry 1 at the end of the first segment, ~100 tiles and 46 seconds of successful walking, then retries 2 and 3 within one second of a single door open - the second without the player moving at all. It gave up on the surface having never reached the ladder. Refill the budget when route progress advanced since the last charge, and exempt exit reasons that denote work done (door/transport/blocker handled, movement in flight). The exemption is deliberately narrow: not-near-path, click-failed-off-minimap and the waiting/retry states still consume it, so a genuinely unreachable goal still terminates. Also stop passing placeholders to recordUnreachable. pathEndpoint was the player's location and pathSize a literal 0, so the log read as "pathfinder returned an empty path at your feet" and endpointToTarget became a surface-to-underground y delta (6346) instead of the real 31-tile shortfall. Underground is the same plane at y+6400, so WorldPoint.distanceTo does not bail out across that boundary - it just returns a meaningless number. movement.md #25 and #26 record both. Tests: :client:runUnitTests green, 1113 tests, 0 failures. Guardrail reports 961 known violations, no regressions - baseline unchanged. Co-Authored-By: Claude Opus 4.8 --- docs/entity-guides/movement.md | 28 +++++++++ .../microbot/util/walker/Rs2Walker.java | 62 ++++++++++++++++++- .../util/walker/Rs2WalkerUnitTest.java | 53 ++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) diff --git a/docs/entity-guides/movement.md b/docs/entity-guides/movement.md index 5b3e4436a5..fef8aa3983 100644 --- a/docs/entity-guides/movement.md +++ b/docs/entity-guides/movement.md @@ -555,3 +555,31 @@ if (selected == null && jitteredReach < maxEuclidean) { **Where this applies:** `Rs2Walker.routeClickReach`, `Rs2Walker.selectRouteClickTarget`, and any future click-target randomisation. **Defensive check:** Unit-test that the jittered reach never exceeds the caller's reach, never drops to the interim-close threshold, actually varies across calls, and passes a degenerate reach through unchanged. + +## 25. Never charge a retry budget for an iteration that made progress + +A "give up after N attempts" counter must count *failures to advance*, not loop iterations. Two things break it otherwise. + +First, **a partial path is a persistent condition, not an event.** `partialPath` is recomputed every iteration as "the path end is further than `distance` from the goal", so any goal the pathfinder cannot fully reach — a tile short of an underground destination, a gated area, a dynamic-region target — makes it true from the first snapshot to the last. The budget is then armed for the entire walk rather than for a stuck stretch. + +Second, **the path loop exits for good reasons too.** Opening a door, taking a transport, clearing a rockfall, or having movement already in flight all end the iteration and land in the same branch as "we failed to move". Charging those spends the budget while the walker is doing exactly what it should. + +Together they are quietly fatal on long multi-leg routes. Observed: a walk to an underground goal whose path end sat 31 tiles short burned retry 1 at the end of the first segment, walked ~100 tiles over 46 seconds, then spent retries 2 and 3 within one second of opening a single door — the second without the player moving at all. It reported `UNREACHABLE` standing at the entrance, having never reached the ladder. Nothing in the log said "stuck", because it never was. + +So: refill the budget when route progress has advanced since the last charge, and exempt exit reasons that denote work done. Keep the exemption **narrow** — reasons meaning the walker failed to advance (`not-near-path`, `click-failed-off-minimap`, waiting/retry states) must still consume it, or a genuinely unreachable goal never terminates and instead spins until the outer tail cap trips. + +**Where this applies:** `Rs2Walker.processWalk` partial-retry branch, `Rs2Walker.isRouteProgressExit`, and any future attempt-capped recovery loop. + +**Defensive check:** Unit-test both directions of the classifier — every progress reason exempt, every stuck reason still charged, `null` treated as not-progress. + +## 26. Telemetry must report measurements, not placeholders + +`recordUnreachable` was called with the player's location as `pathEndpoint` and a literal `0` as `pathSize`. The emitted line read as *"the pathfinder returned an empty path ending at your feet"* — a completely different and much scarier failure than the real one, and it sent diagnosis after a phantom pathfinder bug. + +It also corrupted the derived field. `endpointToTarget` is computed from `pathEndpoint`, so instead of the true 31-tile shortfall it printed `6346`: the raw y-delta between a surface tile and an underground one. Both are plane 0 — underground is the same plane at `y + 6400` — so `WorldPoint.distanceTo` does not bail out, it just returns a meaningless number. Any distance compared across that boundary is nonsense, and any threshold against it can never be met. + +Pass the real endpoint and the real size. If a value is genuinely unavailable, log it as absent rather than substituting a plausible-looking stand-in. + +**Where this applies:** `Rs2Walker.Telemetry.*`, `WebWalkLog`, and any diagnostic that derives a field from an argument. + +**Defensive check:** When a log line drives a diagnosis, confirm at the call site that each value is measured rather than hardcoded before trusting it. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index ce6ef2df33..99cfd7aac0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -635,6 +635,41 @@ private static boolean shouldCanvasNudgeAfterDoorLikeExit(String exitReason) { || "post-click-raw-path-scene-object-handled".equals(exitReason); } + /** + * Exit reasons meaning the path loop ended because the walker did something that + * advances the route — opened a door, took a transport, cleared a blocker — or because + * movement is already in flight. These are progress, not a failed attempt. + * + *

    The partial-retry budget exists for "the goal is unreachable and we are stuck". Spending + * it on these instead conflated the two: a door open ends the iteration, lands in the partial + * branch, and burns a retry even though the walker just made progress. On a route whose path + * end is permanently short of the goal (any partial path), the budget is armed for the whole + * walk, so an ordinary door could exhaust it ~100 tiles into a working route and report + * UNREACHABLE while the player was still advancing. See {@code movement.md} #25. + */ + static boolean isRouteProgressExit(String exitReason) { + if (exitReason == null) { + return false; + } + if (exitReason.startsWith("door-handled")) { + return true; + } + switch (exitReason) { + case "raw-path-scene-object-handled": + case "post-click-raw-path-scene-object-handled": + case "current-tile-transport-handled": + case "post-click-current-tile-transport-handled": + case "transport-handled": + case "rockfall-handled": + case "path-blocker-handled": + case "interim-in-flight": + case "recovery-move-in-flight": + return true; + default: + return false; + } + } + private static void maybeCanvasNudgeAfterDoor(WorldPoint goal, int configuredDistance, List path) { if (goal == null || path == null || path.isEmpty()) { return; @@ -1232,6 +1267,9 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part return WalkerState.EXIT; } int partialRetriesWorking = partialRetries; + // When the last partial retry was spent, so route progress made after it can refill the + // budget. Without this the counter is monotonic for the entire walk. + long lastPartialRetryAtMs = 0L; WorldPoint lastAttemptedMinimapClick = null; boolean lastAttemptedMinimapClickOk = false; long lastAttemptedMinimapClickAtMs = 0L; @@ -2443,7 +2481,24 @@ && walkFastCanvas(recoverTarget)) { if (walkCancelledDiag(target, "processWalk:partial-path-branch", processWalkTail)) { return WalkerState.EXIT; } + // Route progress since the last retry means the walk is working — refill the budget. + // It otherwise only ever increments, so "3 retries" meant three outer-loop iterations + // for the whole journey rather than three consecutive failures to advance. + if (partialRetriesWorking > 0 && routeProgressAdvancedAtMs > lastPartialRetryAtMs) { + walkerDiag("partial retry budget refilled progressAt=%d lastRetryAt=%d spent=%d", + routeProgressAdvancedAtMs, lastPartialRetryAtMs, partialRetriesWorking); + partialRetriesWorking = 0; + } + // A handled door/transport/blocker ended the iteration because work was done, not + // because the walker is stuck. Still re-route, but do not charge the budget for it. + if (isRouteProgressExit(exitReason)) { + walkerDiag("partial retry exempt exitReason=%s tail=%d spent=%d", + exitReason, processWalkTail, partialRetriesWorking); + recalculatePath(); + continue; + } if (partialRetriesWorking < 3) { + lastPartialRetryAtMs = System.currentTimeMillis(); Telemetry.recordPartialRetry(partialRetriesWorking + 1, finalDist); WebWalkLog.partialRetry(finalDist, partialRetriesWorking + 1, 3); recalculatePath(); @@ -2451,8 +2506,13 @@ && walkFastCanvas(recoverTarget)) { continue; } WebWalkLog.partialExhausted(finalDist); + // Report the real path endpoint and size. These were previously hardcoded to the + // player's location and 0, so the log read as "pathfinder returned an empty path at + // your feet" — and endpointToTarget became a surface-to-underground y delta rather + // than the actual shortfall. + WorldPoint unreachableEndpoint = path.isEmpty() ? null : path.get(path.size() - 1); Telemetry.recordUnreachable("partial-retries-exhausted", Rs2Player.getWorldLocation(), - target, Rs2Player.getWorldLocation(), 0, distance, Rs2PathApi.getPathfinder()); + target, unreachableEndpoint, path.size(), distance, Rs2PathApi.getPathfinder()); setTarget(null, "rs2walker:processWalk:partial-retries-exhausted"); return WalkerState.UNREACHABLE; } else { diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index 96b4db62c5..63f7ed82ec 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -517,6 +517,59 @@ public void routeClickReach_degenerateBoundsAreSafe() { } } + /** + * A handled door/transport/blocker must NOT be charged against the partial-retry budget. + * + *

    Regression for a walk to an underground goal that reported UNREACHABLE while still + * advancing. The path end sat 31 tiles short of the goal, so {@code partialPath} was true on + * every iteration and the budget was armed for the whole walk. Opening one door ended the + * iteration, landed in the partial branch and spent a retry; the next iteration spent the last + * one a second later without the player ever walking. Three retries were gone ~100 tiles into a + * route that was working, and the walker gave up on the surface having never reached the ladder. + */ + @Test + public void routeProgressExits_areNotChargedAgainstThePartialRetryBudget() { + for (String progress : new String[]{ + "door-handled", + "door-handled-local-reachability", + "door-handled-during-interim", + "door-handled-before-minimap-click", + "transport-handled", + "current-tile-transport-handled", + "post-click-current-tile-transport-handled", + "raw-path-scene-object-handled", + "post-click-raw-path-scene-object-handled", + "rockfall-handled", + "path-blocker-handled", + "interim-in-flight", + "recovery-move-in-flight"}) { + assertTrue("'" + progress + "' means the walker advanced the route, so it must not spend " + + "a partial retry", Rs2Walker.isRouteProgressExit(progress)); + } + } + + /** + * The exemption must stay narrow: reasons that mean the walker failed to advance still have to + * consume the budget, otherwise a genuinely unreachable goal never terminates and the walk spins + * until the outer tail cap trips. + */ + @Test + public void nonProgressExits_stillConsumeThePartialRetryBudget() { + for (String stuck : new String[]{ + "end-of-path", + "not-near-path", + "player-location-null", + "click-failed-off-minimap", + "door-edge-waiting-retry", + "door-edge-nearby-waiting-retry", + "door-recovery-suppressed", + "local-reachability-miss-no-click", + null}) { + assertFalse("'" + stuck + "' is not route progress and must still spend a retry", + Rs2Walker.isRouteProgressExit(stuck)); + } + } + /** * Off-path recovery must be able to step BACKWARD onto the route. When the player is pushed off * the path (e.g. stuck flush against a castle wall) and nothing ahead is reachable, the rejoin From 6b8d9cad3174b23252294a2f5984c64a20e82f51 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 20:44:42 +0100 Subject: [PATCH 39/48] Require movement, not just a route change, to refill partial retries The refill condition used routeProgressAdvancedAtMs alone. That field is also bumped by stabilizeRouteProgressIndex whenever the route is merely REPLACED (path size or endpoints differ), and every partial retry calls recalculatePath() - so a retry could refill the budget it had just spent. The path stabilises once the walker is truly stuck, so it still terminated, but only after extra iterations, and a route that flapped between two shapes on successive recalcs could have kept refilling until the 64-iteration tail cap. Also require the player to be standing somewhere new since the last retry. When a target is genuinely unreachable the player stops moving, so movement is the signal that separates "advancing" from "stuck" - which is what lets the budget drain and report UNREACHABLE. Found while probing a walk whose goal (3087,9720) is blocked in the collision map, with 0 walkable tiles within 6. The pathfinder correctly stopped at (3056,9720), the last walkable tile before the rock face. Tests: :client:runUnitTests green, 1113 tests, 0 failures. Guardrail 961 known violations, no regressions. Co-Authored-By: Claude Opus 4.8 --- .../microbot/util/walker/Rs2Walker.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 99cfd7aac0..342624de72 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -1270,6 +1270,7 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part // When the last partial retry was spent, so route progress made after it can refill the // budget. Without this the counter is monotonic for the entire walk. long lastPartialRetryAtMs = 0L; + WorldPoint lastPartialRetryAtLoc = null; WorldPoint lastAttemptedMinimapClick = null; boolean lastAttemptedMinimapClickOk = false; long lastAttemptedMinimapClickAtMs = 0L; @@ -2484,9 +2485,20 @@ && walkFastCanvas(recoverTarget)) { // Route progress since the last retry means the walk is working — refill the budget. // It otherwise only ever increments, so "3 retries" meant three outer-loop iterations // for the whole journey rather than three consecutive failures to advance. - if (partialRetriesWorking > 0 && routeProgressAdvancedAtMs > lastPartialRetryAtMs) { - walkerDiag("partial retry budget refilled progressAt=%d lastRetryAt=%d spent=%d", - routeProgressAdvancedAtMs, lastPartialRetryAtMs, partialRetriesWorking); + // + // Standing somewhere new is required as well as the progress timestamp: + // routeProgressAdvancedAtMs is also bumped whenever the route is merely REPLACED, and + // each retry calls recalculatePath(), so the timestamp alone would let a retry refill + // the budget it just spent. When the target is genuinely unreachable the player stops + // moving, so requiring movement is what still lets the budget drain and terminate. + WorldPoint retryLoc = Rs2Player.getWorldLocation(); + boolean movedSinceLastRetry = lastPartialRetryAtLoc == null + || (retryLoc != null && !retryLoc.equals(lastPartialRetryAtLoc)); + if (partialRetriesWorking > 0 + && movedSinceLastRetry + && routeProgressAdvancedAtMs > lastPartialRetryAtMs) { + walkerDiag("partial retry budget refilled progressAt=%d lastRetryAt=%d spent=%d at=%s", + routeProgressAdvancedAtMs, lastPartialRetryAtMs, partialRetriesWorking, retryLoc); partialRetriesWorking = 0; } // A handled door/transport/blocker ended the iteration because work was done, not @@ -2499,6 +2511,7 @@ && walkFastCanvas(recoverTarget)) { } if (partialRetriesWorking < 3) { lastPartialRetryAtMs = System.currentTimeMillis(); + lastPartialRetryAtLoc = retryLoc; Telemetry.recordPartialRetry(partialRetriesWorking + 1, finalDist); WebWalkLog.partialRetry(finalDist, partialRetriesWorking + 1, 3); recalculatePath(); From d16e9d1e2045d334dddb944981722045093487bb Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 20:51:25 +0100 Subject: [PATCH 40/48] Reject walk targets that are not walkable terrain, before routing A walk to (3087,9720) - inside the rock east of the Dwarven Mine, with zero walkable tiles within 6 - spent ~80s covering 100+ tiles from Draynor, went underground, stopped at (3056,9720) which is the last walkable tile before the rock face, and then reported partial-retries-exhausted. The pathfinder was right; a path request from (3056,9720) to the goal returns size 1, meaning you cannot leave that tile toward the target. Only the diagnosis was wrong: the failure read as a walker fault rather than a bad destination coordinate. The intended target was the Motherlode cave mouth at (3060,9766). processWalk now checks the collision map for any walkable tile within the arrival distance and returns UNREACHABLE immediately with cause target-not-walkable, naming the nearest walkable tile so the coordinate can be corrected. The guard is deliberately permissive. An unmapped region reads as fully blocked, because SplitFlagMap.get returns false for one and CollisionMap.isBlocked negates all four directions - so a naive check would reject every instance and every region absent from the collision map. Adds SplitFlagMap.hasRegion and a CollisionMap delegate, and every ambiguous case (no map, unmapped target, unmapped tile in the search box) returns walkable and lets the pathfinder decide. Only mapped, wholly blocked terrain is rejected. Tests: 5 new cases against the real collision map, covering the buried coordinate, the cave mouth and last-walkable tile still being accepted, unmapped regions never being rejected, and a generous arrival distance reaching real ground. Suite green, 1118 tests, 0 failures. Guardrail 961 known violations, no regressions. Co-Authored-By: Claude Opus 4.8 --- .../shortestpath/pathfinder/CollisionMap.java | 13 +++ .../shortestpath/pathfinder/SplitFlagMap.java | 14 +++ .../microbot/util/walker/Rs2Walker.java | 75 ++++++++++++++++ .../TargetWalkabilityPreflightTest.java | 89 +++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java index cee0e1570e..f5365853f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java @@ -67,6 +67,19 @@ public boolean isBlocked(int x, int y, int z) { return !n(x, y, z) && !s(x, y, z) && !e(x, y, z) && !w(x, y, z); } + /** + * Whether collision data exists for the region containing {@code (x, y)}. + * + *

    Required to interpret {@link #isBlocked}: an unmapped region reads as fully + * blocked, because {@link SplitFlagMap#get} returns {@code false} for one and {@code isBlocked} + * negates all four directions. Gate on this before treating blocked as unreachable. + * + * @see SplitFlagMap#hasRegion(int, int) + */ + public boolean hasRegion(int x, int y) { + return collisionData.hasRegion(x, y); + } + /** * Single walking step permission check from (x,y,z) in direction (dx,dy). * Used by {@link PathSmoother}. Graph expansion uses {@link #fillTraversableLegacy} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java index c15ce436d6..8afa384bf0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java @@ -69,6 +69,20 @@ public boolean get(int x, int y, int z, int flag) { return regionMaps[index].get(x, y, z, flag); } + /** + * Whether collision data was actually loaded for the region containing {@code (x, y)}. + * + *

    Callers need this to tell "known to be blocked" apart from "no data". {@link #get} returns + * {@code false} for an unloaded region, and {@code CollisionMap.isBlocked} is the conjunction of + * four negated {@link #get} calls, so an unmapped region reads as fully blocked. Any + * check that treats blocked as unreachable must gate on this first, or it will reject every + * target in an instance or in a region missing from the collision map. + */ + public boolean hasRegion(int x, int y) { + final int index = getIndex(x / REGION_SIZE, y / REGION_SIZE); + return index >= 0 && index < regionMaps.length && regionMaps[index] != null; + } + private int getIndex(int regionX, int regionY) { return (regionX - regionExtents.getMinX()) + (regionY - regionExtents.getMinY()) * widthInclusive; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 342624de72..fc0dda2768 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -19,6 +19,7 @@ import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.globval.enums.InterfaceTab; import net.runelite.client.plugins.microbot.shortestpath.*; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; @@ -623,6 +624,65 @@ private static void waitUntilIdleAfterSceneWalk(WorldPoint cancelGoal, int timeo } } + /** + * Whether any tile within {@code distance} of {@code target} is walkable in the collision map. + * + *

    Pre-flight guard so a destination that does not exist as walkable terrain fails + * immediately instead of after a full route. A walk to {@code (3087,9720)} — inside the rock + * east of the Dwarven Mine, with 0 walkable tiles within 6 — spent ~80s covering 100+ tiles to + * the nearest reachable tile and then reported {@code partial-retries-exhausted}, which reads + * as a walker fault rather than a bad coordinate. + * + *

    Permissive by design. An unmapped region reads as fully blocked (see + * {@link CollisionMap#hasRegion}), so every ambiguous case returns {@code true} and lets the + * pathfinder decide. Only a target sitting in mapped, wholly blocked terrain is rejected — + * otherwise this would refuse instances and any region missing from the collision map. + */ + static boolean hasWalkableTileWithin(CollisionMap map, WorldPoint target, int distance) { + if (map == null || target == null) { + return true; + } + if (!map.hasRegion(target.getX(), target.getY())) { + return true; + } + int radius = Math.max(0, distance); + for (int dx = -radius; dx <= radius; dx++) { + for (int dy = -radius; dy <= radius; dy++) { + int x = target.getX() + dx; + int y = target.getY() + dy; + if (!map.hasRegion(x, y)) { + return true; + } + if (!map.isBlocked(x, y, target.getPlane())) { + return true; + } + } + } + return false; + } + + /** Nearest walkable tile to {@code target} within {@code maxRadius}, or null. Diagnostics only. */ + static WorldPoint nearestWalkableTile(CollisionMap map, WorldPoint target, int maxRadius) { + if (map == null || target == null) { + return null; + } + for (int r = 1; r <= maxRadius; r++) { + for (int dx = -r; dx <= r; dx++) { + for (int dy = -r; dy <= r; dy++) { + if (Math.max(Math.abs(dx), Math.abs(dy)) != r) { + continue; // ring only; inner rings already scanned + } + int x = target.getX() + dx; + int y = target.getY() + dy; + if (map.hasRegion(x, y) && !map.isBlocked(x, y, target.getPlane())) { + return new WorldPoint(x, y, target.getPlane()); + } + } + } + } + return null; + } + /** Door / gate from main path loop vs {@link #handleNearbyRawPathSceneObjects} raw-path scan (same nudge UX). */ private static boolean shouldCanvasNudgeAfterDoorLikeExit(String exitReason) { if (exitReason == null) { @@ -1266,6 +1326,21 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part if (debug) { return WalkerState.EXIT; } + // Pre-flight: a destination with no walkable tile within the arrival distance can never be + // reached, so reject it here rather than after a full route ending at the nearest wall. + PathfinderConfig preflightConfig = Rs2PathApi.getPathfinderConfig(); + CollisionMap preflightMap = preflightConfig != null ? preflightConfig.getMap() : null; + if (!hasWalkableTileWithin(preflightMap, target, distance)) { + WorldPoint nearestWalkable = nearestWalkableTile(preflightMap, target, 48); + log.warn("[Walker] walk rejected: target {} has no walkable tile within {} in the collision map" + + " (nearest walkable {}); check the destination coordinate", + target, distance, + nearestWalkable != null ? nearestWalkable : "none within 48"); + Telemetry.recordUnreachable("target-not-walkable", Rs2Player.getWorldLocation(), + target, nearestWalkable, 0, distance, null); + setTarget(null, "rs2walker:processWalk:target-not-walkable"); + return WalkerState.UNREACHABLE; + } int partialRetriesWorking = partialRetries; // When the last partial retry was spent, so route progress made after it can refill the // budget. Without this the counter is monotonic for the entire walk. diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java new file mode 100644 index 0000000000..7e813a0383 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java @@ -0,0 +1,89 @@ +package net.runelite.client.plugins.microbot.util.walker; + +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Pre-flight rejection of destinations that are not walkable terrain. + * + *

    Regression for a walk that spent ~80s and 100+ tiles routing from Draynor to the Dwarven Mine + * before reporting {@code partial-retries-exhausted}. The goal {@code (3087,9720)} is inside the + * rock east of the mine: blocked, with zero walkable tiles within 6. The pathfinder was correct — + * it stopped at {@code (3056,9720)}, the last walkable tile before the rock face — but the failure + * read as a walker fault rather than a bad coordinate. The intended destination was the Motherlode + * cave mouth at {@code (3060,9766)}. + */ +public class TargetWalkabilityPreflightTest { + + private static CollisionMap map; + + /** Inside the rock east of the Dwarven Mine — the coordinate that produced the bad walk. */ + private static final WorldPoint BURIED_IN_ROCK = new WorldPoint(3087, 9720, 0); + /** Last walkable tile the pathfinder could actually reach along that corridor. */ + private static final WorldPoint LAST_WALKABLE = new WorldPoint(3056, 9720, 0); + /** The real Motherlode Mine entrance ("Enter;Cave;26654" in transports.tsv). */ + private static final WorldPoint MLM_CAVE_MOUTH = new WorldPoint(3060, 9766, 0); + + @BeforeClass + public static void load() { + map = new CollisionMap(SplitFlagMap.fromResources()); + } + + @Test + public void aTargetBuriedInRockIsRejected() { + assertTrue("precondition: the region must be mapped, or the guard correctly abstains", + map.hasRegion(BURIED_IN_ROCK.getX(), BURIED_IN_ROCK.getY())); + assertTrue("precondition: the tile itself is blocked", + map.isBlocked(BURIED_IN_ROCK.getX(), BURIED_IN_ROCK.getY(), 0)); + assertFalse("a goal with no walkable tile within the arrival distance must be rejected " + + "before the walk starts", + Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 5)); + } + + @Test + public void legitimateUndergroundTargetsAreAccepted() { + assertTrue("the last walkable tile in the corridor must still be accepted", + Rs2Walker.hasWalkableTileWithin(map, LAST_WALKABLE, 5)); + assertTrue("the Motherlode cave mouth is a valid destination and must not be rejected", + Rs2Walker.hasWalkableTileWithin(map, MLM_CAVE_MOUTH, 5)); + } + + /** + * The guard must abstain wherever it lacks data. An unmapped region reads as fully blocked, so + * a naive check would reject every instance and every region absent from the collision map. + */ + @Test + public void unmappedRegionsAreNeverRejected() { + WorldPoint offMap = new WorldPoint(0, 0, 0); + assertFalse("precondition: this region genuinely has no collision data", + map.hasRegion(offMap.getX(), offMap.getY())); + assertTrue("no collision data must mean 'let the pathfinder try', not 'unreachable'", + Rs2Walker.hasWalkableTileWithin(map, offMap, 5)); + assertTrue("a null map must never block a walk", + Rs2Walker.hasWalkableTileWithin(null, BURIED_IN_ROCK, 5)); + } + + /** A generous arrival distance reaches real ground, so the same goal becomes acceptable. */ + @Test + public void aLargeArrivalDistanceReachesWalkableGround() { + assertFalse(Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 5)); + assertTrue("with a 40 tile tolerance the corridor is inside the search box", + Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 40)); + } + + @Test + public void theRejectionPointsAtTheNearestRealTile() { + WorldPoint nearest = Rs2Walker.nearestWalkableTile(map, BURIED_IN_ROCK, 48); + assertNotNull("the warning must name a concrete tile so the coordinate can be corrected", + nearest); + assertFalse("the suggested tile must itself be walkable", + map.isBlocked(nearest.getX(), nearest.getY(), 0)); + } +} From e865551672223ee7a71b42a83e37e104f8a186d7 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 21:49:25 +0100 Subject: [PATCH 41/48] Gate rockfall handling on the rockfall, not on the walk target handleRockfall required BOTH the player and currentTarget to be in region 14936, so any walk leaving the Motherlode Mine bailed before inspecting anything. Observed live at=(3751,5672) goal=(3040,9810): the goal is region 12185, so no outbound route could mine through a rockfall standing directly in its path. Approaching the mine from outside was equally dead, since the player is not in 14936 yet. Rockfalls only exist in the Motherlode Mine, so a region gate is right - it just has to test where the rockfall could BE (the player's tile, or the path tiles about to be inspected), never where the walk ends. Extracted as isMotherlodeRockfallCandidate so both directions are testable without a client. Also defer the pickaxe check until a rockfall is actually found. It ran before any rockfall was located and called setTarget(null), so a route merely passing through the mine without a pickaxe was killed outright. Now only a rockfall genuinely in the way abandons the walk. Note this handler still only fires when a rockfall lies ON the path, and transports.tsv contains no rockfall entries (grep -ic rockfall = 0), while the collision map marks those tiles blocked. So the pathfinder never routes through one and the handler stays dormant. Cataloguing MLM rockfalls as Mine;Rockfall;26679/26680 transports - mirroring the existing Mine;Rock slide;2634 entries - is what will actually exercise it. That needs per-rockfall coordinates from a live session and is tracked separately. Tests: 3 new gate cases (leaving the mine, approaching from outside, closed elsewhere). Suite green, 1121 tests, 0 failures. Guardrail 961 known violations, no regressions. Co-Authored-By: Claude Opus 4.8 --- .../microbot/util/walker/Rs2Walker.java | 52 +++++++++++++++---- .../util/walker/Rs2WalkerUnitTest.java | 48 +++++++++++++++++ 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index fc0dda2768..0851d6b491 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -290,6 +290,8 @@ public static WorldPoint getCurrentTarget() { /** Bounds tail recursion that was previously unbounded {@code processWalk} self-calls. */ private static final int MAX_PROCESS_WALK_TAIL_ITERATIONS = 64; + /** Motherlode Mine — the only region containing {@code MOTHERLODE_ROCKFALL_1/2} obstacles. */ + static final int MOTHERLODE_MINE_REGION = 14936; /** * Verbose walker traces — enable DEBUG logging for {@code net.runelite.client.plugins.microbot}. @@ -4072,6 +4074,33 @@ public static int distanceToRegion(int regionX, int regionY) { return worldPoint.distanceTo(Rs2Player.getWorldLocation()); } + /** + * Whether a rockfall could plausibly sit at {@code path[index]} or {@code path[index + 1]}, used + * to gate the (comparatively expensive) scene lookup in {@link #handleRockfall}. + * + *

    Rockfalls only exist in the Motherlode Mine, so the region check is legitimate — but it must + * test where the rockfall could be: the player's tile, or the path tiles about to be + * inspected. It must never test the walk TARGET. Gating on the target meant a walk out of the + * mine — destination in another region, e.g. the Dwarven Mine at 12185 — returned false before + * looking at anything, so no outbound route could clear a rockfall standing directly in it. + */ + static boolean isMotherlodeRockfallCandidate(WorldPoint playerLoc, List path, int index) { + if (path == null || path.isEmpty() || index < 0 || index >= path.size()) { + return false; + } + if (playerLoc != null && playerLoc.getRegionID() == MOTHERLODE_MINE_REGION) { + return true; + } + int lastCandidate = Math.min(index + 1, path.size() - 1); + for (int i = index; i <= lastCandidate; i++) { + WorldPoint candidate = path.get(i); + if (candidate != null && candidate.getRegionID() == MOTHERLODE_MINE_REGION) { + return true; + } + } + return false; + } + private static boolean handleRockfall(List path, int index) { if (Rs2PathApi.getPathfinder() == null) return false; @@ -4080,22 +4109,16 @@ private static boolean handleRockfall(List path, int index) { // If we are in instance, ignore checking RegionID if(Microbot.getClient().getTopLevelWorldView().isInstance()) return false; - // If we are not inside of the Motherloade mine, ignore the following logic WorldPoint playerLoc = Rs2Player.getWorldLocation(); - if (playerLoc == null || playerLoc.getRegionID() != 14936 || currentTarget == null || currentTarget.getRegionID() != 14936) return false; + if (playerLoc == null) return false; - // We kill the path if no pickaxe is found to avoid walking around like an idiot - if (!Rs2Inventory.hasItem("pickaxe")) { - if (!Rs2Equipment.isWearing("pickaxe")) { - log.error("Unable to find pickaxe to mine rockfall"); - setTarget(null, "rs2walker:motherlode-rockfall-no-pickaxe"); - return false; - } - } + final int lastCandidate = Math.min(index + 1, path.size() - 1); + if (!isMotherlodeRockfallCandidate(playerLoc, path, index)) return false; // Check current index & next index for rockfall - for (int rockIndex = index; rockIndex < index + 2; rockIndex++) { + for (int rockIndex = index; rockIndex <= lastCandidate; rockIndex++) { var point = path.get(rockIndex); + if (point == null || point.getRegionID() != MOTHERLODE_MINE_REGION) continue; TileObject object = null; var tile = Rs2GameObject.getTiles(3).stream() @@ -4108,6 +4131,13 @@ private static boolean handleRockfall(List path, int index) { if (object == null) continue; if (object.getId() == ObjectID.MOTHERLODE_ROCKFALL_1 || object.getId() == ObjectID.MOTHERLODE_ROCKFALL_2) { + // Only abandon the walk once a rockfall is actually in the way. Checking for a + // pickaxe up front killed any route merely passing through the mine. + if (!Rs2Inventory.hasItem("pickaxe") && !Rs2Equipment.isWearing("pickaxe")) { + log.error("Unable to find pickaxe to mine rockfall at {}", point); + setTarget(null, "rs2walker:motherlode-rockfall-no-pickaxe"); + return false; + } Rs2GameObject.interact(object, "mine"); return sleepUntil(() -> Rs2GameObject.getGameObject(point) == null); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java index 63f7ed82ec..69f2f8db07 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; @@ -517,6 +518,53 @@ public void routeClickReach_degenerateBoundsAreSafe() { } } + /** + * Leaving the Motherlode Mine must still be able to clear a rockfall standing in the path. + * + *

    The gate used to require the walk TARGET to be in region 14936, so a walk from inside the + * mine to the Dwarven Mine (region 12185) bailed before inspecting anything. Observed live: + * {@code at=(3751,5672) goal=(3040,9810)} — every outbound route was unable to mine through. + */ + @Test + public void rockfallGateAllowsWalksLeavingTheMotherlodeMine() { + WorldPoint insideMlm = new WorldPoint(3751, 5672, 0); + WorldPoint dwarvenMineGoal = new WorldPoint(3040, 9810, 0); + + assertEquals("precondition: this tile is the Motherlode Mine region", + Rs2Walker.MOTHERLODE_MINE_REGION, insideMlm.getRegionID()); + assertNotEquals("precondition: the outbound goal is in a different region — this is exactly " + + "what the old target-based gate rejected", + Rs2Walker.MOTHERLODE_MINE_REGION, dwarvenMineGoal.getRegionID()); + + List path = Arrays.asList(insideMlm, new WorldPoint(3750, 5672, 0), dwarvenMineGoal); + assertTrue("standing in the mine must qualify regardless of where the walk ends", + Rs2Walker.isMotherlodeRockfallCandidate(insideMlm, path, 0)); + } + + /** A rockfall ahead on the path qualifies even when the player has not entered the mine yet. */ + @Test + public void rockfallGateAllowsApproachingTheMineFromOutside() { + WorldPoint outside = new WorldPoint(3060, 9766, 0); // Dwarven Mine cave mouth + List path = Arrays.asList(outside, new WorldPoint(3728, 5692, 0)); + + assertNotEquals("precondition: the player is not in the mine yet", + Rs2Walker.MOTHERLODE_MINE_REGION, outside.getRegionID()); + assertTrue("a path tile inside the mine must still arm the handler", + Rs2Walker.isMotherlodeRockfallCandidate(outside, path, 0)); + } + + /** The gate must stay closed everywhere else — rockfalls exist only in the Motherlode Mine. */ + @Test + public void rockfallGateStaysClosedAwayFromTheMine() { + WorldPoint varrock = new WorldPoint(3210, 3424, 0); + List path = Arrays.asList(varrock, new WorldPoint(3211, 3424, 0)); + + assertFalse("an unrelated surface walk must not pay for the scene lookup", + Rs2Walker.isMotherlodeRockfallCandidate(varrock, path, 0)); + assertFalse("a null or empty path must never arm the handler", + Rs2Walker.isMotherlodeRockfallCandidate(varrock, null, 0)); + } + /** * A handled door/transport/blocker must NOT be charged against the partial-retry budget. * From 0f91de072fd56c1eabc4e5c83437f71b4ae5e29e Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 21:56:52 +0100 Subject: [PATCH 42/48] Add GET /objects/neighbours for cataloguing between-tile obstacles An obstacle that stands BETWEEN two walkable tiles - Motherlode rockfalls, rubble, rock slides - can only be modelled as a transport if you know both of its open ends, and the object's own position does not give you those. /objects returns position only, so collecting them meant reading coordinates off a screenshot. Reports each match's surrounding tiles with live-scene walkability, plus a "sides" object pairing opposing neighbours on each axis: the axis whose bothWalkable is true is the transport's origin/destination pair. Walkability is read from the live scene collision flags rather than the bundled collision map, which is the point - the bundled map has these obstacles baked in as permanent walls, so it cannot tell you they are passable. Also reports selfWalkable so a cleared obstacle is distinguishable from a standing one. The flag array is read once per request inside a single client-thread call. Rs2Tile.isWalkable hops the client thread per invocation, so the obvious implementation would have cost 8 hops per object. Tests: suite green, 1121 tests, 0 failures. Client-thread guardrail 961 known violations, no regressions. Documented in AGENT_SERVER.md. Co-Authored-By: Claude Opus 4.8 --- docs/AGENT_SERVER.md | 46 ++++++ .../agentserver/handler/ObjectHandler.java | 145 ++++++++++++++++++ 2 files changed, 191 insertions(+) diff --git a/docs/AGENT_SERVER.md b/docs/AGENT_SERVER.md index ca216f344e..44e477993c 100644 --- a/docs/AGENT_SERVER.md +++ b/docs/AGENT_SERVER.md @@ -273,6 +273,52 @@ Body: `{"name": "Banker", "action": "Bank"}` or `{"id": 3010, "action": "Attack" } ``` +#### GET /objects/neighbours + +Same filters as `GET /objects`, plus the walkability of the tiles surrounding each match. Use it to +catalogue obstacles that sit *between* two walkable tiles — Motherlode rockfalls, rubble, rock +slides — where modelling the obstacle as a transport in `transports.tsv` needs both of its open +ends, which the object's own position does not give you. + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `id` / `name` / `nameContains` | - | Same filters as `GET /objects` | +| `maxDistance` | `20` | Max tile distance (scene radius is ~104) | +| `radius` | `1` | Neighbour ring size, clamped to 1-5 | +| `limit` | config max | Max results | + +`sides` pairs opposing neighbours on each axis, so a blocking obstacle's two endpoints can be read +straight off the response. Walkability comes from the **live scene** collision flags, not the +bundled collision map, so it reflects what the player can actually do right now — which is the +point when the bundled map has an obstacle baked in as a permanent wall. + +```bash +curl -s -H "X-Agent-Token: $(cat ~/.runelite/.agent-token)" \ + "http://127.0.0.1:8081/objects/neighbours?id=26679&maxDistance=104&limit=200" +``` + +```json +{ + "count": 1, "total": 1, "radius": 1, + "objects": [ + { + "id": 26679, "name": "Rockfall", "type": "GAME", "reachable": true, + "position": {"x": 3742, "y": 5668, "plane": 0}, + "selfWalkable": false, + "neighbours": [ + {"position": {"x": 3741, "y": 5668, "plane": 0}, "dx": -1, "dy": 0, "walkable": true} + ], + "sides": { + "eastWest": {"a": {"...": "dx=-1"}, "b": {"...": "dx=+1"}, "bothWalkable": true}, + "northSouth": {"a": {"...": "dy=-1"}, "b": {"...": "dy=+1"}, "bothWalkable": false} + } + } + ] +} +``` + +The axis whose `bothWalkable` is `true` gives the transport's origin/destination pair. + #### POST /objects/interact Body: `{"name": "Oak tree", "action": "Chop down"}` diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/agentserver/handler/ObjectHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/agentserver/handler/ObjectHandler.java index e19fb0b08c..664688620a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/agentserver/handler/ObjectHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/agentserver/handler/ObjectHandler.java @@ -36,6 +36,10 @@ protected void handleRequest(HttpExchange exchange) throws IOException { case "/interact": handleInteract(exchange); break; + case "/neighbours": + case "/neighbors": + handleNeighbours(exchange); + break; default: sendJson(exchange, 404, errorResponse("Unknown path: /objects" + sub)); } @@ -133,6 +137,147 @@ private void handleInteract(HttpExchange exchange) throws IOException { sendJson(exchange, 200, response); } + /** + * Like the plain query, but also reports the walkability of the tiles surrounding each match. + * + *

    Exists to catalogue obstacles that sit between two walkable tiles — Motherlode + * rockfalls, rubble, rock slides. Modelling one as a transport needs both sides, which the + * object's own position does not give you. {@code sides} pairs opposing neighbours on each axis + * so a blocking obstacle's two open ends can be read straight off the response. + * + *

    Walkability comes from the live scene collision flags, not the bundled collision + * map, so it reflects what the player can actually do right now. The flag array is read once per + * request rather than per tile, since each {@code Rs2Tile.isWalkable} call hops the client thread. + */ + private void handleNeighbours(HttpExchange exchange) throws IOException { + try { + requireGet(exchange); + } catch (HttpMethodException e) { + sendJson(exchange, 405, errorResponse(e.getMessage())); + return; + } + + Map params = parseQuery(exchange.getRequestURI()); + String name = params.get("name"); + String nameContains = params.get("nameContains"); + int id = getIntParam(params, "id", -1); + int maxDistance = getIntParam(params, "maxDistance", 20); + int limit = getIntParam(params, "limit", defaultLimit); + int radius = Math.max(1, Math.min(5, getIntParam(params, "radius", 1))); + + var query = Microbot.getRs2TileObjectCache().query(); + if (id >= 0) { + query = query.withId(id); + } + if (name != null && !name.isEmpty()) { + query = query.withName(name); + } else if (nameContains != null && !nameContains.isEmpty()) { + query = query.withNameContains(nameContains); + } + query = query.within(maxDistance); + + List objects = query.toListOnClientThread(); + List limited = objects.stream().limit(limit).collect(Collectors.toList()); + + List> serialized = Microbot.getClientThread().runOnClientThreadOptional(() -> { + var wv = Microbot.getClient().getTopLevelWorldView(); + if (wv == null) { + return null; + } + var collisionData = wv.getCollisionMaps(); + int[][] flags = collisionData != null ? collisionData[wv.getPlane()].getFlags() : null; + + List> out = new ArrayList<>(); + for (Rs2TileObjectModel obj : limited) { + Map map = serializeObject(obj); + WorldPoint loc = obj.getWorldLocation(); + if (loc == null) { + out.add(map); + continue; + } + + Map> byOffset = new LinkedHashMap<>(); + List> neighbours = new ArrayList<>(); + for (int dx = -radius; dx <= radius; dx++) { + for (int dy = -radius; dy <= radius; dy++) { + if (dx == 0 && dy == 0) { + continue; + } + WorldPoint p = new WorldPoint(loc.getX() + dx, loc.getY() + dy, loc.getPlane()); + Map entry = new LinkedHashMap<>(); + entry.put("position", positionOf(p)); + entry.put("dx", dx); + entry.put("dy", dy); + entry.put("walkable", isWalkableInScene(wv, flags, p)); + neighbours.add(entry); + byOffset.put(dx + "," + dy, entry); + } + } + map.put("neighbours", neighbours); + + // Opposing pairs on each axis: for an obstacle standing between two open tiles these + // are the transport's two endpoints. + Map sides = new LinkedHashMap<>(); + sides.put("eastWest", axisPair(byOffset, -1, 0, 1, 0)); + sides.put("northSouth", axisPair(byOffset, 0, -1, 0, 1)); + map.put("sides", sides); + + map.put("selfWalkable", isWalkableInScene(wv, flags, loc)); + out.add(map); + } + return out; + }).orElse(null); + + if (serialized == null) { + sendJson(exchange, 503, errorResponse("Scene unavailable (not logged in?)")); + return; + } + + Map response = new LinkedHashMap<>(); + response.put("count", serialized.size()); + response.put("total", objects.size()); + response.put("radius", radius); + response.put("objects", serialized); + sendJson(exchange, 200, response); + } + + private static Map axisPair(Map> byOffset, + int aDx, int aDy, int bDx, int bDy) { + Map a = byOffset.get(aDx + "," + aDy); + Map b = byOffset.get(bDx + "," + bDy); + Map pair = new LinkedHashMap<>(); + pair.put("a", a); + pair.put("b", b); + pair.put("bothWalkable", a != null && b != null + && Boolean.TRUE.equals(a.get("walkable")) && Boolean.TRUE.equals(b.get("walkable"))); + return pair; + } + + private static Map positionOf(WorldPoint p) { + Map position = new LinkedHashMap<>(); + position.put("x", p.getX()); + position.put("y", p.getY()); + position.put("plane", p.getPlane()); + return position; + } + + /** Live-scene walkability; false when the tile is outside the loaded scene. */ + private static boolean isWalkableInScene(net.runelite.api.WorldView wv, int[][] flags, WorldPoint p) { + if (flags == null) { + return false; + } + net.runelite.api.coords.LocalPoint lp = net.runelite.api.coords.LocalPoint.fromWorld(wv, p); + if (lp == null) { + return false; + } + int sx = lp.getSceneX(); + int sy = lp.getSceneY(); + if (sx < 0 || sy < 0 || sx >= flags.length || sy >= flags[sx].length) { + return false; + } + return (flags[sx][sy] & net.runelite.api.CollisionDataFlag.BLOCK_MOVEMENT_FULL) == 0; + } + private Map serializeObject(Rs2TileObjectModel obj) { Map map = new LinkedHashMap<>(); map.put("id", obj.getId()); From f9aef423de0e6778555ffdbf8c39fa708e412e00 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 22:05:57 +0100 Subject: [PATCH 43/48] Catalogue Motherlode Mine rockfalls as transports The bundled collision map bakes rockfalls in as permanent walls. That is correct for upstream, which has no automation to clear them, but it left the mine carved into disconnected pockets: a route from the cave arrival tile (3728,5692) to the WEST_LOWER mining area died 10 tiles short, and walking anywhere inside the mine mostly failed. Rs2Walker.handleRockfall already knew how to mine 26679/26680, but it only fires when a rockfall lies ON the path - and since nothing contradicted the collision map, the pathfinder never routed through one. The handler was effectively dead code. Each rockfall is now a Mine;Rockfall; transport between its two open sides, mirroring the existing Mine;Rock slide;2634 entries. 32 spawn points, 90 rows: 19 are chokepoints where exactly one axis is open, 13 are bypassable and only add an alternative edge. Duration 10 keeps an open corridor preferred over mining when both exist. Positions came from the live scene via GET /objects/neighbours, unioned across 9 samples taken minutes apart - rockfalls respawn, and a single snapshot was already one short. All 32 appeared in every sample, so the set looks complete, though a spot that was cleared for the whole session would not have been seen. A missing rockfall is safe: it just stays a wall, which is today's behaviour. Item requirements use ';' (alternatives) rather than the ' ' separator the existing rock slide row uses. Note this is presentational only: Transport parses the column into Set>, but PathfinderConfig.hasRequiredItems flattens it and calls anyMatch, so either separator behaves as "any one pickaxe". ';' matches the data model's intent and reads correctly. Tests: 4 new offline cases against the real collision map and transport data, incl. the original failure (arrival -> WEST_LOWER, previously 10 tiles short) and a full Draynor -> mining area route. Suite green, 1125 tests, 0 failures. Guardrail 961 known violations, no regressions. Co-Authored-By: Claude Opus 4.8 --- .../microbot/shortestpath/transports.tsv | 93 +++++++++++++++ .../MotherlodeRockfallTransportTest.java | 108 ++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv index 5a6cb7333c..7c64a9c968 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv @@ -6061,3 +6061,96 @@ 3308 3493 0 3308 3491 0 Climb-over;Broken fence;2618 6 2893 3507 0 2893 9907 0 Climb-down;Ladder;17374 1 2893 9907 0 2893 3507 0 Climb-up;Ladder;17387 1 +# Motherlode Mine rockfalls (26679/26680). Mineable obstacles: the bundled collision map bakes +# them in as permanent walls, so without these edges the pathfinder cannot route through the mine. +# Rs2Walker.handleRockfall mines them on arrival. Duration keeps an open corridor preferred. +3718 5664 0 3720 5664 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3720 5664 0 3718 5664 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3719 5663 0 3719 5665 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3719 5665 0 3719 5663 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3726 5653 0 3726 5655 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3726 5655 0 3726 5653 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3727 5682 0 3727 5684 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3727 5684 0 3727 5682 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3727 5688 0 3729 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3729 5688 0 3727 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3728 5687 0 3728 5689 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3728 5689 0 3728 5687 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3732 5680 0 3734 5680 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3734 5680 0 3732 5680 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3733 5679 0 3733 5681 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3733 5681 0 3733 5679 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3748 5683 0 3748 5685 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3748 5685 0 3748 5683 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3748 5688 0 3748 5690 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3748 5690 0 3748 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3756 5677 0 3758 5677 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3758 5677 0 3756 5677 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3757 5676 0 3757 5678 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3757 5678 0 3757 5676 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3758 5690 0 3760 5690 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3760 5690 0 3758 5690 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3761 5652 0 3763 5652 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3763 5652 0 3761 5652 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3761 5687 0 3763 5687 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3763 5687 0 3761 5687 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3762 5686 0 3762 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3762 5688 0 3762 5686 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3766 5669 0 3766 5671 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3766 5671 0 3766 5669 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3767 5674 0 3769 5674 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3769 5674 0 3767 5674 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3768 5673 0 3768 5675 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3768 5675 0 3768 5673 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3767 5679 0 3769 5679 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3769 5679 0 3767 5679 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3768 5678 0 3768 5680 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3768 5680 0 3768 5678 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3768 5642 0 3770 5642 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3770 5642 0 3768 5642 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3770 5658 0 3770 5660 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3770 5660 0 3770 5658 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3720 5664 0 3720 5666 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3720 5666 0 3720 5664 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3725 5643 0 3727 5643 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3727 5643 0 3725 5643 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3726 5652 0 3728 5652 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3728 5652 0 3726 5652 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3727 5651 0 3729 5651 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3729 5651 0 3727 5651 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3731 5682 0 3731 5684 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3731 5684 0 3731 5682 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3743 5640 0 3745 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3745 5640 0 3743 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3744 5639 0 3744 5641 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3744 5641 0 3744 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3744 5689 0 3746 5689 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3746 5689 0 3744 5689 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3745 5688 0 3745 5690 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3745 5690 0 3745 5688 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3754 5640 0 3756 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3756 5640 0 3754 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3755 5639 0 3757 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3757 5639 0 3755 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3756 5638 0 3756 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3756 5640 0 3756 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3761 5668 0 3763 5668 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3763 5668 0 3761 5668 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3765 5687 0 3765 5689 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3765 5689 0 3765 5687 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3766 5638 0 3766 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3766 5640 0 3766 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3766 5646 0 3766 5648 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3766 5648 0 3766 5646 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3768 5658 0 3770 5658 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3770 5658 0 3768 5658 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3769 5657 0 3769 5659 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3769 5659 0 3769 5657 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3768 5680 0 3770 5680 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3770 5680 0 3768 5680 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3769 5679 0 3769 5681 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3769 5681 0 3769 5679 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3770 5638 0 3772 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3772 5638 0 3770 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3771 5637 0 3771 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 +3771 5639 0 3771 5637 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java new file mode 100644 index 0000000000..c37f8866c9 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java @@ -0,0 +1,108 @@ +package net.runelite.client.plugins.microbot.shortestpath; + +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Motherlode Mine must be internally routable once rockfalls are catalogued as transports. + * + *

    The bundled collision map bakes rockfalls in as permanent walls — upstream has no automation to + * clear them, so that is correct for upstream. It left the mine carved into disconnected pockets: + * a route from the cave arrival tile to the WEST_LOWER mining area died 10 tiles short, and the + * walker's existing {@code handleRockfall} never fired because no path was ever routed through one. + * + *

    Modelling each rockfall as a {@code Mine;Rockfall;} transport between its two open sides + * gives the pathfinder the edge, and the walker mines it on arrival. + */ +public class MotherlodeRockfallTransportTest { + + private static SplitFlagMap flags; + private static HashMap> transports; + + /** Arrival tile from the Dwarven Mine cave ("Enter;Cave;26654"). */ + private static final WorldPoint MLM_ARRIVAL = new WorldPoint(3728, 5692, 0); + /** WEST_LOWER mining spot from the Motherlode plugin. */ + private static final WorldPoint WEST_LOWER = new WorldPoint(3731, 5659, 0); + /** SOUTH_EAST mining spot — the far corner of the lower floor. */ + private static final WorldPoint SOUTH_EAST = new WorldPoint(3753, 5650, 0); + + @BeforeClass + public static void load() { + flags = SplitFlagMap.fromResources(); + transports = Transport.loadAllFromResources(); + } + + private static PathfinderConfig config() { + PathfinderConfig config = new PathfinderConfig(flags, transports, Collections.emptyList(), null, null); + try { + java.lang.reflect.Field f = PathfinderConfig.class.getDeclaredField("calculationCutoffMillis"); + f.setAccessible(true); + f.setLong(config, 30000); + for (Map.Entry> e : transports.entrySet()) { + if (e.getKey() == null) continue; + config.getTransports().put(e.getKey(), e.getValue()); + config.getTransportsPacked().put(WorldPointUtil.packWorldPoint(e.getKey()), e.getValue()); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + return config; + } + + private static WorldPoint routeEnd(WorldPoint from, WorldPoint to) { + Pathfinder pf = new Pathfinder(config(), from, to); + pf.run(); + List path = pf.getPath(); + return path.isEmpty() ? null : path.get(path.size() - 1); + } + + @Test + public void rockfallTransportsArePresentAndBidirectional() { + long rockfallOrigins = transports.values().stream() + .flatMap(Set::stream) + .filter(t -> t.getDestination() != null) + .filter(t -> { + WorldPoint d = t.getDestination(); + return d.getPlane() == 0 && d.getX() >= 3712 && d.getX() <= 3775 + && d.getY() >= 5632 && d.getY() <= 5695; + }) + .count(); + assertTrue("the Motherlode region should have transport edges after cataloguing rockfalls, got " + + rockfallOrigins, rockfallOrigins > 50); + } + + /** The failure that started this: arrival -> WEST_LOWER stopped 10 tiles short. */ + @Test + public void arrivalReachesTheWestLowerMiningArea() { + WorldPoint end = routeEnd(MLM_ARRIVAL, WEST_LOWER); + assertEquals("the mining area must now be reachable from the cave arrival tile", + WEST_LOWER, end); + } + + @Test + public void arrivalReachesTheFarSideOfTheMine() { + WorldPoint end = routeEnd(MLM_ARRIVAL, SOUTH_EAST); + assertEquals("the far corner of the lower floor must be reachable", SOUTH_EAST, end); + } + + /** End to end: the surface route must now finish inside the mine, not at its mouth. */ + @Test + public void theSurfaceRouteReachesAMiningArea() { + WorldPoint end = routeEnd(new WorldPoint(3144, 3337, 0), WEST_LOWER); + assertEquals("a walk from Draynor must complete all the way to the mining area", + WEST_LOWER, end); + } +} From 6415b8fa1138c00861ead38e29b9ce28c6aedef6 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 22:34:57 +0100 Subject: [PATCH 44/48] Let item-gated plain transports take part in bank planning hasRequiredTransportItems only admitted plain TRANSPORT entries carrying a currency cost, so an item-gated obstacle - a machete for a jungle bush, a pickaxe for a Motherlode rockfall, a Shantay pass - fell through every branch to the catch-all "return true", was never reported missing by getMissingTransports, and was never withdrawn. That contradicted the pathfinder. PathfinderConfig.hasRequiredItems ORs in Rs2Bank.hasItem when useBankItems is set, and refreshAvailableItemIds includes bank contents on the same flag, so a route was planned through the obstacle on the strength of a banked item the planner then declined to fetch - stranding the walk at the obstacle it had just routed through. Extracted the decision as planningCoversPlainTransport so both directions are testable without a client. This only widens which transports are ELIGIBLE, not how many bank trips happen. Collection is path-scoped: getTransportsForDestination pathfinds first and inspects only transports on the resulting route, so an item is fetched solely when the chosen route actually needs it. The downstream machinery already handled generic items - getMissingTransportItemIdsWith- Quantities walks getItemIdRequirements for any transport, picks whichever alternative has the most in bank, and uses quantity 1 for non-currency transports - so nothing else had to change. 235 rows in transports.tsv become eligible: 90 Motherlode rockfalls (new in this branch), 102 machete-gated jungle bush/tree/vines, 10 White Wolf Mountain rock slides, 6 Shantay passes, and ~27 keyed doors, ladders and slopes. Only the Motherlode case is verifiable offline; the Karamja and desert routes are untested live. Tests: 5 new cases over the real transport data - every item-gated plain transport eligible, every requirement-free one still ignored, currency transports unchanged, rockfalls covered, and null/non-plain types rejected. Full suite green, guardrail 961 known violations, no regressions. Co-Authored-By: Claude Opus 4.8 --- .../banking/Rs2WalkerBankingPlanner.java | 25 +++- .../BankedTransportItemPlanningTest.java | 126 ++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/banking/BankedTransportItemPlanningTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java index 8c4c153652..3f33a79336 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/banking/Rs2WalkerBankingPlanner.java @@ -62,6 +62,29 @@ public static List getTransportsForDestination(WorldPoint destination } } + /** + * Whether a plain {@link TransportType#TRANSPORT} takes part in bank planning. + * + *

    Previously only currency-bearing ones did, so an item-gated obstacle — a machete for a + * jungle bush, a pickaxe for a rockfall, a Shantay pass — fell through + * {@link #hasRequiredTransportItems} to its catch-all {@code return true}, was never reported as + * missing, and was never withdrawn. That contradicted the pathfinder: + * {@code PathfinderConfig.hasRequiredItems} counts bank contents when + * {@code useBankItems} is set, so a route was planned through the obstacle on the strength of a + * banked item the planner then declined to fetch, stranding the walk at the obstacle. + * + *

    This only widens which transports are eligible. Collection is path-scoped — + * {@link #getTransportsForDestination} pathfinds first and inspects only transports on the + * resulting route — so an item is fetched solely when the chosen route actually needs it. + */ + static boolean planningCoversPlainTransport(Transport transport) { + if (transport == null || transport.getType() != TransportType.TRANSPORT) { + return false; + } + return transport.getCurrencyAmount() > 0 + || (transport.getItemIdRequirements() != null && !transport.getItemIdRequirements().isEmpty()); + } + public static boolean hasRequiredTransportItems(Transport transport) { if (transport == null) { return false; @@ -81,7 +104,7 @@ public static boolean hasRequiredTransportItems(Transport transport) { || transport.getType() == TransportType.SHIP || transport.getType() == TransportType.MINECART || transport.getType() == TransportType.MAGIC_CARPET - || (transport.getType() == TransportType.TRANSPORT && transport.getCurrencyAmount() > 0)) { + || planningCoversPlainTransport(transport)) { if (transport.getType() == TransportType.TELEPORTATION_SPELL && transport.getDisplayInfo() != null) { String spellName = transport.getDisplayInfo().contains(":") ? transport.getDisplayInfo().split(":")[0].trim() diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/banking/BankedTransportItemPlanningTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/banking/BankedTransportItemPlanningTest.java new file mode 100644 index 0000000000..ef4344e011 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/banking/BankedTransportItemPlanningTest.java @@ -0,0 +1,126 @@ +package net.runelite.client.plugins.microbot.util.walker.banking; + +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.microbot.shortestpath.Transport; +import net.runelite.client.plugins.microbot.shortestpath.TransportType; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Item-gated plain transports must take part in bank planning. + * + *

    Only currency-bearing {@link TransportType#TRANSPORT} entries used to qualify, so a machete for + * a jungle bush, a pickaxe for a Motherlode rockfall or a Shantay pass fell through + * {@code hasRequiredTransportItems} to its catch-all {@code return true}, was never counted as + * missing, and was never withdrawn. + * + *

    That contradicted the pathfinder, which does count bank contents when + * {@code useBankItems} is set — so a route was planned through the obstacle on the strength of a + * banked item the planner then refused to fetch, stranding the walk at the obstacle. + */ +public class BankedTransportItemPlanningTest { + + private static List all; + + @BeforeClass + public static void load() { + HashMap> transports = Transport.loadAllFromResources(); + all = transports.values().stream().flatMap(Set::stream).collect(Collectors.toList()); + } + + /** {@code menuOption;menuTarget} for readable assertion messages. */ + private static String describe(Transport t) { + String action = t.getAction() == null ? "" : t.getAction(); + String name = t.getName() == null ? "" : t.getName(); + return action + ";" + name; + } + + private static List matching(String menuFragment) { + return all.stream() + .filter(t -> t.getType() == TransportType.TRANSPORT) + .filter(t -> { + String target = describe(t); + return target.toLowerCase().contains(menuFragment.toLowerCase()); + }) + .collect(Collectors.toList()); + } + + @Test + public void itemGatedPlainTransportsNowQualifyForPlanning() { + List itemGated = all.stream() + .filter(t -> t.getType() == TransportType.TRANSPORT) + .filter(t -> t.getItemIdRequirements() != null && !t.getItemIdRequirements().isEmpty()) + .filter(t -> t.getCurrencyAmount() <= 0) + .collect(Collectors.toList()); + + assertFalse("the data should contain item-gated plain transports (rockfalls, jungle bushes, " + + "Shantay passes)", itemGated.isEmpty()); + + for (Transport t : itemGated) { + assertTrue("an item-gated plain transport must be eligible for bank planning, otherwise " + + "the pathfinder routes through it on a banked item nobody withdraws: " + describe(t), + Rs2WalkerBankingPlanner.planningCoversPlainTransport(t)); + } + } + + /** A transport with no item and no currency requirement must stay out of planning. */ + @Test + public void unrestrictedTransportsAreStillIgnored() { + List unrestricted = all.stream() + .filter(t -> t.getType() == TransportType.TRANSPORT) + .filter(t -> t.getItemIdRequirements() == null || t.getItemIdRequirements().isEmpty()) + .filter(t -> t.getCurrencyAmount() <= 0) + .collect(Collectors.toList()); + + assertFalse("precondition: most doors and stairs require nothing", unrestricted.isEmpty()); + for (Transport t : unrestricted) { + assertFalse("a transport requiring nothing must never trigger a bank trip: " + describe(t), + Rs2WalkerBankingPlanner.planningCoversPlainTransport(t)); + } + } + + /** Currency-bearing transports kept their existing eligibility. */ + @Test + public void currencyTransportsRemainEligible() { + List currency = all.stream() + .filter(t -> t.getType() == TransportType.TRANSPORT) + .filter(t -> t.getCurrencyAmount() > 0) + .collect(Collectors.toList()); + + for (Transport t : currency) { + assertTrue("currency transports must keep qualifying: " + describe(t), + Rs2WalkerBankingPlanner.planningCoversPlainTransport(t)); + } + } + + @Test + public void theMotherlodeRockfallsQualify() { + List rockfalls = matching("Rockfall"); + assertFalse("Motherlode rockfalls should be catalogued", rockfalls.isEmpty()); + for (Transport t : rockfalls) { + assertTrue("a rockfall needs a pickaxe, so it must be plannable", + Rs2WalkerBankingPlanner.planningCoversPlainTransport(t)); + } + } + + @Test + public void nullAndNonPlainTransportsAreRejectedSafely() { + assertFalse("null must not qualify", Rs2WalkerBankingPlanner.planningCoversPlainTransport(null)); + + List teleports = all.stream() + .filter(t -> t.getType() == TransportType.TELEPORTATION_ITEM) + .collect(Collectors.toList()); + for (Transport t : teleports) { + assertFalse("non-plain types are handled by their own branch and must not match here", + Rs2WalkerBankingPlanner.planningCoversPlainTransport(t)); + } + } +} From 5c06b86e004309cc0dfe4569a500501d3f7c5eee Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 22:54:12 +0100 Subject: [PATCH 45/48] Revert "Reject walk targets that are not walkable terrain, before routing" This reverts commit d16e9d1e2045d334dddb944981722045093487bb. --- .../shortestpath/pathfinder/CollisionMap.java | 13 --- .../shortestpath/pathfinder/SplitFlagMap.java | 14 --- .../microbot/util/walker/Rs2Walker.java | 75 ---------------- .../TargetWalkabilityPreflightTest.java | 89 ------------------- 4 files changed, 191 deletions(-) delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java index f5365853f5..cee0e1570e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java @@ -67,19 +67,6 @@ public boolean isBlocked(int x, int y, int z) { return !n(x, y, z) && !s(x, y, z) && !e(x, y, z) && !w(x, y, z); } - /** - * Whether collision data exists for the region containing {@code (x, y)}. - * - *

    Required to interpret {@link #isBlocked}: an unmapped region reads as fully - * blocked, because {@link SplitFlagMap#get} returns {@code false} for one and {@code isBlocked} - * negates all four directions. Gate on this before treating blocked as unreachable. - * - * @see SplitFlagMap#hasRegion(int, int) - */ - public boolean hasRegion(int x, int y) { - return collisionData.hasRegion(x, y); - } - /** * Single walking step permission check from (x,y,z) in direction (dx,dy). * Used by {@link PathSmoother}. Graph expansion uses {@link #fillTraversableLegacy} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java index 8afa384bf0..c15ce436d6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java @@ -69,20 +69,6 @@ public boolean get(int x, int y, int z, int flag) { return regionMaps[index].get(x, y, z, flag); } - /** - * Whether collision data was actually loaded for the region containing {@code (x, y)}. - * - *

    Callers need this to tell "known to be blocked" apart from "no data". {@link #get} returns - * {@code false} for an unloaded region, and {@code CollisionMap.isBlocked} is the conjunction of - * four negated {@link #get} calls, so an unmapped region reads as fully blocked. Any - * check that treats blocked as unreachable must gate on this first, or it will reject every - * target in an instance or in a region missing from the collision map. - */ - public boolean hasRegion(int x, int y) { - final int index = getIndex(x / REGION_SIZE, y / REGION_SIZE); - return index >= 0 && index < regionMaps.length && regionMaps[index] != null; - } - private int getIndex(int regionX, int regionY) { return (regionX - regionExtents.getMinX()) + (regionY - regionExtents.getMinY()) * widthInclusive; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 0851d6b491..3a71bb7aff 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -19,7 +19,6 @@ import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.globval.enums.InterfaceTab; import net.runelite.client.plugins.microbot.shortestpath.*; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; @@ -626,65 +625,6 @@ private static void waitUntilIdleAfterSceneWalk(WorldPoint cancelGoal, int timeo } } - /** - * Whether any tile within {@code distance} of {@code target} is walkable in the collision map. - * - *

    Pre-flight guard so a destination that does not exist as walkable terrain fails - * immediately instead of after a full route. A walk to {@code (3087,9720)} — inside the rock - * east of the Dwarven Mine, with 0 walkable tiles within 6 — spent ~80s covering 100+ tiles to - * the nearest reachable tile and then reported {@code partial-retries-exhausted}, which reads - * as a walker fault rather than a bad coordinate. - * - *

    Permissive by design. An unmapped region reads as fully blocked (see - * {@link CollisionMap#hasRegion}), so every ambiguous case returns {@code true} and lets the - * pathfinder decide. Only a target sitting in mapped, wholly blocked terrain is rejected — - * otherwise this would refuse instances and any region missing from the collision map. - */ - static boolean hasWalkableTileWithin(CollisionMap map, WorldPoint target, int distance) { - if (map == null || target == null) { - return true; - } - if (!map.hasRegion(target.getX(), target.getY())) { - return true; - } - int radius = Math.max(0, distance); - for (int dx = -radius; dx <= radius; dx++) { - for (int dy = -radius; dy <= radius; dy++) { - int x = target.getX() + dx; - int y = target.getY() + dy; - if (!map.hasRegion(x, y)) { - return true; - } - if (!map.isBlocked(x, y, target.getPlane())) { - return true; - } - } - } - return false; - } - - /** Nearest walkable tile to {@code target} within {@code maxRadius}, or null. Diagnostics only. */ - static WorldPoint nearestWalkableTile(CollisionMap map, WorldPoint target, int maxRadius) { - if (map == null || target == null) { - return null; - } - for (int r = 1; r <= maxRadius; r++) { - for (int dx = -r; dx <= r; dx++) { - for (int dy = -r; dy <= r; dy++) { - if (Math.max(Math.abs(dx), Math.abs(dy)) != r) { - continue; // ring only; inner rings already scanned - } - int x = target.getX() + dx; - int y = target.getY() + dy; - if (map.hasRegion(x, y) && !map.isBlocked(x, y, target.getPlane())) { - return new WorldPoint(x, y, target.getPlane()); - } - } - } - } - return null; - } - /** Door / gate from main path loop vs {@link #handleNearbyRawPathSceneObjects} raw-path scan (same nudge UX). */ private static boolean shouldCanvasNudgeAfterDoorLikeExit(String exitReason) { if (exitReason == null) { @@ -1328,21 +1268,6 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part if (debug) { return WalkerState.EXIT; } - // Pre-flight: a destination with no walkable tile within the arrival distance can never be - // reached, so reject it here rather than after a full route ending at the nearest wall. - PathfinderConfig preflightConfig = Rs2PathApi.getPathfinderConfig(); - CollisionMap preflightMap = preflightConfig != null ? preflightConfig.getMap() : null; - if (!hasWalkableTileWithin(preflightMap, target, distance)) { - WorldPoint nearestWalkable = nearestWalkableTile(preflightMap, target, 48); - log.warn("[Walker] walk rejected: target {} has no walkable tile within {} in the collision map" - + " (nearest walkable {}); check the destination coordinate", - target, distance, - nearestWalkable != null ? nearestWalkable : "none within 48"); - Telemetry.recordUnreachable("target-not-walkable", Rs2Player.getWorldLocation(), - target, nearestWalkable, 0, distance, null); - setTarget(null, "rs2walker:processWalk:target-not-walkable"); - return WalkerState.UNREACHABLE; - } int partialRetriesWorking = partialRetries; // When the last partial retry was spent, so route progress made after it can refill the // budget. Without this the counter is monotonic for the entire walk. diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java deleted file mode 100644 index 7e813a0383..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.runelite.client.plugins.microbot.util.walker; - -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; -import org.junit.BeforeClass; -import org.junit.Test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * Pre-flight rejection of destinations that are not walkable terrain. - * - *

    Regression for a walk that spent ~80s and 100+ tiles routing from Draynor to the Dwarven Mine - * before reporting {@code partial-retries-exhausted}. The goal {@code (3087,9720)} is inside the - * rock east of the mine: blocked, with zero walkable tiles within 6. The pathfinder was correct — - * it stopped at {@code (3056,9720)}, the last walkable tile before the rock face — but the failure - * read as a walker fault rather than a bad coordinate. The intended destination was the Motherlode - * cave mouth at {@code (3060,9766)}. - */ -public class TargetWalkabilityPreflightTest { - - private static CollisionMap map; - - /** Inside the rock east of the Dwarven Mine — the coordinate that produced the bad walk. */ - private static final WorldPoint BURIED_IN_ROCK = new WorldPoint(3087, 9720, 0); - /** Last walkable tile the pathfinder could actually reach along that corridor. */ - private static final WorldPoint LAST_WALKABLE = new WorldPoint(3056, 9720, 0); - /** The real Motherlode Mine entrance ("Enter;Cave;26654" in transports.tsv). */ - private static final WorldPoint MLM_CAVE_MOUTH = new WorldPoint(3060, 9766, 0); - - @BeforeClass - public static void load() { - map = new CollisionMap(SplitFlagMap.fromResources()); - } - - @Test - public void aTargetBuriedInRockIsRejected() { - assertTrue("precondition: the region must be mapped, or the guard correctly abstains", - map.hasRegion(BURIED_IN_ROCK.getX(), BURIED_IN_ROCK.getY())); - assertTrue("precondition: the tile itself is blocked", - map.isBlocked(BURIED_IN_ROCK.getX(), BURIED_IN_ROCK.getY(), 0)); - assertFalse("a goal with no walkable tile within the arrival distance must be rejected " - + "before the walk starts", - Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 5)); - } - - @Test - public void legitimateUndergroundTargetsAreAccepted() { - assertTrue("the last walkable tile in the corridor must still be accepted", - Rs2Walker.hasWalkableTileWithin(map, LAST_WALKABLE, 5)); - assertTrue("the Motherlode cave mouth is a valid destination and must not be rejected", - Rs2Walker.hasWalkableTileWithin(map, MLM_CAVE_MOUTH, 5)); - } - - /** - * The guard must abstain wherever it lacks data. An unmapped region reads as fully blocked, so - * a naive check would reject every instance and every region absent from the collision map. - */ - @Test - public void unmappedRegionsAreNeverRejected() { - WorldPoint offMap = new WorldPoint(0, 0, 0); - assertFalse("precondition: this region genuinely has no collision data", - map.hasRegion(offMap.getX(), offMap.getY())); - assertTrue("no collision data must mean 'let the pathfinder try', not 'unreachable'", - Rs2Walker.hasWalkableTileWithin(map, offMap, 5)); - assertTrue("a null map must never block a walk", - Rs2Walker.hasWalkableTileWithin(null, BURIED_IN_ROCK, 5)); - } - - /** A generous arrival distance reaches real ground, so the same goal becomes acceptable. */ - @Test - public void aLargeArrivalDistanceReachesWalkableGround() { - assertFalse(Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 5)); - assertTrue("with a 40 tile tolerance the corridor is inside the search box", - Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 40)); - } - - @Test - public void theRejectionPointsAtTheNearestRealTile() { - WorldPoint nearest = Rs2Walker.nearestWalkableTile(map, BURIED_IN_ROCK, 48); - assertNotNull("the warning must name a concrete tile so the coordinate can be corrected", - nearest); - assertFalse("the suggested tile must itself be walkable", - map.isBlocked(nearest.getX(), nearest.getY(), 0)); - } -} From 289090d7a8b2396e3720e3d5b563b4d38e6316a6 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Tue, 21 Jul 2026 23:23:59 +0100 Subject: [PATCH 46/48] Revert "Catalogue Motherlode Mine rockfalls as transports" This reverts commit f9aef423de0e6778555ffdbf8c39fa708e412e00. --- .../microbot/shortestpath/transports.tsv | 93 --------------- .../MotherlodeRockfallTransportTest.java | 108 ------------------ 2 files changed, 201 deletions(-) delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv index 7c64a9c968..5a6cb7333c 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/transports.tsv @@ -6061,96 +6061,3 @@ 3308 3493 0 3308 3491 0 Climb-over;Broken fence;2618 6 2893 3507 0 2893 9907 0 Climb-down;Ladder;17374 1 2893 9907 0 2893 3507 0 Climb-up;Ladder;17387 1 -# Motherlode Mine rockfalls (26679/26680). Mineable obstacles: the bundled collision map bakes -# them in as permanent walls, so without these edges the pathfinder cannot route through the mine. -# Rs2Walker.handleRockfall mines them on arrival. Duration keeps an open corridor preferred. -3718 5664 0 3720 5664 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3720 5664 0 3718 5664 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3719 5663 0 3719 5665 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3719 5665 0 3719 5663 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3726 5653 0 3726 5655 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3726 5655 0 3726 5653 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3727 5682 0 3727 5684 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3727 5684 0 3727 5682 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3727 5688 0 3729 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3729 5688 0 3727 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3728 5687 0 3728 5689 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3728 5689 0 3728 5687 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3732 5680 0 3734 5680 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3734 5680 0 3732 5680 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3733 5679 0 3733 5681 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3733 5681 0 3733 5679 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3748 5683 0 3748 5685 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3748 5685 0 3748 5683 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3748 5688 0 3748 5690 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3748 5690 0 3748 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3756 5677 0 3758 5677 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3758 5677 0 3756 5677 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3757 5676 0 3757 5678 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3757 5678 0 3757 5676 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3758 5690 0 3760 5690 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3760 5690 0 3758 5690 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3761 5652 0 3763 5652 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3763 5652 0 3761 5652 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3761 5687 0 3763 5687 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3763 5687 0 3761 5687 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3762 5686 0 3762 5688 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3762 5688 0 3762 5686 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3766 5669 0 3766 5671 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3766 5671 0 3766 5669 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3767 5674 0 3769 5674 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3769 5674 0 3767 5674 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3768 5673 0 3768 5675 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3768 5675 0 3768 5673 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3767 5679 0 3769 5679 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3769 5679 0 3767 5679 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3768 5678 0 3768 5680 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3768 5680 0 3768 5678 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3768 5642 0 3770 5642 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3770 5642 0 3768 5642 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3770 5658 0 3770 5660 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3770 5660 0 3770 5658 0 Mine;Rockfall;26679 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3720 5664 0 3720 5666 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3720 5666 0 3720 5664 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3725 5643 0 3727 5643 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3727 5643 0 3725 5643 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3726 5652 0 3728 5652 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3728 5652 0 3726 5652 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3727 5651 0 3729 5651 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3729 5651 0 3727 5651 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3731 5682 0 3731 5684 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3731 5684 0 3731 5682 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3743 5640 0 3745 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3745 5640 0 3743 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3744 5639 0 3744 5641 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3744 5641 0 3744 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3744 5689 0 3746 5689 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3746 5689 0 3744 5689 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3745 5688 0 3745 5690 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3745 5690 0 3745 5688 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3754 5640 0 3756 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3756 5640 0 3754 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3755 5639 0 3757 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3757 5639 0 3755 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3756 5638 0 3756 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3756 5640 0 3756 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3761 5668 0 3763 5668 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3763 5668 0 3761 5668 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3765 5687 0 3765 5689 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3765 5689 0 3765 5687 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3766 5638 0 3766 5640 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3766 5640 0 3766 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3766 5646 0 3766 5648 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3766 5648 0 3766 5646 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3768 5658 0 3770 5658 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3770 5658 0 3768 5658 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3769 5657 0 3769 5659 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3769 5659 0 3769 5657 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3768 5680 0 3770 5680 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3770 5680 0 3768 5680 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3769 5679 0 3769 5681 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3769 5681 0 3769 5679 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3770 5638 0 3772 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3772 5638 0 3770 5638 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3771 5637 0 3771 5639 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 -3771 5639 0 3771 5637 0 Mine;Rockfall;26680 1265;1267;1269;12297;1273;1271;1275;11920;23680;23276;13243;20014 10 diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java deleted file mode 100644 index c37f8866c9..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/shortestpath/MotherlodeRockfallTransportTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package net.runelite.client.plugins.microbot.shortestpath; - -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; -import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Motherlode Mine must be internally routable once rockfalls are catalogued as transports. - * - *

    The bundled collision map bakes rockfalls in as permanent walls — upstream has no automation to - * clear them, so that is correct for upstream. It left the mine carved into disconnected pockets: - * a route from the cave arrival tile to the WEST_LOWER mining area died 10 tiles short, and the - * walker's existing {@code handleRockfall} never fired because no path was ever routed through one. - * - *

    Modelling each rockfall as a {@code Mine;Rockfall;} transport between its two open sides - * gives the pathfinder the edge, and the walker mines it on arrival. - */ -public class MotherlodeRockfallTransportTest { - - private static SplitFlagMap flags; - private static HashMap> transports; - - /** Arrival tile from the Dwarven Mine cave ("Enter;Cave;26654"). */ - private static final WorldPoint MLM_ARRIVAL = new WorldPoint(3728, 5692, 0); - /** WEST_LOWER mining spot from the Motherlode plugin. */ - private static final WorldPoint WEST_LOWER = new WorldPoint(3731, 5659, 0); - /** SOUTH_EAST mining spot — the far corner of the lower floor. */ - private static final WorldPoint SOUTH_EAST = new WorldPoint(3753, 5650, 0); - - @BeforeClass - public static void load() { - flags = SplitFlagMap.fromResources(); - transports = Transport.loadAllFromResources(); - } - - private static PathfinderConfig config() { - PathfinderConfig config = new PathfinderConfig(flags, transports, Collections.emptyList(), null, null); - try { - java.lang.reflect.Field f = PathfinderConfig.class.getDeclaredField("calculationCutoffMillis"); - f.setAccessible(true); - f.setLong(config, 30000); - for (Map.Entry> e : transports.entrySet()) { - if (e.getKey() == null) continue; - config.getTransports().put(e.getKey(), e.getValue()); - config.getTransportsPacked().put(WorldPointUtil.packWorldPoint(e.getKey()), e.getValue()); - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - return config; - } - - private static WorldPoint routeEnd(WorldPoint from, WorldPoint to) { - Pathfinder pf = new Pathfinder(config(), from, to); - pf.run(); - List path = pf.getPath(); - return path.isEmpty() ? null : path.get(path.size() - 1); - } - - @Test - public void rockfallTransportsArePresentAndBidirectional() { - long rockfallOrigins = transports.values().stream() - .flatMap(Set::stream) - .filter(t -> t.getDestination() != null) - .filter(t -> { - WorldPoint d = t.getDestination(); - return d.getPlane() == 0 && d.getX() >= 3712 && d.getX() <= 3775 - && d.getY() >= 5632 && d.getY() <= 5695; - }) - .count(); - assertTrue("the Motherlode region should have transport edges after cataloguing rockfalls, got " - + rockfallOrigins, rockfallOrigins > 50); - } - - /** The failure that started this: arrival -> WEST_LOWER stopped 10 tiles short. */ - @Test - public void arrivalReachesTheWestLowerMiningArea() { - WorldPoint end = routeEnd(MLM_ARRIVAL, WEST_LOWER); - assertEquals("the mining area must now be reachable from the cave arrival tile", - WEST_LOWER, end); - } - - @Test - public void arrivalReachesTheFarSideOfTheMine() { - WorldPoint end = routeEnd(MLM_ARRIVAL, SOUTH_EAST); - assertEquals("the far corner of the lower floor must be reachable", SOUTH_EAST, end); - } - - /** End to end: the surface route must now finish inside the mine, not at its mouth. */ - @Test - public void theSurfaceRouteReachesAMiningArea() { - WorldPoint end = routeEnd(new WorldPoint(3144, 3337, 0), WEST_LOWER); - assertEquals("a walk from Draynor must complete all the way to the mining area", - WEST_LOWER, end); - } -} From cf8cf030039f1032105eb64fb109f6dacad2689b Mon Sep 17 00:00:00 2001 From: infuse21 Date: Wed, 22 Jul 2026 00:03:11 +0100 Subject: [PATCH 47/48] Restore Motherlode Mine collision region from the 11/19 cache Region 58_88 (Motherlode Mine, x3712-3775 y5632-5695) regressed in 631884f9e3 "update collision map" (23 Jan 2026). Connectivity from the cave arrival tile (3728,5692) collapsed from 1473 reachable tiles to 192 - 87% of the mine cut off - and every lower-floor mining spot became unreachable: a585dc3247 (19 Nov 2025) walkable=1623 reachable=1473 spots OK 631884f9e3 (23 Jan 2026) walkable=1580 reachable=192 spots dead a19a3340d1 (12 May 2026) walkable=1606 reachable=192 spots dead f8b113810f (20 Jul 2026) walkable=1606 reachable=192 spots dead This is why the world map could once be used to walk into Motherlode and then could not: the pathfinder had no route through the mine, so any target inside it was unreachable regardless of how it was set. Restores just that one 952-byte region from a585dc3247. Every other region is left on the current upstream sync - verified by comparing decompressed entries, only 58_88 differs. Safe despite the age: Motherlode Mine last changed in the game on 8 May 2024 (Project Rebalance, minor follow-up 15 May 2024), so the 19 Nov 2025 capture postdates the last map change by 18 months. The January regression was a bad regeneration, not a map update. After: walkable=1623 reachable=1473, with WEST_LOWER, WEST_MID, SOUTH_EAST and SOUTH_WEST all reachable from the arrival tile. The upper floor (WEST_UPPER, EAST_UPPER) stays unreachable in every version including the good one - that needs the ladder catalogued, which is gated behind the 100 golden nugget unlock and is tracked separately. With the mine genuinely connected, Rs2Walker.handleRockfall works as designed: routes now pass through the mine and it mines a rockfall that lies on the path. That is the correct model, unlike the transport rows reverted in 289090d7a8 - a transport relocates the player, and mining a rockfall does not. The archive is byte-larger-compressed differently (1197109 -> 1058342) because it was rewritten by a different deflate implementation; entry names, count (2724) and decompressed contents are unchanged apart from 58_88. Verified offline by decoding the FlagMap bitset directly. NOT yet verified in-game. Co-Authored-By: Claude Opus 4.8 --- .../microbot/shortestpath/collision-map.zip | Bin 1197109 -> 1058342 bytes .../BankedTransportItemPlanningTest.java | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/collision-map.zip b/runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/collision-map.zip index c4448fdd82a0fb7fa94a9333b4bd05e4595600e8..63e0f77850cbe7cda4e0d3ee8e3c0f61658e54a6 100644 GIT binary patch literal 1058342 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�?IJD9l0}zG;6HnzQ8?;#mIe@qU+uKsBnr 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 z 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

    18Iiw0ghGvW+zCO5^W|z%L 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%0DLO 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≠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%0DT1G=5my?xaTxOEm{M&V5h?Kh}M1@xnJA} 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
    $j8iZ;SB)3x_Wvc^(LM&crj- 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
    kn$z=n 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

    t7s34dZrc$K2 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 z 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

    NYCP*)IuA_1T{6O?Jp>oY4e!J9c;xO5-{iZt z^wCVX{9|w9_eh#@IMlFWn<19jpTN*T_IQwurog8v?Z>EKC5&dKj*_IBc-DO zZ>9XrTm^@K_-qcfi(o-0pPxMx6qpxlQH0$J{9t|~q*tRbc(vKE2yXU4>;gSdHcl)Q zHko&Bfz#9IO~!3VtnYBFZOzDTA{vafDmGxf&89;~-4{IHMa$8*VO7Vmhf%{{_1`O0 zakXFfmVoPR;b?(}p(5>_6INAdV&U%xqD+akqVKXEWWBKpf1#meO-NpC=u z<9ns>Ca~Jl7Ysca+@UZYZ@+DI%sj zry2$KGhySC7a422#2p&Pw^Y@b#TwHu^$=F&8c`tnV2mwE@P>du(Scx1^}Wh6;zgkf){9a#cxYD#Dymr$C=tKB!?ta=5xo4$ZQ zrj-MRaXx5BzRf+QHgT)(_6)6JKwkPp20xWH2-1^v*t^=8=#_iGHBzNN`Z%Bx^<-)# zhKCcD$%u0_p=YL5X+(5zxucUTDbx%zo>DakH34_ez!F&y>B7TcXGUI=TBTxExIDxW zxk_V+itJ_sY}0G8T#ZvNH(iTbo-T+AZ*}N67)(?2$MDttDRF_V2XW}_P(>G&v3yT; z?y~gwYF!6#OaE+f*>T5m%>Fh(k%r1S(R}oe$4_DmP4+m)1n90zA9wi_A# zijw^DB8>tBgta?8-*6QNnGoJ*ZPUSrGMcbSqP5nWquY8eIMHqDOdQ9VzDfHshAW&@ZtC+=aN1 zU(w{V5#3Je_QH6=gZ)>X9tpByq0ryUsd&K*7m64}N@t1kBl_meqjl5GHiiFw{?E(;5NH`ICf0fJcFClW*`WLEq8j zy}~`P4Sp_X1N=w%jnVj#?;tg$950>wIxmjvGI41}+!&|vY}4f4`WSYzeR@jtT{O*+ z72FuhunV8iPQK|~b`LYSA783{XcqAq;M^w`&@mWOPo#Ec$5|1vfU4QKONPJ8j32}T-E)b*(CyETdScPK;Jm(}jYa*8t8Ncf6j7ak zK`ld9!}n}IeG#5|JTP`UTs_M%aK>XyRx;jT}VXi>MyXp|$2(6$O#T`e)+(01OOy4qhj8?~IhPBWPZ z&BWHcy~>%d_Byh;t@S3vhYQ=_b|Kh4UH3;_^X?DTzzxKg^D`FMq0;_D`%SOlO}s0@ zCU;L;2M9cMcsv4O0Tbux%Yf&TtJ~x~X4g$ns5yNF(PBR{9al7II7y1YWD5o=axagZ z0Kq&?C7-w=BjlEy*E@_rBuQGsxMTHZzMGs6&gw0z+u!G_N$yH;Tj%t8PhWWnHokA1 zW3FN2%X3?^|J?YFmThMER8=HW$_)PfASOuCYQ6%>>yOG)OMrSOlykH*0n~dIU@&io zE5KG57=IzmkpSI(lfU&l@z-FsHI9Oec*0F2qLTh#v7l<=+`5B~_AfKOPrzARA6_ED zi9)s`3$qqvAzvb#sLEziXsW6C09f!0hk^_^8te+SjC=^jN05)K8Su6UR3ex==l zMxm1G@wX*R=>j&~ewaD}RJdV&K%-TtQmY+b&9G%NG2-S7b?$`o_bkXNZ13TB7t_II}o5c_u+Utli zCZ!fT_Ex96!-o~C9o61QKDO0yT*>+Sjxnb4gI;#UJ(b(f7Y&(P)w)j$Y?rych}By{ zzLfN>?;&}f!Je94?Vm=znAAYSGx^B)JD!`30NF7ZUqAV{(B5I&n;jMOe$mUCy74GM z^;lyY>}-$@D4CqJ(-|A5ofl`#egs*8lx&1n2~97y7`pWjr1%nx5Ggkq}U}kzS{6}?5&SL!KQ!bJl@OZv)gO=dB&##sdUa~r4!|d zSLy1XGexq*r!j`*a*07S!qjUeX35^8$J%=>ZV1g0KlWZ(Url*yKx$Z-3JB;IIa|kH z;vD`&xljQrHv@4WZ1v||gi)L0SK{X<0GE1`zcfxVw$lt1@O58P@ahtUk~ql1YF59z zI}nYD#v_WJA7IE@cR_($ekRW;AZmW^>JxpuPE--2kBK04rn3?*uXJtIW2Cd2T3-Hg zSfS^RJ!-xhewjpg_{c=)Br%(qarX193n~ZVp^1zA%vXMh)C_97%a8!B4D`a<+VNFI zH;d28&d_r`gh}PT5Xv^S^O6`;UhT^SW8B_oq>7@=dy6G-t9!vX6)>rZ%0&>hF!PNX zsLQ+o3Rh%zBhg4L{p}P(^v7P=#Pv|I4?+1aN30Xr>^kSz$e$;@vy#p{_!$!U{>`UPb}WfEyiIcXI8_-OCduKIHqV9hD`Tigq|x zHuqtKN@`eyS{X3egRmSbk-Ov=p&YI#tvm?c%FR?$&G6W~zbHqwp?eEuV->zUEz75lb~m z^zo}aMelc@_Txmqu&SI>^-#Rap#%;3_AVY=$ypw^bnz1({6<`sX`7!#ue;p`KUc&C zac)p!2`(BW%DZJU_6?ob%*AB9OPlq8+EG#y$XpyZC1e41nMC_ZS!5wZWZxfIi%q-vk|qpg`8=LM9zb?n1bgA`IKn{5cZLw>lFNcdWhA=qes7Z@e}v!D&>e2qx{9ON|r-Scf5;c^Fs zURa3f0srBs9dfUUg0=O%i96Df<~0$QvBC3Jr;4t^&QqjD`2xW+L?#{S0uJQu`+9OkY+;6yc-kl}Q19f4_ zF7IPMg~}BiwmB?W8}K3?t23T!QGH`U7}F8xi(;4XPuD~#g(YEuR5xj>64oIbxkhur z05OHP6YT;gO$(eYa}jH9wfkAZxzahvjc=bo>0ow_-xaW`C2o6AOB_%XM-I`)52<#A zwu)K?W^PnPTP#nm$P|c8NC$6e9TK(Kp$F^n=@@NJ4n_Hf>3pta7(9G9y0azDsz^op zz>Xp2C|?*)P=5ZzS}-VtpT>=C_Kv(}E0ReEkF#HaD|3?b?ZGZuw zOapvEgn}_p*&iC@k0K<&H*R^>hDRKRx82B&xG*)O=GdXnWb~nG654CNFQNz6NFZb#2hw z+U1XMgVNq=*sE zfV)`^!DsX;aTbnR3us09>Rh>3Z@sGBiWMRFPF4)uZ6d}$eXBweNXt7Z07x1d#y090 zWY3(~3h1)!&cMTM6ZoPV2;TQNw6Yz;5q13b2S@TM>fO1gE71Pr_~YiXa6Q#|(BlP7 z-{54B9ca0@#Hz=a@=a{l83+|U8V)$kK(ITf)Q)+g39@0hz%BN?gPa_8Pg}&IoyoaI zNO-&Lc7jiza524S!A2Oj=~e^#YT3w%I=Vg*jxDc8pMX~HR{!{D-~yPZbZ-Z5PJdxVImjwD{(80S=jO!MfWA#*@1{CkTFm_YP~17r@zKE zgp&_Z-RGZ=GaT*Ep9k%AXoB6H!Lg=fa!0x7 zxr?Y~qe~h@2~K=EJg5kTay?xT0(lxzne;wQ-)og$0xwt;VfVbU%laxhBL4WAM(p09 zfD)Wbi8E-+h0GVbB9~WUC%OMI1D7L|=^b*6d}F|SWtdr|o}V>%kcVbfWhsSTy7qW| zjU1!05zsyQ zN+~0+KuVbn-B6(lG?Y!<5W6xBtNjD6F~oF(X=Op!{VkXlrPK>ak+3ivz62*J7h1Eg z{25mY*}YGc83l#QwBvBE?2hiw*)Z>H9$FYrhfWy11EIl|^6Q=CJ1H_u)ZLZoC)s_+ z`O<^LUGX6=L)XzwXPVWjyHhZ$q`L(s*CmF=L+l0Bq(@NQKJ;&>7jSBir@i~myQ#ocVfcrmTO!&MLO?*`<#tAB3-X=k+6vA!jqyxRKRTV7aISmT z#A8KRO6Q}m?s36x`cL~y%1dk2#a=*TxLgQfqRlm9i;Jp4X_T*d)x_hqyN+sx_vo1< zLl2T#O{OaK!H4nEC+@JGQ1SN!A#hUL=aMX2~l!x9R|GKkafIEZG+%h%+ z#EIL#Z{7e>+~4%N9e^Y6P5!p^-&>Kg-!z0lEL+Z>b@{%P_J`^ii)Q`HjK>Ph~>i75XDL@_0O8c7g&5{4F+-MW{IIeEn?9 zwvp96;+Dv~(r3v%?B@_lJGOdA?T6zMxHcOGXlhG?DJhxVE!k&spz4{=)RM04r62dd zUVCnrJY5eyWv@PVyCAk!^A`z%9dtYjt=J8ITkjgn(v8En&L<&<)F8;tq&8m)LJRH z^4>PEuL;V3_R>87j-+~*kLuF^HU0k2^cg^^{a3QJ9&jAJ$^WCK<6$VGfEwR;c#04` zH{DKMi(O4{jFwYfvKputoD5^Iptb@v!>V1x^-QVgxc&Z zBGXHcS*F68`c`V{ZE=B1(bkrSHiGA1p2vVG7F~8-BR#$)=wglQFLoMIu zPt>|WM{}TO&zRaFG3Q1yAuQIrb$~3G%7&tP_%NEm)qogA_i3=cKL$U<6)ku;cKry1 z>)Hx}a4*LgCtxVaBHUMjxiRf6zU%88S#zba2ufoQ=y=M~^^vtfb+uB-Ff`a|v%8B_ z?yA*kBoM|krccz4O4N|k+UHEs`I5>YdqR9@W~PG?+qNOw-)H`*`+dJ9$IQw5S7>Xn z&~x#P!NNG;E%(BtFwN$Dz2=y?DOu10IbD>-+XynTp&0)@NeA>evFn)nM=9;~{fsy; z63teWxH8s9ybW9NWgLHA|JDZSZ&lI_VfP9{8b!<|EAL0tJEN3-q!8aibM(>PLti`9 zel>`ZEveItNxepdLM9EzPx~SNB(n|CoELu%NpoUKkXlLy_*1M!LI^Zjc7)?(UZEP6_Fj7U}Np z?(T-~&(`;B4}0(DIhWtX+^(FNHM3^sHzzX&Q4)hTEB0;HHV`XJMPsXA7u%M&q+tw) zXMFWmuJZ0N@lu}ZR-kt=X(Z*w(U*kZ__@i~CytGGKSY+s91%Cmkq?-u$=cR*Y%J|s zyCYdiXf;?iDeVT75yH&7%2&Mhpt`wAH7G}wVbusPU8zo6nw9y>Z z+Ur%lf4rdDI42KCk3FdRw*};xgjsN=mZ`){(;PLC>umh3EzVa7O}k#;3lL%gzj$#b zyh)w2P|9jv6IS|A&$U{?N*k0Ad`R=KfQH>GnP6eFc^jLDAeFdN%E2y-5n%mO{Jx<0 z81%Ttn(f{km4&>;X~WoRs5Ja76FoWE(cVsLx(BW1RoV2bl!Ewhc1g-|R^(4y6^<=9 zhS`_&L$w3xQuTsUsPJ2xrZ)1X;(U8?jUU$!aCMNgN0R%ur8~W)2R`oO)D;`^?BCR8 znyCcf6w5b*N@C#j;`QG+b!l@3arK%e)^!XH_XzJCCaf(LJC}Zg!qAk=cQ^sPe$SAm zCl;5NJriv`A0HEwo=6yOjHZ#M=u?cTOay>?RE7+F);x_nN8nSOOueE=4n|{jPu};~ zY7W;(?7HEv^dnJLZMHki*sfA@r0}-`^W^{UqKPUj?iTG zvv|@BBq~8|PDJe1ZTmPfT<>cSp^Z7p_=PVUZ*3ZDR=^=@SFgHVk)g-JT)TA0N~0@6 zA^Z3IEj;_XD&Ffu(d&v8)jrZS^q}cGiw~GEplYZEA-N*5LzZsOVg3xFrC0SAX9_zn zU}R7=()yC#@HuaD^X~26NL$$e`@D_%P#*wzF^PY`aOmm&ffhIeSm&8uu+PCLEp#i8 zyL9pc5_|}6d`8ZZ24YCgS1qHB{gVO70vP|#+>iKeuT%N&9s+!E(W4?5;B-T1JJIga zyAXvzXV){*f)DD;IVQp*++vS*+hW|J9jearbiTVWmED5hTS^ag;IQmoQe$t?Ypgmt z=*GKB${Cm&saxDRA}ESsK3Pmo)Qnsy|K+t`0MEk9TrMC{`cK5Y1b7mj>BTPo2}1l| z%>j6T^T>z6V4wuVY5z}VBH-3B{jN1-0nXx?UX0Wc+Y~kixc>$Rq?j#G4IvSBlA=x< zb|>Gm1sI4JMDma{1gt(<39=Cgw>o(usbHMGgH%f+Ac`}2rxF>U?($F`944Ki3uLz( z3=R(78+>_v?meZ52Oqtmv}C<3gh3$l zQ^7l9&38QVcTF8bRy@HY)O|D)en6<^P{Mht|5m&^9#nF4y9LLN_q7({fJ@w*+W5op zH$*olY(p|#ub3E08p?@?S;47NZ#^$rFG|s<4OMZ?`Cq)d->LFs2ii`n^m)1c%JACi zxr5HA@rM~G-+i&4q3d(_Vk?@dd1P<|nwAf8apTCQaA4|qL%ZN#fQSwJ;<(IKRK2}^ zZ=hzK zwURYQq_zrc!4+9ZM44{vqW)WRLjtV!A56>qPvY1Rz_8Esg4O;j)5ZZKNoG}*q5t&; zFaRlNzbl{S0fv317bCfiH3tKgPY}n

    b)OlM73rYT}}V+FOMJnKV{#GpqgDC249w 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

    F@Fp`?j~87 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 z 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 *wCUEpDP+IcitZcAaffPG^-Y7T2^E|Na#93 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

    #MKq}YR!exKu-p~aR zC|{hb*Efh)!fz6XgS=VdW;BPzfb#bTjPEc9B!;>B!U}TK zbVw19`Bz-Xr`@@8(2({&x`T9}W?(VPlNQ#sL;i%{r=bnF0gGsszxR9rWwFdBm~K=n zUyKb%T$qQFg^!hHkx%q-NOy2xXJe~s5>)Hw5{rvc8?FZ@+CmQ)*6*16)|0ZuYp&5Q zk|s`3zLr8W2PRPg%Lq#Tlu(b_HqpsXH$~0t`3C;e4?I%7^Ir9%o#{wsG8NCgH5yyf^SY>> z!o(fhw6^u6do@NZlc$}WG?8Ml9-;GD=W@Ms8mzePkKJg!9Z+MY##9S@U`_-&I5C;Z zwCZ)Jm0dw`=#rJhfwtdaPdy@Xg^Z=|i|X$ZqS_YHxyJS@@GtOQkX{9`s9cP5f&$FU z!^^|MLuqUf<}P#`IR-5rIjhVcDmm?2%=^B%(>Euuc&an%_~O{`9&aFeO63j5C-x0r zlo;jiy2ip(9u1#!g0$$m1-4ncd!B~7qK*GZt8*L3bQt5Vza88`sc0DH)rq(2eo$lB zRo-+-3rI!3btyfr&?TjK{CZdm)$hG5gSekO0nq^E@5*WCOIT(ckEQA7N4Z@qX1SwU zR+uqutK4E4prb_*hYkLwxPH3@THMawJ2r2%!0}ws>ZH+~Zp(RorzmZ0e&^d&!UDNr)-}V7=m$?IwQ(`sH&%G2>V~94-z_s8vv*9p zoCdMj9*q?Wjke~EGq@Qu`7kW-WoLBK3zu_rmvegJS?PU@;O2U_2G8>l9xHfj8Kw;2 zZI5C*LJ-e#wb+Q4p&@bEEogBkj+E;A6HGWyoygeZ(YMuO9gQ(Ia~W17KhZA+Uc>TR z13K`(BHa&gj$oWmZd6{$V6h$*dt@L*Gk#H!#$F3iL7 zKHS!mzX)2o(5@D3lf zZLLXE{RK^f-IK@HH5d>WYS^I&PzVkpz8j6{i|bWLSI2IdIWak{FXPsFAh)`T^aNGQ zmfghP-uXvnI=^dYp~?14gb-erGgw|?M-TY5}_~m8yIKnZz1!X)#!)~!44HG)X8V_xsS)}PpPC>MykfMd~4t$+CNPQ zmf(Ft-UiQ84PU8%d{OM0kBH(zTS0S~>H!Iq>7%D~=lQQ+2qSJw>2PE{zphFF-IO`45^R7(jHnZb`WVWN+ok`gX;KYzN+ zmdv#2-NjBwcbur}L(`$c^XX!-ni78eJAkA!#DwJLr94(fHWqe$^rKA{`i0A~h<$2h z13B~Hp5yy~a}PQLkw64dbA&A^&Z`8t5uRK)`vF*bwjoBnzE#KBa1Y!ZvHBgg?ZKL& z;$4sLZHRpZ-Wa{wGi^1I<4W?J|Is z1LZGE|Bt(s>_6;#KpWL>rXDze7NGp!XrcmWBCvfF5(YTqh2Ogm2=@L}%|-`k0m@&R zPNHcff$-cDSOSXL`M6ObC?>CDBBo3M>En+nVY=nSSsgp?ztK7N>bhWY8=+(h+{VXFxp$np%FBP#y)1$f;WC1*u)@^W>SX z%fSYF@IHb{{$Q}SZiLi)z|;2r=F3XxcU3*R43cgC1agMex?w^a?D~=8eedoAF|Wr2 zEVN5GeHPZSGjE}`<-OsPiSmNI43MXe)v}|L@FLIF zRP$sHTo_InL=67mCddyGUEk}xB*Ib3L}iwugHHG_=sQR)@}QJ=-`~c+uA9{k!A^g` zecuE_#0LJ}MTw_&&l8po@_6$iGxe=~?C4Zi_S{T(fZas;k&gdsqQVuiW;N$MCCX=3 z_!U<=dzOtOsI})o@lk~pl7BlvA;4#_xHh1@1-Rb`fFu0Zt&-^;f1p(gxD1Uti z^$9NXE<7~wbE<>(`5Hc?FR}%P63!uTU-1UVP4q$NQ zXn(*r<#-D01aX9dM*C*d*~1moVV_I$dS|}?HxxEfJFvHnZlzR-j(Qki^3(EMvpyqU zu3AO;osXjE-p(Nwr75ihW&JjOU!%HNa9@I#HOTDz9cfJf618g9W06GIQ19$3uHpW1 zB1OiT{Eg*IySqu{%rw~1p3ZlUw`QibZC+(sbSO)9`Ri48>Y=KG&v#C8#{=@8dSHy% z%!NWd#yVeq#)iKz*64nZ^*EzEYi^cas-rZo+ zhN=ITkqiHEM{xi&B`1F}2jZXqNqNx&PSRiaXGXx<1Ld#v|D_2ZcJ_7Y6+Ut7Md$_I z`xZV{^VNXsG5xD>q2f@*95vnr`s-7f&_)^0R#nC#+;-W6AA#)HIVkQc6UM79M;C-V z;p@sy%= zS_0V=NbXK~_fU3k6WL=sK+hV1FJJtd0T&|p&B^!gdQ*3bPjwv(#vEMUMo_=Lm$Euq zJ2@U^qBB|GeZo1KQ4(SZ1CxKJoQ-Q9AkLx}D`nUJ=)fJj*4&wa@g>a16{+vu?mo-m zUPhyUA1TU?tBVh#fY)1)aRrRF;bVY*dk8z?xov(##2AlYGUJzX42H0;VO|_4G(vo# zxnG!t^mz5Eunbi+@O-|%+#%|7u7O8{xG>dGk_y0dj|u0xP=Y*T%|U+aamu>jwV{r; ztOmK)n^mBVl{Z4m{Hz%3A9>8_&{M54d{i&>DdiGe;XAQ`6UzA=pKnQm094g!wv@t0%b{j}GpJmWUN`gR z<2XzNsiCWkgfuIrmYXSAM|e6vqO z;bN`(a|0UFn3Zc+^QFV1X%FZ-Ii|kpwRD!FT6DzQm+o-lk*>24C3-%|o>BW7uEif0 zWyr_JXNwcHpobo$Z&oi^1-Mo@m%luuSH@`uFsv%|m6>TUe&w{5x(+@d@8#oYp1b&| zdTU-X6&l5MJLaIIYw{v=I=J<%oUGf2I;2paUUcegtnsT0jyzMqH@4K4@WM^CMQU4; z`dIArR^CmLxmxi)4Ex!yo9;{2f+=X+ycZ+0ye;J=*fR^ zKs8epK>#W&h;@%@K@&J1wIIA7jB2_Zp8e{vdzOt6pCt2mm5RvAHf%e{P6v@T%tw&j zVPgXjqwGlFHU@O6UF?(Onf%tlMhp$?-!_|4i#<+Hy7bu|Qq+`6rGiQ!u-b%0lo*p* zWG1G)E2w&@l~hECz4|;Z6EwM(Ts$I*W_|Bg68G83=T&;He^&X7v(1?78gkH%QL*x8 zn0Sd^<2ee4oXUbCM6_A`@w?GO^VAVlg1L5EZ}`T@)$g9h{0Xhf;MuFAg+ksDQOuyH zvrOpkZKMWhM@#zN#RV>fY+7?lge`>A&onDlCrdq7fD-4Kt(-BjqXjqwIkjEame3|c zo+0}MESkFS`h4tt?psysYM`Yo?0LgpzeE?5^#*>ANz)jSxF_F!3&vyZ?S!5!gCqLV z#JdK&=QtZ*m0&aadNacmljrr_nf?#a%Z4;cxw?qr)+eVVZe?Ha5w=RpDt8zvI~%eY z#%yDl>ktCk-?eesM{8^a*r!8&K1mhob%VQPyK)<6TNGHj0C#n2QZk0vn$kuk8OL&@ zP(7O?PTPvSKY_}GqgxxMX$`Vjx_au{)l9#-H$cm3<)l(vd-=TiBE0-y~kM(4=Q-X)OX^ataV`D1W9wnn7Tc<_rCbT z;uqNuwYNo@e)TS&r#P-gxM!MVK;IOFk#WAzsS(t$_XmxLG)eJD_I==Gr^2=6v07ySx`3%-O)tSPDT?!_1x0k3yc`iI4%$=W zG#;ZV7ykFyuik^SS%~#2u-23dUMQn#9n``S9N&{GM9GEf!<>|rC%oot8YQapf+4oK zztqc};&3@~&H0I3HqIOHGs!D~@=yrz52OX1ZsM*pagR8RgGTg|dy&u zpy@1U=g?(wt8uOb|K7=v>oEKBrD3p6Hi@n=@Lr*IXe9Z`{aqQ%hObS9 zEA-hZ4g;<3vR}d)YS-M1^J0^8?NGWD^ds!^`y&W9XTwEg%p1%K>V`!r{+BKSIc=Qj zgF&_jG()&A>9L>>5il}y+cBW5@9$Sodh!Q}DyOXX_3SZvIzQRF|AAkI0@!fFsg>Or zz=oUtxlA(uGt6WXV81~5+lGJBW*D4FYUrh(PYCp0Him@wPRTK=Yxpn)9!Lk;8jxNh zAjOZ;`Uzmd)Ioi`ML-hFDkt!rOGPd-Pgto+O$p`?6ejhKEMBs3(BDg6xFD=X;q`wL zMW=?IJg&i_K^HI53*uhN9OC+>plJFs1 ztmD#DSa2QVs=Z?r$Q$U52d~Jdr^J>OdC^xxQ)Qf_HqzdI7DI{k3XdeMpmZHXh5Zh` zNgTbO@I-us9rlrpn|$9PWg>~Z*gN-uKuB+L)e+%|w%V@C9`jF+BhR@LO~a>bMD+>n93sn|VF(d#UKn?-7oB@* z%!-G@I;s*2hCQ;vpKD(6bqmHxLdLbBm1w)s?$Eb%JFiC>kgx(M_|C;Ln6kWe*7Zr1 zrY?~ZMMtD9Gxqq!3s}+xR>AsnbjmVK;eYIa)2_iuth^ss)wN8M2&F9&V@k7ww`+VU z@=Y>ornRP|X6cNgx|CAgS(A+MSlO`x7pJJ?|3a7;Fb{9{?I0|VzQEG@O;NH7vMK=O z@}8dONEhiSn!*Ru)WL_)(K5P;#=fsvdt~Wy%^(=U=M5x?hISV~L4{kYk+G7I&$9{p zKm^Mi*u%h-POC8u?s--#>?(U(Yz}E9E2(vz3tc#yKp2ks_SGrNYh9ZG`4e53szcd< zX64%1?H^cWAojkclJTP=Aj<|Uz5c5g0x-4k7uMy!^V?zK&pzv05 zb*F-B1jG*G($C!Elij0RHoE(YnjWxiauNRWSTK+IIh`bPSZ)Fry{fvDJbdwa>nxoN$83Kuw6B@|jRQ%W#t5gTq|TvA7F;jGJ<)0Ze6z+n2$~ zxTu(TM$sH_RE7Nudu{lu*Q>G|Xp7!Ow-3RwST-)toTFUZcR^ifMa$i;IF}It()KDT z6{U!!M9Np8nB zBPHsc>7P@$xgYe*mUzLGdmd3A^pHz;JxfDisu^(|So!|A-vd`p5lN$lvwzd5Wp;@x zanE(o2K}`@nI@q1)zipT!U?Kx?J%O?^|NyKp1I*lx^BoJrre8IqM^a%8qBT2@tLe+ zx<6{oS|RemSrD{%-`QYnHlZ9xIF}pwk0&Y-^|mLo)fKwFk5l&^L}zItAr4b^!>`J7 zyKQVr4{rx4#@g7at+xHST7B%VW@A^5%Cc3#O&ISk!BSt>LQF3`!ZFJtpNs1GE3S8q z*2f$X!1|fb-oRt`@?q!AF8QGCxXUIZ{iNH+U zOgCg5Z!PO&XCsg0Q0lFdgH}m2QGYsG`;QERs{8aYnbwDwhr-$v*a663=w6Ld!PS^c zLbE;&?oqm%%u$cN)Ko_bfwth%QRA`56){w*E(M_JjI@S(?nkghnF-9=ET-F9tBiuRpO_+G=N0}RMnzd;@nBBo#v)GeEJW=TLw z?DnuGbE`ZUF`mh~s+hj@b*83-i{{lzvv_Z>R2P7dS;_QN+h$lOfVVQUl8VM*cFr%j zP$4<;Lt$pVE26z1N-CX2sGWmI`OZ*76)>AttL5S8uDQ`t8@RP%B(>cB_!{h}L*lu` zd|NTa{ZvWUxK@L2Xko-eU=3Ng##IDsYq1GBqI^d^_l=!V^39{X*w;(AXMVeBc9J@w zQrsyBT*ne&GfUl5WUGxFES0UxVfp>=cR1QCau<50$Jz*oHwUtQHIA5jg-df`kBdLq z8-3tr?B(M6>+$xJXq)Q5dSN6krf)=NncVvp(`*xJvq#gZ8Ys_H==?~GD(qdqHjxi_ zSLkY&#*y;uDQ1!dYkp_wt==$ia*M0Td4%L@dQCnL7>A!m?}ba9JadTi-+;GMqwTBq zIFeq#T5((*zjGf{O@>XKpVK%SR<*gbCI~lj(RY!R*;rh<8{gj3-fF4Bf6-kat$|*g zGk-1Q#&uM}oilLX-D@J$wH;DS`Jw^FK;{6K*9;hCEF0j?TLwgZITH?NHpdrnArUnBV9i$&Sdqg(x&mcy#C1 zmkZs`E!yJ zfMoM`W(5)O!+`R?RQ`)y_CN6Z1F=a$oJX;;fC%sLpL;6cmh!7b;=f>%IHJeQ5otd3 z_ATUdS_;?W2eMLmA~|}~BOsjd5(}4_A;&Wvq>3if@jJS8luZ!oz#p}IZ7Omdc8peu z+)RHRc3lgJhnpLC5P@RS6c4cbwpxtau1CjJN+H?dIrWz7VoWj~nJYGTSK@)z;VV;x z($`tvMYGb$>zPl==c^CoF{Pa<^{r_mJND&8h0va5v-ThScba?`H5HC@_WkhHAT`+C z8Qg-ceA@$prKYpMFz(hsVWrNaxcc{Ssw)!IrH;7chp%o5colY%R7=?HYyG|AMQ{wG1-k|uk zQFDW-80WLVaA5aYeF@3?tU)F!D6PO#md$xXnFmSbltv!&>iOJZp_DI_kb!D!Kdsct z15z(-D9|y_v{BFeYMcTi(W`oFx2FKi#GSJK`IqBLtq83vLowfWq>yU(m+ndDIXcP9 zCY3%M80kxzDGUkh#TsD1m)zpwCJ4GEMI;`SSknY@!d?u0s^H6wJgF7BcV@Dtymr^M zc-eIXMQy0N6t-zTGf%o2^FJ3&MEaox-dK}04ar8Pq;z65e3r^sg?%FCwz^~ggCIce zc@a9k^RoN?pkzC_|5!F#DmeN4f_U%rI?ATR71C}yBDWb&aC0rtuBovc3{!gv-bVAcrb z#5p8^cE0r8xkhZ4#@f*Fg2AIKUwowNrA-sv)#&ju_5hll_INi4du6dw;3#JV0V~es zAYu_!;2l;BPTk4BqQ27)nRI;-!w-}5nwR+W+?Fjs$mRaffxR0MmeOScq_4Z$( z%1|9<3-Kv#>-a^!NZdtTjCyG8^0o>=JTLQn3h|i1JdVTg)9YV#L9Jo0A#onfQo3IE z^=^c$5$8ck?XD*tHTz0%2}+DpmHeg>F7WEV?Cq}ZO;!=h+erdD6Q}GeCJx0i^?PFJ%*>>N`T4j{Wu8z z5|S{cRsBi<(Kijx9nt{GRG=cq__X6mkp#K_{ftEJ{qqYsnSwt=uqc_fXvZ?on6%ug zMOHS;kjs4AakqD1^Jsjq-f1XH2N##v%wB7W7{o?^G?YqXE=1mOZ4_A-M**`1=cxZqIMM>og-n=f^FK1~Kq|mr#~>bH z&j97`eKS@8>q!msmYe${5@iP|IvJ*~R|Fd9yzfUfp-3Fj7ia=se!nIP(^sY$F5ECG z=D;env*uPi9hauM({Mjm$&~a3=}Ym|2@$oLQyY(9`!l2gpNcUbev(%_r;2LVRtH7M zA`@0`4jG88THnOmoyQ28ky@Qds_|)o++w}c^Qcn- zo_VMbd^?$VamYLN`X4=y4{SgKKGY?4wXX+HpdjE_+&WUXXZmhW`rm^z21V8$){oLC z*w?~7#8mX!9V!&&=I9We#ngA^kP_OzKUMF?bOM(XMV?$1>MbTIelMWD8-5yLeB~s5 z^Tn`C(G0l^FsOD6VKC=RDO*{A7aSo8@;I>%THI(kd+NejuxNM?8Cxu2>n7rdn*mFT zHinbB_%+m!wgd}m9CFeJ)g-_564cKDhUnrJi$_66KI6O? zcHz~B*|8~{VytyCTeLJS_o6*^-LRJU$tM?v2G@d8ByJ{?B?xjst%S5)^oX%-aWe60 z+^6SuUm$a3M>pluZAtLeVHQk5D?jM@_Esd{n=A!n=7~MMRC3OSb=AS)h=qGZglldX z5GggHM>vWQK&T{iX$>6vn>dZHa#+nBmfpm>b*J#Z=h5uF=HLoVh!=o%?sAWlh^|_H z?hXF3hHRDU^!TE?$(~LyDUtJr zq0A~3Hm`)-zo$r?UvdIZkY$6YdjG0HUNEqaJ_|ex>X$tU!z%!a;k8TMk zt-;p(J=sMvWE%atBDY#eC-sQh25g*4?9%}OtWvU~K%W}|xZW;gE5kQfgU7r)`dgnGE=|e`SwydP;oS zv$HRK5-iaan~l*_w%Bu={G*|=1n|PQpQkTv05uaWKrH&Nsx1)m_bX)%PNZZEl)siu zJqk!Rfz+qTE1m6Ghy>AFts0Xfga?K|D6|fu2C999Zv|@*+&NB2k4IDrDho;Eudns4 zWT5Lp$oL9Z=k+NqJ@uB!Q^6BwzR-%GbsEp?yc;ec(1o#Y|5%D;vtQ->15L%9A~kxw zcddbsQyOEG*a&lnhCp#cbYS)gKaFAtZr>NKqWa=5IndPV?I{U|z6}jL+3=q77j>I9 zC~PUy-2+mGHC=(NL;N$r;*P6zp7+ZlTwq;=4@H1}EzIcg^I~;VaY!siA_pnTL-VH2<%+qzOiK<>v8=!zVm-5&1*-%})c~jUaMV>a{H|&HiH%UnnODcabT`(Av_{f4%^Ou%Th6;=7-~L^s{) z1_q;rz#DVX1T5ufgx>VA_aT?H*->k!Fm9S#2HT(PLUEAw&6w$$a<&``AxIS44K;4H zR3wA6*mFlY&-)?Y!aldJs-an!N%SO?m9nTL8wC`7O1B|BEM8x$dNh`i4FCN4;tf^Q zk`X@3(Mz%qF^x3=duTpZ@zTV`{4hrSS?a@ML)D|Hwf=P)|4V4GVV{ca8pAV6c^pT8 zbs{$nlGsSs#7O{4V&>zOKCd5i=TN}`ZW4N;V&{E>q>3p{#~H8bE? zL+Ul1KRAVeaj~*)-uT{1!@R4&d%%3H+(3pjh2N@#l0^m&Dk$A%bBmxy&%DN55KK44 z^h)a4&J>ze1$*y$DGI@9RG-yOJh^hgirkOy;57UVaf}$1E?=*nVuMz+ZKq?s!7?@6 zRWpfXqAX@UqL^3BDKcC+=h8ICU$aVGP|=Sd54uMB@W+^cm|R&A(OiRQU7GN>uL$Yz z=mRK<8dnc5pj|0Cc5NalY^WTkfq@Ll`AAqKz}?%#b5KsJB1|E&rL zF#ys$hR11xf0t=ejd(Y+*ui}bBCuIfw$TvXOF)g6C6#3k{$@HHk25SYbH)(OTPY}} zzi9}!TkMmE=i67?={~l_Pw?%A@8vl(X?q(XB5nhd(bmCsy<4vy!<>lx^L%5!ysJ|Q zrY4YCJg;k)m^tW69Fscwnc)Xt7pp;^fU3T{uhka3gfzw^Qk2~bZl}0IBjEZ$I@d%# zqrv>L+s3@~a)Uy9UQJq%HCENj2rQ{wIYkFE3iSTAV%9P6t@3Nvb%GEVbcPP4oj9)T zG{{W|GE==SB2h?P$QgQGUWLxGrG~Wrb%8POy+7Pod`vL%jyivN&V0GWaecN$yzOPx zC;*&!8|nEF4bs*oQuVb41U;w={@q0yovUC&Ny*Q>>++d`vyL&hgvk06!UwCgcw6@J z&kpM~doU|}?Aoq7PUd-6_2K!c$;|T&{1X)nSD!`~QI5kRL*WH(IF1;w#k<#$8$`Ad zW_S8r&zb64W%3<5^%+b3QE{|LFLZ{Aw_Hf*}DT4<$a23BFw z|BZ_~^Q9R@?iw6@=oH>epR;SnBt<+*r9Ewx*gI%H zznD)^>3Rzm^pCg6hI-rZEWM2nAsjUoOA^RV>G+b;Jzw8obCNq8B$G9Yje+o8pABNQ ze>oYgfd7DkUz>~kh84?vGJ1;yCZW&VVD)wraaJ)paL*bnqFRog2#jzQk$C*<#rMj6 zyKM3im91b8!0{yZo>aP46ap6ekVy+xodp@C-ZS>68R6HIt;X3i6{Cfg{uU`t)4r0$ zlyu4`DVcAE_bXD8VM1sjAx{pMN~nC$<8#r(wn2}i0Vu=L!I-BdmOd|kkocnjR*so{ z7PS?y$EtqMI0W_*G5kUm9Rp4pp!~ITE72pst~5^)lYU;Q2{9hO)t0+=yE5!9hnPf; z2PVf7$~`}K1q^+8HQOQ2v3$*Q@P1@&4HM;>Rm)FA^K~8fjoQC}x>F2nH1)Mj75fqnKDfMOrDV zAKR5SuT-u*-Fcl%S^ChA3U$lTHI*kt4lQ5>6CgjJFBa%9hZ}+#wPfUxT0p3pvtRn z??DntwQ8Mx9>rb|i}%#^@OG$mYnH z<=%iU^fJ5CYS|hF304NjIZs&-nV)K#`1sha77nuK@Wl5eaVjgnp>fJh$OP|#(l>x5 z^z$Pw1}|p+ycieW2vs|(B(e?n(PjV?O#rGl6->2Y>%56d&Y;GVPvPvSiVK;L&E-_= zGg!mdPckO#bEg&WEkc)WO-xnJUIT2Cqo*`2XLr8}z@Tp7Dr`p&yPV5lN9LWCD^}wBw{SQ+XCb=G4c+k?d4TymzMG_FSOG@>Cb79 z-vJNfNIQMA3V6`}LBs)=kAD>pI{?oC%3sf#nXG^VOx%H3=R-&?_ms+@gKPE{=M1y5 z_Z*qCB-G|%LWHD-YxQphr4baSPxIYOV8 z2OUF0<|J~1cqCBeBv5a;+K);dd9l=%brv!oev6ZyE$ATJ0`dwnQ|Ta2g)?*%2#iB0&iBToS~a5xqG`^sm213WhH5o& z(B>+jAXaSQAwuh!q0_526ePI!q&;y;2glx<3ih;{rR(vA3X9b7Pn^M5z~U%MHx_RI zqJD)xn|*#o{yKn_0m@&ia}w7Qw#@j!Q>an>yb>;pLKbWN`fzYtjR^jO-p-(BQIT8@ zXMH^_HOdFMozHKuBY0&Z-QJQpc{lUOQ^4cbT0|RzQ+SLM#U!g(ycY})9$D$*F)c)C1_yndZV+DHgWq-P`Cww!YRu+Xqd9$w{tVY;s^c#ywsu z1Kz1M>&Av9C#{c>IAfN+kJe#bB)N}Ht9q$USC*Ap>xATGaBdr!S|!&TT%(58Exu}I zwJSv#*W$no_(q^&Ao_%@8D}FR!-G(cBh#zWb#u3#JgLw@gPD9h$XKKIFn5_%VQzuy z0_}NxAHj85qr&pDT4A!iB1y-xhXNx_G*%I)BTT?s&{n{;pe2qB5a)V(-j``xLD}w{ z02|X2jDDLONn(ru1!GD_oGycc*=Z=4!T^IwK?UhJj-H7w`PN1LHuH(Z02`I10@sZF2&Bbi=UQaOiJr-?Q^& z6hinu$*@u|jL|B(v}&~!*pAcX37Xq?OKfA8p7r6yp+nbIaFExlHSLV_;@Tidx=L## ze-sqAyzXFjoj#OGMKleM0d%HRNPLY+JDPTP^4gwx^Wz#)VyVas#U^WC|Bt)TX(21k zbVF5PatHT_!e-U5Cz#+=lBf%cWVb01lZT%Ql)#07iqjrP=bURO_1SH;Cmf_k+xKa9 zb%6P|Tu!^zHJ}Aan@nzwIz}S5OGrfBM7Y$|X<+Bh7PdgGbM`LwRPZiG=1ioGsvV-i zS6L??!a@Vxm9AT3z!^ehp7^B`Gb6^U#cqm^;#|a;!ODTmiqQVG$d&wztLWSh)0})C%AgwizZ;p!UA`=uY=S_?BbRX zZ@WEYtvji^Min`2HC%v6gW@Cak;DG* z9!R~WjzD`PWki@W>w0UG511UK23{&MV zp?*bP?HHQfQb-_SHeCjhbs!)qZNZ}!$zv|?*3w~NyqR%3k^0y@=6+wCN?ak)Gz|q_ z5bdYTXU3=LZ;)g(Y6rlpukdV7sp{RWJ3edV^H?(pDiIf-756I%q!K*PnII5lvY5zl zhE2FzpZN?1B28=N`R~p-)08Bw2gZepC77~)1*Kl!h!_7tXpVaTTd=`8vS;yI^WCimynkl?!a5txylS$ zciS^XNe(JCS}Jh2L;4B(F3bCv2H6rdwv(k_l;?oW+F#uIO`S*U4_Y_ABrckd9 zpj>ZT^Ivf%z&U{NSGB-@p*kZ~kP5{SMRaGGlnkDZIbQOko^oYQC7suY3m~5fh6gfT^$8~Y~>fUtw<1-zw|D0v(77>2H z=<+?aECJjK@lt%tVcbiBbtg=->?l<`2(#k8=hdWHtF6tpO~%<3%7<32u7-K0mkQAd zeuLU&qna#aZ%P`>{YOG4K`Wl>?jSjKfu~2D;ZcD*&y#8)yn}IT+<2I*^r}?ybOUl4KdTM?$!e5d^Z7jV$Cwuko;{z-9HN%63Zq z#B$|H?KSj-=x-u8U)hr_8B1_VU!!vMcU&1)^EYDaN{Z3CkJ=PrzMIP+ZAdlt(Rw$m zoK z%l3lNUpX&7Sgq~YW1L%#f^a!;`5+O_?&26sdgFGU8J6qN58vz^u93J0*89O|<3>}9 z4dbRPJo-x{`Pc*7R*aidR&f__4tVfS(jQS}JPtZYUp#NRa7>Yu`-}^<4ZueYElAcs zpGCids@xG)v~7s2z4F;AQDU*FHsS6-yIFYd`J0d_S_*&vB)7d6KitLb4=hX`Q5Wki zPG>t!t7I!5L^R9fGmpEk(!N6B()4WymN7O^(mF&;!38_E6O8PkM%s>tMla&xA~IoK z8UyAFDJ`-`ibsMv)(OdaUh(DvMb|Q}a|wf)Q@ZD8J)Lk`Bw3D6qg^|SvaE7XYDyW@ zMbL(ZM4vUe8R2m+jZ%Zdt?h%h9MqA>8BON|pL(RZ6R~TeMD+qo%_l1)`iDi=7mv2- zi5kT|m^dEc+|L$7@%pnM;2wzHJ%}uXYt$t^o^cgRruB&4fLDo8HSkzuT1$H$aQ(-* z@&ok$&$16zKy$QTM^koyV|~LP&h=lTAa94*ABpQ`>TNR0wCoLe@J>G(1(4U=L6J-Y`p5PoQ>iKxB7Um2Xg;NfOz`; z1Wu-SefN$S{I%`%_2?7uVPy8jd}LIQwmqc(Xx~_wDO$xNBoOrpUt2_vD10OuEU>3+ zCj<*O!##|$N%UF_&+6Oz$pbowlo0 z3QVwEF9)xQr&4~U*|)Cn&=f%MU);nm+47!1e{(zHfFZI%DtSc#hIkL)hWYFI0SFoW zU2ZA~7~dQI?=gNk%S>Mv|(50v-o>IQGuU8 zzPN=c!xQmxstWUG7-b;}WcRAzVYh<>GE5USC}DI3k34|aT2W=FN@!hbR?-L_$Y zK|K82|J1ox@zSU*BM(%`m*r8nM;!aq!N}saG7{u}NjKD>8}T1Qej_sbYT%;<3|Il` ze`wg5wK;ypNB#?u+3+NnE#SEid`+7kMf}>b&g<06Jr2lh+t<+pQXH)7>R>X=*CK5cKG7Y8)V&^vjEij@tJh&#M|w~uLA5}7ick~6#F z(QuJ{V6=w;g0!-$v93++JrL9g#P#Zf%yt!BxsvIcrRai;tOZZBPT2ZHa>BK3@6Rhw zZk-{mSU!->NoG@M_|7>OWEoZ!B5}bb{|K3>uS6G4(y$J_f|Hq(-$go_85$^mvf5!@ zn7GN@d1NX&m!8!h>|jM}?8C(*+$S6T0`V>qFXMoDT6 zAFd*Nkj(e4upa1VlwHx6y<$=!_-6z}c{Yu*9wl5$Ir?*RL)}7*7a+uS^l7w=w6Y-w z0xO5(xyEPz0icWveZI@h;ndp}rb?5LFs=fIV!WBb+cth3A(;*|!cG}N0ip5Ea_5~| zYBqc-miNlR*$~+0jTb8omI;G|(-|IdVTpm@5M^LRN(89~S$P9UD?tO+qKS{YDK>2h z^2lil;OiJ&yy!qB?KA}Q_e_d7mXm?wAx*v7*neEVM)gSR*EnutUG}`T? zJuwZ4Y-fKBWFdE3sgaen#<~3@)+aXn?6Et-C!&S&>*C`S-&=Q6JtxaUaz{42 zS>f|IeXqF4@NB14)Ax-6KFkx=#0h1qr}|{>*-}Xro9ekE=RtM87@L~<5_qw%Bkv5S zxbcxrMVu_J&z-w8Cb`wfIV>{exl@rk-IaBXiMLQ+(bx1c(PY|~D4sEQ;Vw9jN`YgF zwjl*6cf}Krfn%;zUE3BQI@}udyE!@_a&9ZFyQJn!2sR0Wx*t}E*SoaQYN?pVw zj+E#h+-C7XFSDaYe;4W~Gm~ZEiqkR=E)v8l7q8BC$T9wjo(U0qqL!iW8WD?~%W&%X z+4lP!KbUYTzI@O4dz-A6y+CpZkRsGYgfY107^iP3U>omQ*s6>TW^b&AQCaS`szmEP z!5S{wusXqJaYSOO@~w^T``PsJn`&kVT{JRNtD)wRjo%#JB7+Bs*~QV#ur5L=BtdCI zH+5})s4*W&Nf)@ofVPFls-#S-MzEu{d%8AF(BIZ^nw;iK5h_z#0$TZG$g!y1->r}h zJ^{gwl2P06u8v3gxT8+fafk7;O101Wwl3;P=9#{ZGlOrPt@`OH@jkRtYMMzo9ZzX` z=ng{xZ?KwKfHI0UM(FOW(of=M%j?x|_Gx~~L~GDsVRy&!!SGV5VQXinDp3Q&@?r9t zjhtYop#Od0@(X(-T>9e7z8#Lczm!s1$PbtH(;X37QcnyrrBW^1iF|{q zW304=G!d2ic#<)!=NUKR*gqSd#Mu_lu5+N=q&@_jM!{I$=xG<6>AcA;ggXpu{n+?k z@))81q;u#)pUM}^s{;p$D1MbV<)KFNvDrB%7lOVkUb{9%y9#T*%RU2;dmbx6+S9(h z33+JxbO)J}fpRL3uSDK#cEHjfJu25ejyff^U+Q4M(C z?O<1cjXemAX$|woRco_O>Etvz^!XI!)#N+4dh%`Ld-5>aFsEbkbJ3U-_7Qnt$Ru5D z%de@67iG|j%#pTjvt&{7rMkp~6F)7#9C3%hq#0=IrgNB!*o4#D-Lw+hMfKCq&n#Ey zFNI=9#!fK~(gxPIt6vb}AHXfI#b0@@0KthKxZ~*MW_!brY>+)5Dn0DEhdU>CT@Mvr z7|T*cVbGX3C2TkIMDy7Rw$%TeS>jwJ%nZ1MmVi?{CcWi?D;u6nW`AL^#r}*9Kc|4z zynA5C%|4r4t=2-G%o4tF(&5oTuFN{!;_PbQ68zEjJux3W(j$9iDXb^`AfQJ3a%2D1 zRO(Wu;*R*`w!0;FK-08e>i8!&j>gSJBDl@cbR05`)=PY|YZEMoha+&H;7c7h-@EurG;1}{y zPb?`v#VH@Sk*bv=UByy*v=GO<#d$u=JkC3MW}ZA-1n$x1;PmDif_r^|QgS_nO`Hdz zfqCMkynsi&+l-Ze;Y6#OC-zKU{dom*Yt}}2v&r7lvQG}Yx=TiW2@2!|nPY-ZimaVl z+`3kBHEB@Qpd;6vfCI!-r1cpnm^x-0z9@q+cJyf~D(zEYFu30yAk#C$Q>p#rcZ? zTcfyJN#NlOA+aN+9g;N5hKQq&qSHR<+w};2IIZVw=B5ueDPNC4!G{kX7Tdu#=&b)- zu^;t_Ww7tii}lUc)F->Yqydt9DA~lXANJFZWm9_+dwR3%pmY?}_h^fE*iz5P)UHfc ze)k?{Vz9j)?jz}Ab@c3A9If7GlGZI|*Y)wsn^MDJ^laO_ju;ThMZ5WK@TumpN9W;% z!uCaz4vdC7L&)!3*iYzEQ{Z!dR1T%(?Q4U)jLy;Kl*E;kzUHsg4;sC&a?5QUBJWy8 zkBZM$QM|6?dU1BhejGiLX1$*} zs*j`70Tx-dMpYs5yCis8(T2TtatS-Rbi>~u!UsNLtGUDGO@HZag!6du{4H%E5TMwl zeiTBfza3NGN*;b)j++5W{f0jjdwGHf8khkQY%NGQfL(CKC+I1-o@DJ#`xWnIoRaBy4J>jCD&f+u#&};@G-zs zJ9vrv;t~9KeB59u5DgkTsx_SWK%AmlYOL&gY`b?t4k*EPb>JjcoK&9;=VT3fFtT)^ zC1h6aUq@lbJqs;^LVJ(BBG;YI1VE@sLHMc01niZecmp@2phPI3iE+o8t)z3EthwOD zFAg~SJW^ULAvAW7{8tPObM`q#FtICe%f_)y*5_BKNGkQTW=+5>N6Bzcc)3TYbBBYD zzmjm-9G$jIfS=slm*$*K1W{u=i;~aXOrDb3a^oD})blNF@SwJN;4hDZm1$cTtHE=Z zra+_x`K}2P#+MTYu;_yO6h@nW=EO{gEHQ`TsPuPErlqaB-OtCB<#C?i)_J(S2lkOV z0ADdi{zQ8E^V?IYm-#9S=!5UWZ+a67nBD&?JOe1_{S}_+0qD#d{?MC$b**0jk`zSq zx4;eND@j<&r_!{7eRD$(`=sAZkY@DEnoo=6r&*6DFvgndQy^59E{SGYMm4+3!}_Y1kuCpv+eOIlVVbvQ0dKhn!d81$F->;C;DM8)a> zaWD0E9X&U7-*V5JukLw6lVvo29vqSFnc}D>iP8J}#6NR`;icET!&4-w^XANU6rb3K zOKMRdr7vKdJe0krVu1bI@bBt#K-bj2Pn0!)F}~r?aZWKrF3_XC(+N~G z4hCY%pbX(suKju}`{BnF!Nh%oto`1;(C9}_&7K#~0g+CzCvR~v+D~d+tMaOm-QPig zuv&TbKY3-dRS8b7sOKOoj-Fq_tWlIP5Vi!Q6Z-9NU6C~5o!0%x7c(|a`c6_92bF|P zmZL@1myg<{oJ{zMvQ0@osU>Ewik>fC5Hn%3BQnA(0ettIILkwk_PaI+d9`gv7_e3A z%B5nM18mfi{#`sd1bj^fHjTI0VV|f=X5#x=Be=_&uVGLD^Y}J#f)=+|=a^m8aHoOK*WBcBs#s3Qq zAL${AVLND8J5kNc)qt6HN=P?-8&}rwW{R;X4M}l>W83ITSFsg$0NU5{@phl&csyoh zs_camp-wt%n5YX32Xbla4(KO40oG=RT6#P_2R*ZO8GeQdB-=@tk@$k8BrWsDOoCaj zPaZYLp5q}rw(gv?yjfWEG2nPVU>eJ}M2DN`O+JiMAYVy;Qt#}24@3(3C_(ylQx{Y4 zw0{Ds0&-R zXax(a7EfIzvcN_+U0b%(dy6Pdx;W0G)nwgT^V1#_nF_jAXJ@UK%cB@8Sq#>2*tU{O zH@_wb)u}o*>^ZvtbUB*x7u2%Go}g7`Z|KPS2Jw5ul@hdaKJ7w+wn{y8@)Z_4JTCY$ zpi?&{!F$E7?bA7y*5=~gAzy8vnJ2v=J)2iH%4v-u`-(;kT&D8Zhqm*XRDZ=GUm9rD z40zFd^H_CkuU;to+J0#WsunDfyE9mVJbiV5m?f|$f}sS|eRZVn(P z6rUf)M>+!Ce7@>gIiuWP5URleWlh;mn%!*5+rv{&iruw&5Q(6%yJuRKU;4-yNu~rt zQGriDAq4y+(Rlc|XbR@NpoSzY?JeQuGN5gRV7@^ME;_@-85y*MfPIeV=oK5Bjk67r zA2{@Y(nWT!LcoQ*n8cBhNLQhZ3f|Aw9FrENpfoabs_x&rRX**64I4rB3^daVZ2>_$;prC$j3e`fm?ibxxTtRCz>5C701YNub3Q$hoY|i84QYyc0h}dS zs6%J_oNW|AQNItR*;}=oSvcau$yV~`8J}ls2`0vLc*g^uSU7p;eoD7!jy+G*-eDK~ zD8-=;G%I~R5LVk!lh=48;Vz8X(iOQaAX*G=2s54FD14FagbPIf%m#NTIp)c-!q%h8 zT+E;~yxq%QThBhytKtxI8|e!XhuN=hmVCN&py0 zFj?~A6-B*=Eaq)1f85J&gnq&R>!>$V_gV*7$Gd;51HhT|%Q`*+Z0rqxTF0c!n{|Mn z&C7FvLoTlnvf`o8fugjhGLW?aD$4PvoWAH$R$9+jX7YdHW|r9OPzr0rfpopu5i@DR z6yM7c$u_?|cP~J-(AVR3Vi?g~TzzuCO=eX_z;UW4d4R+ER%3OoHe*6~I=|^|Rz(#= zKjG-$!UZR=dhmGXg8f}FgR8KLt}q~Omp3SqPbyY zE07DCA(cy2_wks)N6gJ@4G~@f0WMXNTBmq}MJ%ojC^!5ohIGV$ERC@7EtFXM0U&%X zBdee^7i$&J$0dDai7bo(N|GDod3_a!zHY`vBAJNZEeoX`{JnR!iD^32c{DzG_ZbIJ8p*pGFund&CXK)0=uzpyQ=)s&PPy@qRM?I~T50BgCu>v+F} z?0@20D;i%+0TIUEoD=cG@H&5?R4Lg5Yuaesx`j3QLrvqbIodgWcWqYgG}3V;e#0X{ z!(BeIdu!1I|CF8d)N$GA*J*E4q3DMz5+aptC{6Hb)=2UqZ4*BGuh|56zMmT7BveBwm^l(iJaeG zaUNlOMc<^&2+xl;u?e4q_)%C7Y#cYufvuHF*P zzVGxu`%oglKGOB!iL-t?_c5?(v;N9}Tn5<28~(75=Gc$We)O=yiT=sq5Qy9z8oHJ< z#M2;6@!CL75SdYB;aNgRmV#Se zM7Wr0>8op|nYk(js2VzzvzoH@JjY!2^shoR!_KG9AsRdGAyy09T|a_6eJ(HXu=G8R zBHyW}RT%qB{k=n8C#cd0Uk&`cFEg0Ms4We;3vR`W^0mPm=|97}0z8wbzvEd!{cU)R zfO@B2&m_fwjqweC4DZ)A8x5nJ4Frzd&fl2%zl!DG0cOm$|DBT;Ag}P#-`5mCG#Z@M+N$$m~H93T%}` zVA^*mQ5((ts-pH@Ao2o@l|8zoE???xvKFq4=Ht1G#M!HjZ_kZTptvyLKUuHgDPJZ} zKVG|Ad4XIJF>p`EbQbi_;yHMCJ0X5U81YspR&_5KCRjk`B)?GF2#xjI2FDfn>dWls zL)H*S6`q*3h%O76S`0Eg95Sne6t0HLNb7Cig<{L|phNdFnny=Iu3vnsJPuxprIy+z zws>h#yiPrIHn>c;kUtsUUw{!#aSQ~Rs0fkUfJ{hPbPDaW_wkZrKn}$4_x@Ap=`X|E z)igC5g|7SIied^h#_%dqYv zGH6@Cx)ZusedjS3R2>@5h&i=`T1TgxP(9ug2(3u9H{jZn5{H_Z=*evmX}|B=3P&Z1Tcck)#F@EK+|=KyVus~n5)wyY^&Idyp>y%N zznsD1^YI94N_LO2zMoyGUZ%>|LTROIKo}UHeSd2vn5&8y@4X!y=H}qm5JajY^MTv( zaSySxtY6MqgLI|idTL`_QpaHg4;A%>0E@Sa-%WO|7tVv$Bhn|$Ru2;uvI6f`l&i^S zK2x*7m)b%7=19Q*tH$*)Y9vDo0WkW3A)(+M6bZ~R@gx0DA-tFjV2uHwtpkQ|QOz$` zJ}a!Sz=`Wa=Y0NcowmS$R#0JFn$X;t2tMQMio&|U;*MuG^MYKp1V3T|h_>OG<7DWJ zW|hd$Lx3Hv6|0UDm?uM_MS@|!_R*Qvg!xu$b{0K$qm~ta4NT*L-&3EzXT9s#=;bl@ z6bs~@W*tqEI92S;Faf2T!g4h}T~u9dQqUm0I90vDb^K!KL%NOP223Yo{k*2(H{dT; z^6IP zW{RtyQ8aQ0F6TMlmd2**Fh~-@CVFcpEti{qKy=<-+)TEdUcQLaD1Zu+7+ED5c?XGN ze>NIn=b!mFm=^rh<+e|VB`1Iquql7Hj5Y1yOxtD#pVMer{R6HeZIQRdZmjQvUnJxD z{GjV897$I6X?D1JSW`M=m)n+gB$Bl9@Ig_x?O4-+lXJqlzmlB8tpEpuftz~ud4}?qn8xp5ab0{w{D*k(7?uZDpJV z?M*V5_{+oXUfNP^iMW~1 z@h*O%`|Y5Ycw_RFn#jf|o^g0sR;`Ml-=Zs%d-NV3;1S>1IzEgk zDfEcUN(O)$YTBtRSqT?bNe%YIn8g^|x#xE`TlMIIi{I z0wQj~f7=2JpuYcCZU-a44&LymEyMu&bOR!8ku_0F=54mMzzjbeV46_fffr+YTSPgT zT_HZ~t<73DPGx!Lr>hI)a2f0iI#IvRiZ8&d_;DERLo6?m4-6IMiFh9^y5dPL4{2?~ z0|FHv)P)^8nZbB3wNfK*NGdj+lxy*h?-ii-V9|0hXZd-q1>qBEPg@s@9@)DoO~ z!XIDIraO{$@`izQb&W7)A6(;=sST+ZuRoyh%%snC#W?pS-7<^vT0^>GTYk2#K$|Moj(_>ePOgYlkzR-pVEzIRb6hUN*whc6bQpU zT8OnCwclAk8iVv<3kEn!-Tw2K2GGA> zZw`F`DR1~g(s9DazbG44Ny-&Imz__2P7K?9KW8--p6CI0P2xfiQ7$V$ZieuT&gudk zdvHUM$6R?#BnpP$0~t&%aWe*mic^!yy?T_NaJ}~N1NwgEvZ3cCpd+pGDGhbohg82c zNTj^|Y*6|z?^@5TBL5Kh;PO$O{FMY9L|Yxk+(Wq25fxeQ5%FnS&P!B_(htdbdqBsx_xDh|GPlw{=SmS*;~ z1q(}zBVIwm!dF&b;azmifKAv?r=>P3ZiH~Rt7J@&SJNU2=H2X(YV4xFZeJwA7f^gh z3(@)3=$8t0Yr95`43oCMReg+0frisnfP#mPi_~~p0+Jw6yYB8q7o=~_6bI4;q7AIX zyW}h(?2(7sjV{Z)t(P6{B!o4vDH1oU=)if%X&6)-=Wp^oFpe%W8T*2EI}h5hi`BRa zo3zUXiOrdPhhB_V&1<^ve_rJ8PXH=!>MID9~xy`T+S-kb{yw5roZBh|IeFd%|ZAaLhgnDGpCZk4%D%MuR5HG!^ZtEfHt%E-g>5t^}n`oaC7!3OcqE zbR>mYY$f%B{UBQ=S@VE#uajyLq*MaR4YjTY2-DzI&%YCMXwjIDG=l4ztxJ-~4Ag&% zjvf&@p=hu%mya$SvEP`>$HDO!lHHoBh>K+rW%;~uhcvw_nQfR+gmC)>@lI#()sp{4?$9tU0#&w)Id*4HEa0#N8fSar(_x!8G7nSwjeJyUQj^3A_wxeX=J_}rA z`T7DD99MI+(|hEq(e+h<1iHEI>m}Mp1{K2q#?+-t^f(l z)w@1ItCoE6uJg*hvKPp)C?Y@uRI>lKR%>sMw($kum(G8Cv}FdAHvWoBv;#Ey4S#60 zQtV%yx&mgQzJdu?)MZl+*hV0_`{74B1#58Zg#9pg&yF1bE&#mb%R%gi2QReIg~Qw| zTyJ3aBcAq!iwURqM!aUX((&cl*a5DpXMW8NNB7A+P=AS!`D^UW#i2!Kw7lSIibcH3 zv{6$3Edi0Z31a3e%7AEy2-qc=b#a_%)q8J&x={pIIW-mxT2&pq_&N!PqlI>tCF#UZ z*2DYw1Ux;w-Wi3b?603cnI6}^8A<_$?^speD1A`83L~vLi*_%XS&r2!e>9LPoP5T?j{3FKrX*@9}+zC}e3=~(O5J~l{ z>R_cr(l~X0sc9E6DK`~MY~DiFxs!Bt)0r*>zG2R?&V5FL;RzGDN?O=-$V^2Dd`5!7 zfo~S%bVpvGbJ(&^uzJdq3E@fh(yE?#o}L z_sN-6p?Dm_r`f&4TC5#)b%$$7W?H>4F9o7+UXdFPeY;jdQK(o^DX7}DeBp#Xq2VBb zaVYZ{LduUd4{56iZk81r{)$VqJuP`|5?YQx@Y^$VF+g8#Te9`vDBkA&c7p(Y`Ns`{ z0ytjY@Q1=o#}B`?cI!3PL{YK)#z~6&y`o|romyxS2V$xL4O!Ib9ZATPU^h^*dXzxZ zM>mZ}$d>6k`AK3^B%7k3CXo@a!h8&s=v3WiG2BJ|dTU*HwPz!v*G4WTv3D=Q43QdW z4y2RU`CA{qn%nIru}laGO(b>EL5d!&3o-85H+@WF(EawAUP!S9Y~^4xx5tQC$Pm@T z(MQ|jhFd@!njz7_d==aw#6k?c81KGQzq@w~UDBxFzHZRh3l;+$F3H>1Wbxi|!*T`nCzY^dsy+TthcZzdG>lO@}~R zZ(0vXqz|3}0vOwOEKF$@UxdH}Q6wEkIX30tGHe_m20nPY73Lkrmf27<2qTZWy0zV7TDbg+1)c|dx zWoO4}<6-R*q=s@J83enl0`H8EZZUmMa@0Y}x%fmty&JY$UmCg@T)A}nNT+jhQ_V1I zxV%jN*_A04Nnt<-*hETXqA)1kl(Ca@)r5q^HzUO}UwmvXjj`B@X_1CxZkbR=kaV4f z6+-m``IA?oOChVF6EGfBh(d%nA(&aB-Z1S;FUBabze~Tg<57)Jfv1rDyUqTLzYH zxA4rUDW@&A35D37o-K7`VJ)x8s4Vd!KQ_iRa0=MQdJi|xKM$41Z8o7TQ4h90bJ?QM z6?(@;1bHFd5_YSo9w)-agzn~6dXC%(uW$KDsg9hm+M(!wksWqXh0n|U&uRX@aew~G zx`01PTtk5Qs(n#qC4p@wMj{dy6?lRu(}B&YPa1)EzG7_)zMHe z^25!Sw)*KWHq+VZfi9{R{^~a-wIZTZqH_2N6Ce#>JUGo*Q zDV~frc40ZdvsQzr!`%g_WBPvn{9Qr?v{A?aZ4T+k-XLd@vWd$wyuQ<@yYM5>w3w^P z`a!#wM9E2veTq>fEyeCcF>2Oe{L)YQn~+zX=LUG>ku)i{=Vhtsrg`L9qr`hGz6h2S zo#|OIyM6*r$At&3$fSPfHDb%If@$A1^Q8$huK1fcfs&Np+kCurIzj{zWqHel`X^(J z5%4JUE2oMDV2^M3!-lpe$^o2Z0G2idaEY&bA>vA{;Oe3){$NJ@w)lDa@$X6X$tClf zVDL7IgX1%o=B079ym8)p7P>p0D?t+Bck=~VZJ+TDV*2Jc2M5Ui_|ApqX$j45+6W~? z1G98ckPl_xEb@t-I3^loh=mb_WY*9ylYKVIAt! zqHIN3+6o9@k9G!vykfkf;ZxkfXsa0Ym$Ch)-ur%rlen zt0c_9zfXnqM3XGN*aYXD_KUS|mN7>r9#0t@V>~4ntRY}Tw7=Rc)u&3rkVmBMv79Cr zeG&hrS(o@k&R&zeedXq0vZ$f@@>_uTtTjR^`l z+k%n`u!{EpZke|l9l)7{_1ELmDqsoU@Q0+gdc#~DR6va%zl^Nldu@I!lS{B}O~{HFm2;FHc=EDk zd>36TH>4P=@XNmZ=wJtt`Oo$h4;Z-(C?6a>VB}Y@zvdV~i^%b7yIBB?`VD`K{CKh) z?HwT`$atCaj*VDee1ZtUZR0n-eLbM0f$N|h@UxPMqQ>S)zO%@5y)mu*-zNI{-;{&x zpC;xd0L6I2AD{bI<#>B|{Zq{VG+}=y0IdN2^c((vBq0DK6<=ebp1Mhcc_y6j%H`mpRsQbB;|pxNN)O7v~mK!DTu46hS z;+!ai6Zo(fxOV}h)z=rt|saWUVT zmOp5%lr359+I5;;@~vsno`fO%#~R+K6aQ2yz}qzQuWXn9LY?@p%k!31h6Kma%nVo_ zt$%8z>9sk29Sau#i~NQ^S7+we7PKZ21vwBCgw;>=BkBQCm>Vc^0)juJyJLXZkH$9e z29DzEUW#aznc5QE$M{Yl?^9ZNBuaYOSHW*|4zwePkMC-RUr2tsT=f*z6smaGu{IIr zUax?lPh}yYoZ5MnD0PLe*fZOcT_cCikvrs8Y4sBCCd~-ev>bAE0X;VvJ*CO>kqU}a zY$6K?I50zKOHpjLs`iu`VL#KELC%k7jsARO__@n&uNpOelLn}kZ#0$K8Sc=NIi0X`0zY6tlr}V#j3`GMpt#D=h2DYvrI}B29dB z^5S`hofu@w*p}Zm9uUBkKZ6m#3ILAIntw;bS=j#BczOWS{f0lMd~!4tM+wjhhD~fv zC5IWBr@qpeN1S%CQZc66$J3u0-=!Re>jMleXTM_+70mUN8G@7?!k`2Z1(=~pI-5A# zTAqtyC=*zDOx}@D$4E+3dg&@#>@nH-n&t&*|5oR%`)Z`~DMQbRTGlw|>?~$(pzv!m zk%Qk24GZ@gl!L5LAJ^VxcwfN`t_0Bq*y&gj_U?_XdPPUq?fplA?vJpJc6q!`M2ln1 z8MhL!lIKX&Gjs1c)VB%rx1b-+espdi#FvHFQbKOTgdB2KXC?FR=TU$klwQ{#bqB?l z7~<-@YrxTmfKTEDHpl86{eepz0K)Ix`o2fgTk7JJ-jtLtIuoc)W1TfXczGe#^SFtK z3U}PnG`gfEG^>AY!}Nxg;^NAp>XhVI*XU9YJK^VJP}Pv{P^a)SzgFWc{*T*u8z+zq z9qX&>>z_lWg;;9`{Or_rR}uMWUDFZ=E(Vg7R_-pB25xOJBkFs&_w^P-LCwqj#HEa2KB5j5(KMdT1C!=f*~R z2Ug`iL*En8^u%`apmGk=B|mp|_#>$i3z2X2wr$W2>J#XUb-&2XOaILLKg_*VSe;E4 zHHZWW1PJaNT!Op1hX5hCLvVL@cXtU+Ah^4`dvJGm*Ew|ZO=r^G|1)zp7yI@-r)ux2 z+Pc;QaFl+s1Jf1VDvJ$p{cNpiwNK;u*bs9mOksbUBAX%Y$F@QOz-(?e{cLJXEyt_ zP1~oei)Gls8nQtr`+d?5!ph<)k4a3WPP;<=2iTqbm%MFLN5BrQOKw@m;s!2--i1{R zd(EiVxXgPjmKFP?lsTqe2Ss&2pDmwj>5Pbbqj3}8kCTrBABFB7;mS-PDh5tUaXLvW zlS|fnn3oXFC@L3+!hutEn^Zd*BcD#{#&Q?vk4xP{@f-n%A2RNeTw9;!E1+d^H)2E; zV$orwp7hg271#?zbSj;OHaw6O^_#8%P7X*>w+S=)u6jMCqmCbr(ejGXz8}r*`Ebf! zF|VoUBvh^px>htds-na=4F%98iPlteCFO0(JtZ0Ja7F;XLsju$gSPSD9G_m#TX{sA z_5k(o+w%!{dv=ub(v|}s(a*pq>GdIH0T#A?Wzt)KhwoMXK7do@aKIPo%@{(M1i37} z6S9&YA_j;Tl)wPAHcCP)O>y77Xi6g~J`9%TP0_7tyes{|o$B>E?!|jBr@%w+&++CU zec2HbGh;PXylI9Sg2XdH-!{Ibwz2FuU9Ue~$DT|!t@&kb!>U4ZN}9%i4|kh&GpvNK z^Sh#v9qipPq0`^qv7TN8%+A~+gnr%U&1t16S$}ubI@O)K5`n!?vVL#!QeC>QtkzQX z%v-<~GWiFjG%E1IVSjR@c?90^z}M$rPcRT%f&TY%u?Jl2tNgv-m|^2Zy7#@J;ew%H zk^%_LZ*rQGjxsIADZu|TdD<6Qha#=fC^GGkWR<1{c>RIqVx+hb^wu?*)I82iJ9DwUj@*~3;pu<_p*Wrv=*v8h!NG7PV1Ts++-+dtt&|`v~LXh=%K9)?2nQoq7 z)7iG~Lcz8S>wM=P@G<+tcCrkVTGDqno=(JMKwjGRc~GWZe(FTj5Q@SAJf42niZqu3A1$ZkV8!(DKn+l#t)yF!(fa;&RWkkcgz9}8iV zP9+J}bciBd1imfKx9wUACL`qB6x^n3T@sKSyCSp+IRi`SSJ9z5~Vt^if6#Ce;6=b%DB9hW$QExVmw`nJO&YKmjK`W;?< zp`+rbB-Pjuvt;c?0=l^>yV8fI8;gw5ZOV7lK9$$&k7F;ocdO+Pp99t$S!g|z*i5vS)=l4 zhKyPaZlkZtRTndQDQ>B}vit>N4-keVKFviWw3C+iVURuP=RBy>oZ57(c}9Z4CZ}C1 zV&}$N!f_vqWZjdN^_kP-a*%>IQ%_Er#z<=)mzn&OZphRs))kj)M7xSgXp8HRPt1c@ z@+_is1FV2PX}3am-mgW2wT8)lEG&C#M;XADY}A1n6o4O+LM?zmS|O=s46s~T%*kur z?&S?R0bN%u5S2ud?o7hcl#oqBe}8-U77v8J&mB5Y{ab_-XE+aMF~6W(yWZXq<& zQR2xrj%wi7Ih{7>QaLnFvVk*W5&q6il!I3C-#HVGVZ~Y_dxgKbf`2!SOX@VAPosuR zmhW^&81{=z8985klOJ##EQ_2W75`k`um2cx;GNBwqO&w2esdgzxMsR7v3xwJ0TWpMPmvN ziN1z{wm3KhKpj-ibb?4W?5bdv?A>=z%E_D)OxAaP;7`_TA0a!8v;W9m=m6DLeyU^3F`dCg(q4yzLjVCcf)kY5Cgu;m^_w*&)+D&sgnQ`s8 zEQSxa=eB#zsr}xf%i@PiRwZ8 zxauj)^b2mFu{!)?tiaHp`B&(#30(54{I%?(DNbYHL@wm&IQUy6pKl{?w3qP3lL-C7 z*NN&rX%}$^?^B-}`UKgc{49ta!D!c|)-l?a77J#g;DT=NJsuiSStjA=b)X-t;tW@u zA1b#rO3EWDj9pIVn+?OHZ;r1Iu(AcYt}@yByrXDUbj~><&%-)2fqjwlxca^C{Oveg zqWd|pHNv4R3AfG@;4`N59=*%^$U-W!9mzG*O?u~cXMB5pRKe|HAdfqwG_9UUFU4v= zotFZOYj0(3RjCO9(K8~BP&*;TuY=ubgP@qJ^YP3X$z~O+CeLGO`j}g$u^~sG zrguCvt%L3Q`6t1x)$H1Mv5S~v!bGvHx{8ObkjP@Fo5w!iXg^hsqGdMK4+|~mT4p=c zNicX@f$r+6Mm+rqRm*eH(I3sx=6mYu7=u?rS0+U-Z~wjd|20Jb%wYY0PZ7MjkKVE8 zJL*6+j{R06u(zI`=~w&UKG1c1mH$v<`zv%d$e4J6&_01PZP?DU5IBs+6GST?m+EXT z-eVY!g!3tsZ&jYRW|R#VakJlh27L$YL}fZNVJj$v%_5QXo}(p9@M z7;7B93Lk=U)3Tj2i6FUQpOn)o((KuA#i(_6g#g&>jovPbDElt2CHOKlwAo zOAHD}a1ZW=)-8}+!CQ6jqrYb+46>686z4R^JsmF3Nz5NrAb{*)nAR*8D0|Dc2vt&A zulSwUEmvPLYc|YMJ3MRrDan4yGOnv2CRRyLCFsv)h_ruIep;b=i~_X2;^By8DY zdDOj^i*)7RY8C)0=kH9=EB@ZE{0%4Yc)iMBy7{k}AQIr0WC^%X1%PU9{pYj-D|)|2 zs33r!d6mCDwG_)Q4EC0&txd?k4Ila!~;sxbjVnKodR+Y-(dq!SJ!-Y`SZ%X5{g zG;R&mk|{a@Iv>!)cuJQMhmLjB&xM^?1 zZv@C`IvZC}-RbRpolIkeut8&XE@f`#?LF>cd|A`_IDeXpJYJQ~f+x@R)E_b*afnWBH3EM01x40Znlr5ppOfkeV6|Li|r2_|56|5rug1bD_?&x^gFnJ2f>#+*jfH0HMUx~c>BC_E@JO@FXdfy=26QqSo?ycDF_)v-A ziKsFPvSGuXae9F1`RI}V=*`>bny8~8ct_`hm3euu`Mwb&)72iL4hcFPbZF%TA&&NC z2cTrg9XqOiA^MC!mztFM0Rb%T@fMmv0WUU76X2WoiSA|f<*7ANcEA1Q+;C4JO-lp_ zjQVeDg#oVc9RrT=pAZcUEdNX)O#)Z^Z#5=Y3wf=2*OD|GV_ z9@Y)c-v1Ob>}O`F49gUizF=Hjr^kBbi6=JA9m&caPdc(EiHebAV=|+6G}+4-K}bKy zuEl2g%{xuZ#yq<^SFOA2o*f{6yiFY{?d&n*=CGaqQh;l1&z0UMta`XTZ)lihzE<>B zFont%YIo6QySSGT$mMJecDED0HFwuW$ko7yD4F`oS)LDtPOB;1yc-Nj9=8rpLbs^z z5SbXabj1?9k+Vt80oV15<_E0V@t_-%B+DX(nskVMWp&hG92)XGBn;@ z5A?7Nvn_VY85pqBX$y>e5u;zkduM5Rr>yH;PuRnQWNi49L$!0LW)JHdcNn+62Wa0R zyZ^DfulBRFCjnmvL{M7(2MHY*=l`xXoC3G@RsP!ErT7yI6k*_qa6Kocb+KBZh+MGh zGIQSed(B&fr=MQ_VmNCB?>BTj>1FNHRZ(mo{}I&ZbaT<>hB~ zp%cR#XVRLML=KTua}QkOr9au#x>P~G?dc+mnRDmhTyffN96eliHp0RZW?yKVD2tn1 zWB}PW+O;YaAsN21;VZ(tbj`4Qmfcu_vGr8e)1R)8!0zFYWu()gNewWgGhdv~Rc?kw zJIlkq#mITr&6Kj|U1;bL0R{4oQV#B{Qb@TtlLAUfomZ$?^c4}G}y@Y9mlXep&$_-6{wN$}Bw8+}+>%`WK zCvYAfWy|qCKKA0r#|Vj_L2@-+{Y2gj0T@W0QSi$YdL9sG^w?u5=84ntM{_a#K3#@5 zU@fbA2qohtp?6*cXa92_hnIXIq~RC(L>hq}U5M&W*+0Mf7-=XWx=6a@kMFX|N(AnC zF`p6tI4qn*&XJpKE7>FVlRnRv0G)HlgMW?{cD+ruv&)b$-KZB$^6V}@a$VVdw9KUZ5He8HTkdeQoK!d z2x=8iw$G>$duP|4DgGUdV{iuo51}>m(E16ARNhp%HiC*gbgRno(1w0--a?V~glZdJ zN~LioCd*UKH2sJByEOxm&Ri9? z6&*7)*$KP)Jn>E5`fhJO2*d`BI)1TTMh&yENQEfU9Ns~{-oD5|Kb1n6amdE!W(&Ha zKe+iZ_o2F!>x_$9+qlUZO7v?@f4voEWl4Q2l&;Cw*<`~?_eqQ?s=b>Yv{Z`Qg#La@ zEyvl`#SeZP9CXga*!tzxW37+dImoU{K`W)H*dt+DS#ei)gM$PfObIwQolS>qc@@+O z@DO3>_!|xb?DYFfD+{$tC$Wqcw--<7fM!wA*5b5`JBSnYeTQ$~S&_;G%7f1ywt!S? zwQ0U(3&p!qY*RCP4g>Y-!8>`W8*{|07dKBKTPF|bTPx?;^&Tswv##mG;|C*Tb9F0{ zyv3_4I@y^oEgm4SB3SG66v%Z~7vXhjn>?_14Enmv?dnQWr-U3+7B{Lf)x$rkXVn?= z&4#adt*2ahf)xAU7=@{oq(?|DTjG(X{8?9w%;CV%2tG7z?5VfsD_AW~rU>F$VMwM$ zqx=k{RJxd^)Y)yu+-KDc{pqP0ID2^kFiAohknJvt<8 zq@AJn`n)GykrWcME|S!%FcxlD-||+m=l%sJgaS`OPxQ;20wh8vYbE86+S{sxZ>2jI zoYD}ogfY@QQJbqzmn&PXKQyRb=+r=i@@u(i-4Mu5X3Q=qY02hXBO^XCI4@wt@PeXX z-B=eb%P%-7Iu?Y52{orAN=!H2;7X>Yml(Q}uFeoHBZdVyCj|;NlLnNN1ROBmJs&(> zIJxQW@Pha6@KVRD1bDFKFUzYoAJjO{m|bZY6*@3#oJ0U=PtsmGdr7a(|G+w-1K#^h zhnFALfqugRFi-cd!Z5ui+bC5D10|D+T1Ac(!NX^s`aUw2(% zEYs9P`cj{9Y|%n&v8@~b13aZBP_Wcl2Zccf!R*1-_%wyw$(iGuhofZzce{e)e#da` z6Ft5M)LMI)wl=nw5*H@D$dGTTC80DI$T6vzPh-Bcb}IIs{o}lZEN={G7VHthgI-D! z7|TGY%3aQVFQg=`h1hkdpUUZEQS6h9dXj4{w{Fc+4%X+R>J^0C3i$<{IER0`9X7xX z`VT5?x__WqlYyJ_Dt~Rze?YVTKc<6UW7~O88t=kCd^HC4fBF&rS7QPj=U)KK2y&=5=!!A^7M z8|(?Uac|qQzQIqHxHbgap4fSXFJ#VGPT37mW;g0*57`td10UJ@lMHEzNUJNLWv@n^ zlj*se|L`hau^G`%6-|}?SSb*fo9P!eV>xi+UgbYF@8!kg8sX~QOS>ncz*E5K%ToZ% zi%0AI%Co$kht|L|z~GT+_!KJt86f9*7J(nA`2yABK{N`Y;{(SQKET^@zv6+?b_*Hi z@h0pAir3>`eKH(>a+$w|D>eJIW_G}EWe!+L{a4csuy^WLZsC7KE8l?Zfk2}V@bGVs zi$qaCQ}a++j{M~5c}RB65w+mHeJu}kw=Pt+!*DVRhjB9Ah* zkF}bT6Jr6s?AC~*_2O5OS_|hfgmw)${kZfje1|X=~8{P^Ko{@HF%7=1qgjz59U*8qIAIb`Rz4#~|hN?)K+% zqm<$UUbijU>-LtcYd0FV@h!7;_uWyhE6Li3_~A#v|{oOIl?TOx3kowwmc?3JpAxBk(* zjSkeAU?^>!3{YoXK%Kqzg8Zux_3NfO0y?L!@|P`j$NYl%R*Vt&gazQAvQ2G+%8pzk zrbzmnlPe$*XOioyOF?^Y~1SkG3hZGBQ+ zktygdofI#avt~ySQ@`!^PI+=l9cO~DRf!IDkYtN|u#G1D!7-HSxE4d5)I)~o{k3m+ zP^PdZ$M5On;&)&+*b1v{pY(>wmP6yE4~`ru35*t$o9iJBw$>p4@I6#hL%X<^vt0s5 z-j-CZbv+%~r%BYOWTRiz0ZQvK7`e8rhVI*1rpxrArfAdE_1ZVAc>^&D*j<`>ANz6Ew9*aG+)ZXXfKB|V2a*E)C#>TbwQ1IbVuf1DLz# zK3M$wVtj2t{4d#q-x25kXh8h0*#lDGm)yQ|?^FX-3j*|MUsVfiYM}oOmjDI4B3|V$ z)gDdqhflt?`K*W&OC$-amGkTA4{>1AeE!j?24W6oB1ampWEoZw0+yvcNJ@jR&ndc_ z%+Mi5B|;wTWRDcR2om&|a$Trdg#Lh<$Y?N<%5Jm$Xi=_iFTBB1u}pBTZ~CDbn_V!p zv+KjO4(u?Qd%>1_LrWUQ%4QDUz8ajnDt`0mbA#o#kP-Q)uZO-Zg(&S{#e!OmIV&R^ zm0V-WZ&K~AhFr-b`oRiEBEq<3W?-XsmpL<(7cH+EZTJk@nH->2n=*%o4@Pn1R<9Q_ z)UZtSK0=IO3hm+L)--7fKyO@Yv?l>D>nWC5E3P!~)^{j{97YLG%*m^GJC#brf**lsvHuwvz zGQD8P61<@RUMbFqck|)go9Q<6lJ|cU(k*~WSFz+SD*@_U_xBwPq$6bc^)y5S_5CV; z>HO#TYa#u;pSCCp3W}*GRECys8~LGEY?=7J?pqk*X)$SJ4oW4bM6k^l!tsscn9&>8 z8XJ$YsyDPfg0)_PR^AVU&Z)KW)Aqr=p}!oCv_@4;RS}5zK>o#KZ`T@;p zM^MkrKXf!cECI)=5gbbH8YBaig)Y+vFNhH`;uEco-q>F=NL}B#qANYvZevU|;52xUWC3<7@yva7 zFD5HkS8r3kMRdSbgTC#0=s~aqP1eu=G{HuT(@hIkUWKYnPd6B)n#6f^e4;6cbC|WP zP(6y75Y14CppgAeuDwfyq*%0ZcX9Br#l?CwD{5ZP#0ehKhW{o*Ns+uN1YrFZ3dg9D zmu5M_6mmgiO0@{a;~Ghyvk^4cma{0w8N86&-Mef z@}5TNiT6yesB=TdYuM?tob7PBd8|z!UvMVkq@)m*OPsJTxNdzqxtr&REug(m?w2h1 z9+N9^uQ#G(KH-p5Mp16JH{Yxh#Q@pCMo2{{$4310$TeAd7&SYy&ULf@^WfyIzAtT| z2mX}@@m0xNgG-+Lw4#?kGS9EQ$nWEpN8^F^^G{8Sf$kq>0t}$-yvkqpBN@|fyukO~ z-#{;hVuWD7n29jO25X;-FXMax#aYIj$-aQsi{49RDM83TXkW)*P2(_u@t<&6I zsP*30NS@*2!=cC4!hDqIGoh)H{X9IM0^b{X+mC`?obVU(>&|OTYNYXHWX38ug+DPp z)yEcN%EOgOhHg*U=%TQC)-${;9ExEG3(;EI5mAM~+Bt=94q0FOtT2Jt73UH8OD+RI zbsiSo66uUk6;km@pT_)xm2-#zKOmkdl14e0Ds^CtO*mILxfQkVc78i>i0}gwPHLRQ zl%9Z#K;$r^XWzs`EsTX<{USc%c!6mhgD0+cA?U#kmv>+^_F(4gUe|t%lC)~kj?YL=3J1z+4o8pS)ayx7wFBU@(~Z-^D%ZQl3o^PM)-iFXGB*y# zN4lJ-;>@XF9}kvlF}p^_wZB=g+0U0;0ll$vD{h@G5PfFfYg|D-*3YU?+);#m_CR8R z9!KYNdD>vF;#>(Xpn(?T! z`4eHc`HWli#@MZsK6j@-(r)oNuBU5C9(^J8zic0QYV#@3HKEK?MdxFJYyT{1D73iB5sjO!UEg&EcnwqIDyTiYK5%!5YTyD;bBPKv<=83ivEBY zW6QN!RSvy}C8ZXyiGfOcL@!q4%H!ntp=%EO=(t!%hn*7e=(x*pWzPkIYc0-o>a~&h zTFc-}EhAjT7|0=%P!>)zNvduvcu<@wL}rOZ^nO;cH^lek@I}!o1CV?myKjOEbRqRM zilIXowtVT?d4A-JiP|wEnDj!i;ApqTnryI@M|(tSDd2*~b;0`dxfsSSNTP`J>1S4dD$(fEK7uz4!%q>M+?cps=-j2UQw zEeKp?cn%o43cfqox+(=KLolRw|C(cIha9`O0rFRM;^HWE`*k?nu8jB+p1!maG9&>1 z-5n$`wTI$M;f|%~I%Nq+0pEJ1_0vN{4zPIJ8SD&&5g}0sDJF-j1ie-H_`^Wgkeu!F zDCjoKE zfB(VZo`fe{l0DzM29Jjduf&o zp~1Mg-$eX_kWO6Rh}m49$IW31 zX{Il(qySy(_E$#PiQ+J^GD61bn5)9NYF{CUMT+bFBEZM~bE3NWwXCELVf{uy9ku|5 zFrVoSdYM+;?b%ORl(BCgA`m|XFO9B!l)uCdg0b*Q%EGtGwH#Z2Hql}V&f|(Gg&M+5 z#2DiF8ei6X736;rVM2g;3Pjx8+I!Cvp0J=^Ne$z^`*67rL85c!_uVw6dLLDJ`bys}+>+PC z55hjA-zAs2G0D`jGB8_PW?8qQJyUjdI({oX#0-bu9kWTz-os~smi~d?=GznPyzw`v znA1LYUb@k_T z5^o}KY~ZQ%rS$qj_;l&O<8H9ZdU$-|AZ5@ScOV`!uLQ2oMOfov$4&4$|5!x zi^L`lqCeblV{gXV zZJP@Ww);`lZ#7=|0vr`jE>0jSABJ2NmWR_i0ZE!WRTaGS7GHKtHz$#fHgAhHmWiEJ z0W(*uH545x!4w1r4-EJ{^HJ(;$(yiOlVep+U{XF|lF&&v&O9PNR_#&mca%z41HB0G zKe1lJhKs1nsK$rQu4QXIS4$tT8eS)l-&~YC1p6=)!0iB=5;hk_Q@|{rw;ris>l9~LMGWOKW&%DoGRtNq^aMFLyh)M%(>{Lx-Gy8Xp^ZJ4^ z(E-_Ae|1qQ01fO_{xULd+4ArOHk4E{MCYFGWdq#;bhYoILFN#kwRWVx7+}YR_?2fB zKETC=gn;I~gKtkNIA)c@%UX9_>L9ya8f(YJwi4p8)?Y3w1Pv{`4KZIPu>T>5Cs|kU z)oUkjnRtWxG#N05PBsT}bud^$4!`FgvjE%0wfnu;q6(B>_4lh$4 zGVuoOI`h5n&%n=ApNY^v>^tPsZlSAX*nin*jRF~6NpXcKJNfdZ)shatXyx_^s=0&p zu>~fkF25NSVz1#q8FCJgu0_0F-o^-7{OIu5Mye+KwvB&jI4fwO6xBX<_ruckWjmKe z=$!9)W{)H{qV6YZq6E6f>KH}h$?#|jluiJlz(Ip&WHaN&uvrMjC=e=1adGJ@eraU~ zDYhd3cxb+o{7PAymv4s1g{Ij!{*{u9o`ok2&NlD)===ubk zQozr6NL21B%#G76{22fk3sdJb`8axK#my4`G zY;I1KH~AJ#5_j%zXhf^G%j_9HpqR0d-Zm$Ja>&&Wex!l=Vi_-V^PXD3QfGJ(gG>1t*+EBI)Cy0 z&=Kk79Mh&g#E@rgQ?}MroNu-z0M2=|sXFRWZ!jL5bx1YKBkN)TulbSzv5@~}-8z3G z!@g*G4t56JLVK3RN18B}}!NEMm-x>wU4eMp*-VmR@Fi1c!X&ZTuYok<0AIz79k zt#02%VzzDj_qzk_mk1#2_`f5b*VfceL@3}3f5s`m*3@4X?hLf|`*q~G>(e+v0Q$O%w};0NxPt?4wtDGJ>Lr=Eiu z@AuH6P41kO8lhv-9cDGNLsK^A3+nbOJ`hmt#JE@LHbPAg%!g%;{_tGk8#N;cm0Ut$ z=1$C0pbP0E5=J{oUA^S*j(K|l2>d?mz7c*>*YY6|P?fSskQ()q#4o+<{u;LADHO*1 zp-i7N{jR0=8$6mOy~ieA_ENHomI=?%T}SpTV~uC$(3;(PRx`hSTW)XYgxBPliz~SQ zj-LP74-fl@i-(cXvqTcSakL}RZMT`sO)#AC4DPUA(0l7Bt&gxbA(()MyHw=v2YgQ6 za9W|XoG-C9z7dlV7wh`V@3`WtK5m&J1(eJG6uwCXggAV9VYrO_a*dquxgNPFH@_tQ z=rfu((H&o9ig$3FX1Q9j)0_m0r|^$U7laR9TE^R3$aS zmp>rYU&q@24n%;H%fBsS6=)T&@|R`&*FfZdeCanj^XqW@tNg$DQatcKd8u9dO1)a^ z``@K*;28KXYh3_-UW%(ttC#=hRjea!MAbK@6EE7I)88x zg)%?r4A;k9Rr-vlc%3lw*fgDF&SSp#J*C%2*rVRLbvZj->c{>_>g}UG=YvFKPdMb?5?>;hwZ3{yLEU zPl|&Hcy;{pz+8Zec$L4D0W^@$KF%H1{b5yt)sZnUl5Y!5_uQ| z6ev+h_s`%@$X}XnTOA`EDdkfkTyCW4oDm7@(724WS%qh_Jp?9GBBM=DBO`IQ@0N#p zbkV7lF5?pfZ-;K4(!5AiRQPkORpwMviX4T6wIX5E&pk`P1Z_oH*^x!;fu#`1An4q= zojl)eiM6+|^Qi=qY0dBVyf*^jgDQf2O@44p_#>s{O5lC2;LFCv?oG^AHkoPMOZ@O% zKF%m?gI9u*#yCKBkGIBzte;I*#Qy_aYki-olc&wg%K+3||CG&Y!whK*vlUn1ir9HZ ztlK;H!y>9ezt$YR3BOCg!8Aey?ipMsywJpnuceqK00iF?WiThN*=(0SMlQy1(Y`^B z(`u$j)kt>MzTtVE9xkbxUu2LMhR>G9v^q+{PyocbMei|r>JGloNy}*dMD@#2&1C!M z-rc*+Rd-d};TRSt;-ACV(bA+F6f1?tbf;W7mzt#(&qVDqgQpf5!XQfODG#`_rTl?K6JF}lxY@-LIddTrZWL);lpaZ5$c$IRC z?vWjk##BszUmOy9VYZmMXnn^;etD%e$z^T$krnOR6nq1J+{L#7kGySVA_xM z_e}k(t^S&ss{`8UtNdlFOVh)zoV~yS@9?eSR6$(d*!ODEb$*u62Jl^oard;Ae3n~6 zEJy);xCW#sYbNzpolzgwqzI9S;ZX&yROEtVHBwDr3v3A4cDpoWIqA_`Z{3A>{W8603V z(DCsvY4s{#V|Wf4WxijZMAx6z&a1kCCk>c$*;*F5rXNb)2Vi_UWcMP%(q-N&jpGn) zlrkvVDdU|{y9tj7AINj_0TLaY-riQ7w2}kTkKmf9CI+9;8(Vud@`el^kXF*IqiaGLVrQv@`Ef2~0&Y2Ye()SAfe$778oW z5cE#uh^tz>8qJWqz`9@`UnB=z+)y+UpBV!kZ<>H~U&1-z^MjkaB$!k=h`n<5!z*1EAMb6@Gd zl^1;>3S)83H(D6(_tmU?(mrlIC=_yw<969~l<3X8axypwBg1(Tv+XR`o>bV!<)q~> zv#Q^py=s@NOQvg@tzsUH;*wUbT5=S?^m6^0bBrvCE z6YZqdz!;SmI%W|`8&Z$H~d9rD=Ef-(->ZQxX5CQ zfirm5k;#wem-O^`Rfunn&g!RQsRP~Is~oF z6O-&IWCrR8;WK|V7q*oD0m#NJj3+Qfg&29tKBrGEVd*H#p7)OpEvpvH`Ho!>Wqs@$ z-C61ojts3TLuuECZTj?h{J2~>63DT*iAD6q?c^(|t(nX7R85>Z4ci;2vrX>Qv{^Zc zIwf$MyZZ9M12O#Co`sBg;@B9ffD(I11;xDh^s2TgUy zBNKt6j>cBTGzshOc-8C$;9-=uB6BqrNcnJ#Y`=gXlm+Q%Az+6h{qP?I zrjx_n<>%oqaaSiNiZXcUtLhn$cl9Q&r|Ont&35u5h?z}n--pD1+ZH5UxsLpP)x-wv zM1hrj1Z8nti&*(1WD5^Nva8B1BhT1)Mi^sO6N2B!ZndbpIuDZ6Qz%SV&AGRiQlEL_ z6Yggg%b9+hd}M|ye0;Qz-z0#;^N6b5UUzfLh(FNx#^5GE*!CMCPpw<;-tg^P$*Je) z*Jl@3wp4BmB|e-?*@{2xheR{bu5ep7+_el2d})>;o&f&hFd*?v8gYrseHRsOc|gm$S8I*eZ449t*3P_k^QAtJIXxK)|UV=pLt zb11+Yb0J4Cfkk)`4Id(?Y(^X*h93)&<}Z*0U?TX>2*d7AEgm!W)YL*A1if_VjH1_U z(qgF^A!M{|)z?G}E^Uuh0cvV9FTQsTeWOvl6DqZ2>&c@UEc?8$j{}vfOf3FZ#5+YG)Fj<72*Ta-P1m`Bi*@gO8~O(aO=3p+cmN^v%OzAt$ijJ%kpO zf<@x_13^u%76Xt+e@v)3-8tHxQsAt z1%}1#F<|CK)gaoVVDHwo)drR4M;4qPS^;5sT;vCMw1<~!1mn#dn9UFMWmJnd1lHgi zSGvfLG^})*4brBJ2Ju}%>P@?INjmP{|HJb-nV%gO!OjxVzXmzVQ%_X%X1xa}O?{}RPJ zGc+k-z{&s?EQ3}|>ytd4(~&>)XGQ4Ka`O)C>wbr-jK!&l9MATRm*GjD zn9~eJlneZ-$NMb4fg2;NIyRIfdsP)iNC#u-!EbAmk%uHcYV1j9o17SQEyEz#qP@I{ z7w@G>Er#`^yshL(A-L;E=fKcoPGjnN*LM|>lMmBok?mfv2Kur1L(?0$xTnRi%FN-C zI5Wdp?!qp6TUHA@>Xi7gSYGAgJZhJ&c|(pgVl9q>CH_!ra-!=)NSo{19kRcE?4? zcjo9Up~!kI>Y)68(2%rb*N<)cpOmSh*C!`MoZfv+=+cDAidPibRT85 z7MA##A{p%hU1dxt~86og1bLK9!ZU zzg6UcVz5!`q9X{zNk#|MWu>J$`=cB>Z$X=&A>u$Dw@R=JOpw6gy5l%})xC z#%>87)ioQM=bgF;HP6B``70`zgWN`*Q5bh$2!Fy8ji?ashyp*~sxe;hR*wvm+Gba^ zYS(zlh|c)Yu}e$<^W)h^{xv(bUb`kX{^zGIyS3+5mAaRTQ*;HIO#s@tA~Wwx=fodv zK(F|AWVG)4$bTjQfCQKSM`E$xSt1bd!Z8r=uy(!&^glxV*U4pshmRi(f%m~HV%%$I zH?RQyf1X^D*=|d%XeKlM}d32bWaBSr9u-tU>e9}CJfu`if zcF6?~5RlOWanL$78YUDq6=*oy$M5l9@mFsa&_L0NZPWLBs@W}@ua2Zn#9;Ez7A#| zGC~cg_jGOdnRsct8%$l0`rOjRR*YHu4WF~>o1kJS&61ORjduuZQe}cZj)Wx+wSO%b z=YSQB0tsWU^pvH!G65UpRdJj-#5PTf{>-D1Y*}d!eSWJQFzyE^{LHr^Ue7KaM9nD8l_5LD!(w%sk65$XOq?bUzELdRF_@T zHjJdS(hY*Nba!`ylyrl1cS}o$gmi}>E#2MH-QC^ro!ojo4b^XY;Zzm~`e+E+8dAFN2r#Kb4kHyjavCE;H74?g2(0=%}ov=;m>yWi~ z$(~kOQ+X<4Z8Kv0--Et^YL3z$8{OlwUw1)s251L;yUU-g;7X(jxKkuyD!-fLHbx*1 zJva%Q4?)M_4i=D|_wk-B(Myc-N})~1rD-LvuU7j|JXIm_{rfL+ivIW?NLn^7j|f&d z>f`ZyZS|$e%XARv?X!!`lhj`ys|w8UH{dKTkjG8r>8<^)V&%AkAS0>eek<0n!Jg60 zHPvFTQEP`8-BfgZ3X;N}rQ+u_M-8t?!|tU*gd)|Zzr!nrBq}I^f6$8`Qdu><@*G;l znp~m$G`o{&`c-0?Zr(H;TOl>~FssXLg%pJbCR{H5aqZOv422s4oPWxF4#`pL5R@w{ zk0$#igkY*(IR37SuMfpVMG1?`?&dAh?RBH%CZ1=}@tSX{<$JdYCSe?Z?pvF^@Q%%d z#lz+9>JX(+g+))ODo(>Uiq|;p(G&sVS>wU+QAeh+Ol7$|&i$vyB-sSgid7E;wn*^> z@Uu;P>qtzvO~om>&KBZ1u6RD2Dz?5SrU_;{Ozi{nQe2QVXi0J99xb+W?W@CxF?%IE zDnH&I59{gIJzpyH6p9tI5A6zg_VAxJ3jP^hI}11`Pk3p(MR6c_5y1Jcw$pJ^C|ldD zzV<);#fnUX6ijvRPP?_0%D6`4F0Xrcu8A=9KFOQw3Pd4T_A7seMt3}vq1acyLniaY z+w+9kGE#?+fw?R(Q>J(ZH+$1!FpJvI!IjAK;2Stf4X7sp^0SC8(D@l)h97omMMl@J zYsA(HwUo55?bFn#u3vNfZ>$CqIK_>ZUoiNy^vBbdzduDEeSrD-gqNp?F8vI2B>Nk% zzfOE-hd8%@;NitDmYOSpM{ou-k3^cK<9=s}_})DLL=AMnC0&~yO zgGJ(LHw%|IRnLgwcSNcNwrdqI)G63DZ1Xd&9(noO7^x|W$x7U`?aDUoGSpb+*s4p| z+ZnY#O+|UBtC&yviuO76cAVMtjQqaN`1!x?d3Y`9hB`Ki91Oa%;@Lpi#n;cRS&86FHYN-JEv5ZZtroAgO9}02q%4$?fbJG)t8{y%ZzWxHR(6#;I ztO@W`>Hlt*0!Fj`t^BVBgy0D;Ss247fz5}~WyB(pGUc<&M4fQ4Bjj?J&Y#|O1Mfoh z8p*Q5|0_8Jk08x)*87$oHgF@6_A`M%De{UAE>;sn_}!l+mJZ0KoM&Ja4>TN2&J5*; zj~4^h`Or!v;z(RfuGdhMQ=#ns& z5xRXV1ZPIlYM0{omTqCs@vEm@C`E%GtFQ-$c~ zZOuHOhHIoPbf`MNh8!hQ#c3?4G-gB8oayq$z9tz9q`zAs0&f6kf2t6HpQ?F!d#Ar` zAhJ*ok9p2T|4lY+m-F#ev%&y|J8?!vJZeV`>N^^7LTrDc>K)PEyF$MCU*C>EKt67K zCna;4_H7RMQuaCShmuhS{vqVi`e{)EWxquEZ~W&W6SLSNUU!k?Ik&O>_?%7N3RQ?MmfTU_#rn7Qp+B6 zSEq$*;F^5LqwS2wnCINH>HeJtB9z*4jp>K!G_}gb*O{BkB3;@NcIJ>>{tf=QNniZxc#jp|g75Ju{_3l^}{eoN~u?3s!vA0Xx3 zJFRSAY@-}44#woVGxhMb+#Hy}U>9FP5f#4OP^581T!$NQ{vAi}6!|Gb+$`++M2FU( zu9-8$I}eXF+{t^Rf)p^27XwYn{S4*|t5(Ds@ z=Gr=HkLmqOC8R29NV53!KVV~lwQCN{7*X(P6BjsIg^k-;vRjgt6xv#k%g zyl0}^V6E`-njmW;1lxrA9oW8tNg}`O(5RQ7k934G28h(NP`VjS$%SaqX&(1Jk*W0` zRF_wCFg(tg5@>KJL&Xi&M7l^6e;@Tuc7bZ8>7f}^s@Y%nP28q_^_r%W+i8O2;p`6f_K46Zh z8qUvKa+?lFFY`N4VHPxOvfw*!`1zY)dLB)P@bNXA+Jtpa0}nR$LrhvAbMges@mpB= zF=kFt9StrdPja_-tUiy@k&OqJ9f=Rgw#4%gpohnA$yS@7H$Mjx7+U=sX72MQ&TbXi0|aK+rf1= z@i7!w^KD@?u1Y9}FD~-K&{|381p9;Fl2}bLZB^cc0pC z{tQ(*0jNCT1*QEM9$+LGO28-?ih8{_mygIBQpD9IYTdbd|MJ%^zJ|L@I33xT*7F<5(zx z*1#8AR}k1}XD&pC;aHtu={7tyh7}%njgW>sW?&Y`?4)RS{dqT(how2~6nlM#a>ogu zf>seNU=Jg3d%kVq=L?%_tphoJr^Z_E6MtPSF6;_*@Knne5WUnii)CL^Z=OxBdaA>BTZUE0er8-gY1Kc*B`d(0C%oX! z`foY}(06YjWTlvY??AJLh@61WK_Qn`H;4K;j__~6McgNfwz!2(am>&1zzTp|rCY3( zXALQ-SQ?hK*nJ)GFtduycaa-CD#QGIAdezYutf6xQ=w11+G29(8(duyMU;W5)21ia!?gFY!m#3d-<(Py=y3TD0DjYV5fQU|f5yVbaLMxgXH?jh*fv&D|!8(RC( z6$n34>qb#4pO0&KvYQShKeZYII!@^CmxGQ?i|Nl9e*x!v!izKRM{|WK(7oyE>QTUH zAVB)^=Jk&WHQ~rNBHa$(L0jI+XDFg@D8f)j(w`K+hT_HMA(L-~c#}>jPKJkC*zFWw zT0R{PYBHh}XtI~e^T3dTNmMp4S6a!4b{ZI8ho5K2;Q@1i{ux!eO5KmxmS?uitCgt0 z!@i66Ywc9o7qpQvtZ%;}-TC*FURA-J(*#O^kP$hyG?0*X&Ws1D*6^!H%xddva!}6oi8j-q4}Iup@tvvkzbO`Futd^LfR}=; z{z#KZ1<{V4nU-87O*@&IO3gsp+jd6m^e`52c}y(8Sr&_rmj8u z9vNkEd-uK?TXnYzqI?$Z4r*_SJ(yDcdUZRg;L%UR)Mw&ZkMJoFjxmQ7iJX4sAu$3A z4E`vp0>C?Z!V592jBW`=0T%sG&bArKr8kh1B^8pDHMU%FYjzfXc&|A(8PCN|v^R%J zDrcpc34z!a_H%qoCmw;kFbZyvyV*ZynPKH39ltvV$%@UHuais&8h^{qn$@)d6F9;EI4|x z&eoC}?WHy=&1i(P->n0#7!ZuP=xk@%A$*tNbx4p9;kkG)zZtjHolRA%E9o|fdONPC zPZIS)(3(2k_QD?dMJ0a|7ghu2lRF#a>u_4Tp!j7Y7h#@T>%8X(8jE_EZ7=K}qiMp6 zeDKR+IHZ=rclzCAvH-^zhBmGsoksIpVqAgpE~xHk-poGj`mJZWFjs0dY2F>@C6%#Z z{aq2-9LPr46w0m0Z{wgPO@dvIyUavj0Hmk}i~yO4rZow&r9W*;Kf5??;X_dw99y9j z=N10ghwHY-wq}N`S>(tA-MeSW8zew|nT+N$2m&g415jcA=`I0Gw7(@eYk*KZ;e}uT z{jd<3UW7kCVI??fqqgx2zi;$y^K?LIT<~N=;TCX*$A)PtAOQI$x3`$ zZ0sp6j4}0U&w@|)%RJXFS1{J_-y+=@6~cmc+iECS@ReTCmGA_Hy%Kg-)x067c64Sf zlXaOH@xJ{swHynN_)-U96HSq3JzrZw=8g|c#soA8Y&NvYuCvVoBKi7gNb6zqZA`is z)O6b2GS06>(h`I=&i85brVp>SV5ZnA>Ia77kD@9$^ZULZdF!%^j|sSS#_O`<93a(q zrCu{16TQjoql=ti@_z?kZ{FrM65;RR3-zAkrg7c^6u?sq~Q| zV2VZh%^-R&Gc(c_E=!k(x-pO8Vi{+>4h}^yZB}fAC?0x zWHlYJDVV`a>)I*cO4CEWDeZ$?3$v=eFS{a1V-3!=v0$BzLD3GfH2y`oKWh|Ha=3Mf zhw8Bf`w2RI>Z?5b_)|nAl;A@F%f&kJjL6{6L4B0@cb|BZL~j?Xy4b1 zbr#^ZetjeM{=H_VSs+|I6-8XQ?cSI7^O&+t?|O$WyHfYTK;FdbfHZxgnT7Mh)wGYV zWP|Y2^mUIo7O{O55zq$d9}H&MNgQyBAj1y0QCd|6B104w)Ht|$TLdmfjtqDq>F?O7MpXm-Ewzgxz4tvK`fVg*@?dSFWh1V~JEQTk?7F>DqKS}G z;KYTc2LiX-$PGebiSqD~gZMRZz);N0cgaW7b+l>PMMZ=~BD^C|ClFf&wplV(2{#x) z*JGo2R(U{_%cBc;%}x@h)e~<;zn2#@>W9}oQzjJ1e;RU7rC_aQ%f;U35s6lm_yn`#1b7#ENti0$IL1KsU zQlA`z;fTD^*qcIKKpu6weR~3~y^WP;tm8^(+@KnL7Ojpedp6CtP0!V@Fn*;N7G=8Y zVhPxPUgmaycIe?Hq%Ie$)2!;Ro?K}wWWZOFG{y414ONSSj2j_Hy48aevg1i z&xVZTr%DeqSSD(TI9Meq=E6YOmg7}T;0gTKsbLUh9yK-X^4VBBu!E(|l%?EYKoPf?>{2Lko8f)qPMqCsDa!+_c zQUh2SJH`v=&xQL%E|Pse;dAb0BWR#IDxOX_>L=pmPQ5dg0YWN7S@LLfzBW{9ZiGIv zjmtd>8S_L*>^71CRs(j4&_kWq8Y3xtFM)k6|nL#!;`@didPtaP~%6t(4v2r zH#m+tI>2GDiL|m+5?Fn0;kMx>YOO&io~jziY#yX4qBl;3w2ib*+wB(%pU^S2e^?7g z^L7U`J`YzRV{^!+HQ(9~BiMj4*hW;de^n8I{&#O^9Y*~5l4WBDwSPK@q#e$n?iLuT zUNHjCwl}EMQV=Y1JBlqQfo?Qr!pfIV2(5EqUw)tRUT%quA}<;&D0l@Im4-qjZ@6D* zU*8soi9*L&Y;VHDWF*xu+7F8EP&h(14!u2*U>w|Fg>nf-PONR(4fS9Ys-VuBoG#w^ zY?NwlQQdfySvqBmyFD;=-b?^f*1%wgkVW2+L8_ddOU12+C$NA<{l1YLnxx^Im(}O7 zs%1&hPAso38z;L$lkhZ&GyDyY(hNzo+W0K2Zv@PL!Dl*hcRP?!eh9xO|ne zittsg?|6;Fv-LoGY*BUaQKlQbZZe)aG)Dvxtk(YC<&t6-G-Ww+hQ#&S9OtH3=Dl>| zlKWRdRRYL8_UcFHZqAbABpPj%z*^T69=b*JJ(aCdAG)@DbfV7$$h&D(f*U*j20&0PFnnP)S%sr zko7$+n8|2Pk88>3s7XbVR?%HJ)q(7;N-twwfV#*SHwpG_<~CttuN_?OF2xo`J9$0X zE6>g{YzJGDN;1ys-V~EJm&<@bYA*=B;&k^5pH9nnE?? z?4vZC5@M~|%5B9pQE@(AGpMU$t5gLfupyCc1htd&{A09O%h`+hT-Vl6f_fU;%UWo*~7mqMY_Wkl6p|p|;%gXG=xK8K6%X($8c_tX8kEj{4QpYY<||6??3uX#QCVi$?5H|mNk z8{+e>bKqS0_5U!ky7KCuG|c1MXfo8l@-}lI0=o@(o~MiY7fAy?JWPN5w^87)J>kV) z{8yQMnij>D2yU76Owyj#RsKo!GXqqf@Pg6+U~L2Ae*AHHE8B}%?QB@(#HBktZs9LmqxK4_Thr8HC@oocc3i>ITxThnG< z6gNCfP1MY-tIfMOG}&>?Y-x6pF1iT0?lqsn-Alv=tINX>8K=inWru^qiO0fLa-s*) zjai#}uJb&l`S3O7(Giw@-)ze2)5YYhYF+H#b&-L(tUH5E zT9LOx%S;*RFwRJ`A1cTQ!2XdnoJJA5Evw=;LZVa=0*3YRqisIodVU;wmNn<}>8@Df z(rdjqjjO4CH?d0-L`q~H1m(9He@Z&QZl6p z+kIs(gOuV!av$ckuf|}*55BbZIQqTBklX~-M21q{A~0S!O^O-tO;C)PP#(-OXKVy>O#Gx%O*YP(a3hxixIoH|F~iq$3;E&pkF{7>x#unz8z z<&+Lw?-O2JF;{epDGm!pN2(!YUlBYDsd^m1P0 z_%DbIR@Yc%s5OSw^M>QLvxp3wZ1lC(cG{lZPzhN21rFvBUW87oVgj1;t;Fp>vA!Be&sYUQYO_nZ2AFz6TW|> zp*U_0i-m4FIE&c7n+s29Ax&832Tr=hV02k@Ne}Ea8=2I?js6H{Bu|e5=eOU29`VrO z`Pp|L4vX`zNwVH)hvrmjn{p;rU89H?M;koAk#ZkeIM>!|aCuACAwOQPnjTuc^MItj zmUn1y-CL_gge|KVn7^K2>ViwEDJ3+$sxdXuE}B#dWg@Yf)bx*y1?{KZLD{@5Lp*={ zx~evrT-E6fy|iE{KIcKl0LC2SacjNG>}Y4om9N5jYjt^X5I%mWNhW@vDA3>dph;ru zvuh{fint-gfX2D+ay$xsIG_4DxYSGE5!pV3kOv) z8IwP#K_1fC7~CQLuR(eXgtJ=g^4(gWDKQ|N#q=j%R|7;Wp727#H5BM9i0I(n`?S?a z*xaLt?}fFPuNmf5Rz((39S2Q-;n;0Q!!A zxA9dxiW4FjWVd&dJWiTeDjA^&2|jYPb~ST|S^N=4RPfLWfeqM{miNcHd)jt%dE9G# zvsX2w%p}IX%@j6P+2<=A?*t_cN#RW)*YwMD@^l7m+4Z=Et{XjHGgB_!LN{#@lR8cI z&MV#hi1v(4jEum5O1Z3A2^8gg7?6Nk_Q=^__194P+SzI7@jYN}@1X_U0%uIdGhy%owk z4EFS+x?XJ^zB~YEj>@rHsdgRH-r1 zTRO*)U)}@n?O0DezHPy|f8t{{k>cYPJ{9xi7I&K|W}NdDOLRz5;+BWbMU7aXJ^s9B z{yF}BfCqV?#cw?owZ5cc%Z4FobG5r?Hk=Kh;sh{E+wq<`V!$qzzw=eT0qX4uF9hKB z@oApvqqgkhD}KErXy0>VHwVx=Ia(Ou7VYO#N&j1?wv>P;l+W0`dU+B1juj1U)7%nHmZdZ1P0fYX6GA}7VK$AHgMr$z{Czm}>$XJ5>3bFM;?C^fE z&XL{Z-ZS6kmldlmMiQE4x*46wf-d5ZFLd=vJ|I5}oeWqziwU)oHXjDPjA{{a_Tj({ zK|&lMJK-ehO}5nxRL6?w&c>R5n)G1g$j+T$OwbCA&>D~<50&|k=CrZBnX{fi;aDgO z_ZNs4F&RCMlQY57$v%h1TE7tnQcq@;3AsF_g43zJY7C;8D)b#udm);aA4r3pK=T<4 zuWQ-mI6LV>&D^L?#K_~+j>Wq@h;|*(+3+FIZ)@h zpN%Pd8iAsEvxRYmE@@K>i_}}9)$u(i>^qX`ZJ_Vzm*TG?3obl^J9A&H}l}?8S7qbeg z9LbZpi*tp(qiGckzKe8`7A7|T`JDv1A+mBBHro#$ow3yyFJo#svaNx+H_WO;=zg@J z=ayI?ckI2z;uKzsE8QlfsiQA%Wy*^28V38ZE2`tq!XxFq>cc+1q@Iff{_`%YD1>L+k(^J5(#4_d#vhqb-LiT_3Dqt`Jw7 zv<{yI-k<@Y6y999bpnL)@Ne=97zNAx=b`)tRPYmC2<3dN%u_#Svk|hv`#>=Ze*RpM ze4z%)EU0v?w(@W7rgi#CoM)!(Nm<%hM>+bW=Gurp9)4#^pT!IAjXwS$a$-6yg_k-tZxQcp`i3~52s8yrR?I`Kl|vmV2v}Ft(RWU^`3e- zQkDu>*NUn>%g^MF5dqJRUa&hiWmy)G)X(qZ@F|`=q7B_R&|3;N0f*uzevpD4FDAK3 zBF1n#ooFu^sB4%6N&5`lE>8%!B0PCJcK6|D$%rHfG^`tO;+lk4V}qPBpcKgL8_l*! znQ9-0I5LeZL9{e{KKQLS79N6oO;Jb1Ae#;?_h)#Q{&r&4(Azbe6}9VeaEKSnnl`{; zZ)b-uW3oW9fS_xPlcs7P#Ja}dxtFO*dDY%dfhSG`HyMLh_SWoGCR1s@bJbcttu}6| z#8=V}Q(fF1XTY;*+A^HmE%!R-kJg4z`czvYyGt9-NPl{*U>Zkt_q|o1UARoWB}rio zY`7cUT2UZTwy6qk;M;5MSP$VOCkTr-R}XHSeysWU&S71o1Ka6=(Q$fp@5W|nB*&s+ zSmC6!pg1HczTtCV?}shuI16E{swPshYY>HtuMZ2oXnu@&g6?^0~_i`Bnv08 zs7^kmuG@9s+-$2=E}{P%?cJS z?X?o}mOA~ctBsLLU2D>wmiR4Jqt;5NVxZ4&^K}yW8{`_r6<5!9!kO*i9);7C#~V_) z@=-@v9#+VFkl7;cnzfIzIH2xz-M(8`o{s@BYLBZj-$N)$AN)czFwNYbiS1Ks=gY|A z)6)1q*28~k?fh3~N)&hiFDU^T?!UXSL;#KagclFsUnvm)l%ldQy?ma3(12ate;mA9 z;2AyP1*L`&J{T{8HxR=)p&`ukKp|SPu^!7$f-P!@adtwYAmc_<@M$eF87o6s(>8q& z7Vn$6jy2fwuN&Ah7W>B46lYb60i#pbcF~Send4m5c`cau!p*eC5=&ifk7JM@T99+G z+&8UI8qS1z!u38`sM3G_Dcan=e~-xr=HoLpd`hGG?29Y{9H8n;_Q?mpB)j{Y#bKiV z$LSCT*zklG2Z;UM@U#^MM4LkhVn62&&ZLd%celTiu;Oev{gR zJ|ZX?IK@N$b5x4SqJu`MkJJnL=lSeebI>w~SPj+2kF<_JZKICAaQnzG6=6upQ6kMx zB-jkJ4e+;G%)*SX3-y+X25s?DISyvcJIw?=28bOU2;-u6_sh%Y)Rwm)Rw0L+Jb5-e z)={PvO&luvy?9~*QXrcZgt(ZPI8uKtdlA+@YHo}qK1{m5rJ)!k-w~Hvu|g6tIP=!= zI7%};L#3dFF(x`px5>1lY5w3aVTEko;~qK(}*Vqgn&Ow-`htlMJUMm;h6Wi~Sm#Kz8T#p^H7P+h>ss zc7WCP->L`K0JUrOPsbGy4ER&-N&~R@2`^Z^ANRM7oO}aV{f^S+yPdBKWpNErqhpUQf>2_4*F{Tqgrku_FtOEc zqoy`co8R|SRc(RD`OpRlO%%$XeSEhae{au%pY&x|?rr{5r(R$!CV$iS&@0)tc}&FS zt0k{ULJ%vBZHA=p%6!6PrhADv1k*9nD*QcKCJ}EtFhD^%O9ejON6`89L1?Rm^)tkb zqiMwdq>@#j#-b0S01Md1Ze=Fz+?)FPA>>pr0sh=ob*xa`)JSl~Ryv-EIwpY4sYhN0?1TReVB^q8B=hB2+exSNMO_lF=Om zQuR?yMX2+65~ta`=e-tQgAVeVulOKyx}385+qn!Z$uo9ZFU(_ts*E%5D>X)6in(3h zXk!>_k&Yv@lQ3Vl(e=adF)wW2Hrp*;9tq2qk1Mwo*z$X+=r7K&;F77`b61hEqK zxlg->=7wGJk|WJU6S+ABIrd-#&iF4JFGE71gyS7~q{0zx5S&l;7>}Y2Xuwr`#7+vQ zK}>0bX>76ey#+MSi6MWFj+FHy5%oOYmmD$@+^mE+)`eYtoizDCEdG4E}P-o2) zKx082R}&l+Qa)$FT3!TGue{{ru2R=HW#Q)l1L5N78HbKmyuos5cx`^}vXW?8>>1In zs`PMvlE>YrvwgTycMbzPca=PXdSN@jH2FxW=;j><%X#bhx=MoQS@K8#cp}!iUi~P~ z)G5$-`!~wP4Lpx0ym%u2C}u%Eu2+p*SXy|=h|fqG10-MSdM2iSg1x=~xhMP=lJc*f zQF;wf>Zg!j{Q;=Tp1-x$Ps1VqL?VX(J^zFkl=fqr#KHK0siFs8z#x2M(^@~1UcE*W z+Z32mnZ>}CxRh7Dh1`x2>;_ZOXA=KxnxsPhFrP=DuGBT%&_2iL{OS}n>5l$(V9o=Z zm6nGQ4dmnZM|!8zLVsu4bnUv#+Md9fy0H2m{pyv1y~8QhuT_AJb6qZcsk>m zr}I<4F$`6@gKOtDsu#M3nJk`0S3!Sq9+Qcu>18w33?me&yq+A8Z6a84!8R;L19iM- zV1;1tMfzfE(nJ=0R^4onsqp#socZdvLqBP9-DT(kE7XGJ2+EbK+EG{EK!eSGQ`p7L zg(zDGZkx|S%BO};#RK4qqvB`m!G%mf`TqRioS6;5@{*1~?D{7IUFRAoZo4vxP5<}!<`yoKP zAU`K@$Fr~dvcPi`nv1N*(4uTn?0^ZY)Hqxi?n%S1pg457j_$|Jmqm?Z{6tuuUFy#6r= zjlvhygN8`y=xi-F(WMgK8u_lekY!T8Bs}gS?raVw(@g1pD8fg~)@l^jbKMMRHO$<* zGjEgY6ibwdoHest->Ycs5A zLgxP3mk4xR^#S1IBuJ4xyKvOMI&qrtrS2>BqC4 zc^ZIYXo6E6pPq3H2vGl>cZvzTu_wHE9eQ8p`6p>1HQ=0 zkCGc-!l8$y$EFKU(L1nnnyE+L7@up;9Yo%1NrJcFO)1Mf9Pyn?0#v%Z)=;jm+UOV` z@ZH=ZoPRxkwvqp$0G?v-f1d3K@S~pauRlzV_W!2?`{@Pbmq@BfsWgACg;fTL!`go>k1>nuUN+0H$KEf|E88l$08Tg%op5aaeseno^v zDOfWjy>~^=ODf%aw8C+Vgx|~~m|QKkwL)eHa(zWOff%M~Jo$@w_bxw7^dWfkhD(-5 z+N~|`l?NTs$3VIw5s9$@$j)%c4uPe~63)4DH4mfoS@eWAdgy-Chhtf}^NWqRm9(14 z+ptTP8E+-CTW%mRJn@<?Yy&lZl~dNXe4DbCvC|^eYpV? zspIZhv++4#!1F)aa=m>fBFw;}`V-*(0VvNWyx`xh*3i*14?V_u_=(6hk^ghm{u#KB zSWEHD?q~FX{Py3BU;uCzPk2FZKZ*{al@?A&LylYkDlCH13XBy!Bs$3oL{PcP2g4<_ z>>b9ZssceKDTR?KY;3TU6MeRaMdlGp5mF~o)@`=kI0oj7C5o#LzfkTWl+g#3#wbT* zV1-2d!3e=``dj10qKIGlX_&5ge9Jr(&?W^S^B>uBZ>c9fpM+g{s; zabvY=gb&$;{555+rFWOFRC78s4+&p6kwGWS{c*-j;tE)2!P?B8Z#lcOH-qVEBDfTs z@8P-`YJ)OrXfIO3GZWqpU;}Th`|B?N8*2U;&&2xAn)oDu1y6X%hQV}rz=Zc(HbMml zw*x<=ersRm60@QoWEb5^K}OqrVv4Y?k?nPIOYAGdo{A8dK^6@Bd$1&lu8mTaI$7?T z4;Y`TIkezgugDWa(dd38%Tfc;Q_3D{v{8TjZ0FjP`0+`1COtX60(fr4?^8kMS6J8ua5g0EI4D9xQ ztfW%%iMGOz$^PmSbM(5ArG}pP9D2T$$r)aJEkqZO0BM&~tXM!+zYn=um%cp2+iZP^ z;Wm6T)!P5yqmxSIjt@qi>m0p$VG#8+s^}mHR&crD(OGLz8g4v~waQzj-d&13B%B4x z8Pj#dfgxA4qluQyG%=&u{Biv|Mx# z{rEZRN3L_{N4^UN>@Pk&VYO{yu&eL5O2=xm*FmQGWe^JgCP`e#_Sh?FhSW|%KR&u_ zJJ@EfvRuuserK@-zkkQXTGEAD#2D&zFwZj0sn7T~isREBH)Q+r{x4KM*2jANJMDL| zs+>eO7^h4Qtsgk}y?z$z#rvcX(GvNY41B7aQvV$4?m$&8rjrmkm7PIs@BYz_jcJyp zZsiMcFQui>Z}oXx`r_SO1@wXC>rPI_LnB9xHcTF$2clKI1%0=7(QMZ4DRUr8c*ZNn z&Pdg|u-@*m5E!~xK}~1LPHbiMlJ`-+CXb3^$W~M0Sw6cc9V~Q^`0q(a!o3wf{I<0X z8bP((oVWcWJnGH*hY5D+cBTAkW#T!;@KG|EAHBZpJ9CK0o}1(MKYL<^23=2cF38aD zZr@jFD#~*r8s%!5qbg_HT3mlTCXu9(-eF2;g|D-#%3y|ApX4(hV`8gy_a1ui-=8i> z%6#bBU*E?6-&}(sAX2{^O^^Xc>wiQFu>1Z-3%mevdcq5lx_!idjqrdE@ibJM_jzpj z$!B$ey_DX|?8-H-XFW<#l|rQUB&?83Z3@A^70VzUNd2(hQ%mh5GAVBoVD z>zqRV`pDOf>wZXGD6dqACm8K`TK)2_`yy1@Lb%3$H(qZ1kt{dZk5J~->h(~EOTHudMIVXr zD4IeK7t_axII;@&TeW2#XNLD?+8wZ|+C^sa*|scmq1P^i}9hj4MZl zr8ZY^SDFSVnns?aJG>D?REs;97_T?b69OR(73TBd=q6Q^4UGc>64Y)RzKVPMpy{z& zkDCb(DaX)@VFu1g{MxHa@F4C|_8Rl;Zr)cM| z{FS0<<65r#jHJGtpc}&a=7gTcv|=+;;%`QR`GEL=E20q|P&vUD7m#Dgn+G|MY51aP z`WRK5S-+3MZaw@QvT^_|-MFfrZb7KVLfEV2!Rx2=Ww_RISITMtdS7r@mFwV{75l z&>cg0L-en)t)0pX5XE2bCd(~txTAlm8viopNF75vSsA?BurEhTaR^w$SFJ0xax}_W zDAPnT$o`HnwVjB;uY&>**o4`ptpLvG*fH=V`JmNg{ z6K($$r>C07|Kl*m{ozu0UtkI3uz+A$jK7%`Q3Skpj2Y<1X<|&mET9@AJ43L0#Rh{m z06XpLT6BaH{o;dvcX;YKC;oXaNR7T5=$@Z|)D+A&LDh0vlZmji!km&og_uiAOyx9m z+mC#8^!$n+%$-a>#8S1JlaULk1gvdjs`;2=eC=;kd-&a7_7#t;tagzlae2H?(r>TXzpqQO6P zH;;fCe!>goxgYbN9rpgDQYOK{KdLiY&Q#9Q5M_;Fd`gy)MZ<-%s5NgeHpuq*!c!R2 zmQ2rbpjw=evFQ&i3|Z=2heMXK!KODP93HM66E(aP?~HKR=Qt7Ey{ZiT5e1@OWnvJF zIfeLkZn$TsqPa0 zsZ^0Q5ae>CguJRM9c+?N)9fCS8j+LRXy=}NqQItoCU%_}b=S{ zD?Z3&nOL06f!#uc42G22|#fx>hK|3&f_cI@a@=c;qfdIjGgEn;Ce5X_Q9a+Lx4H7jbO)pxoxmqaZ4t$^un3ea7+s{|@(;8} z50(_~AS|+JL7BNSSL0Sug0`Dz4`}!0m+;|;_k22UP5}xQ>cOf*}zQD{;dhToc}TWfUoo)(P#n0;t4NA1K1Awd5H__ z@eM`w14!Z>pPT2S!1}~vddBqO$XA|+rU&>$B)h{RVf!Ih;g6R% zBFkXogr_5O4>03vH;|0nZIp};uj=m}Pr$D-y@JzHK0cp&`ec<_iKca>J^OKhfAN2| zO4on$A@~BpeOXoeUHA=(2FyOqju@eaSMg^A#pcm7KazQwyy!C(qa7xj2%LH2p_k@l zYz|%$k6HV&*+dkko`6lsnWMC15ff6-bFsPx9Ier^1)q)8; z!POjjF^kR@JvHhyBmoeMv8R1NTxD~5mj6oN0uiwTg=uih+PbZV20o^Li4trYQMv~= z!BVgczx~Y>`g;m2QraWln)e`hjJqMrJMmfHNT3NF-x8cTNrCKrAk>1JJeLa$n zE|y>UYzKMSYPi(_f(@10?+G<|S(hsl(Qu&CwIg?FRfzlk3aZ|FBA7@Gb{5JyGF7&a{;m19FK4i*>{Y6P8QT2&$Yt$j{5O ztLC*MPserU@Pils3ePr~we`f(q{M9ep@o&r9+Wrd-1>qmumaTGXgg(9VUy{|TJ+No zaV1gBVnbbD{cJTEzTB;D0qZ5@isT*;>~|MPirTBQ^x+Nm?39navy8y%)}oHOUA?4x z;<}`|>0ftt$-5Jlb4)i+*36$hDG``3q zaO?t3$TP+o_ANIPCxlN25eIk#zYoX*cby=VVnnPpgI27Ha2qi#kph2K%v@hDx;=D~ zxC~1lS8k;EvJpGjO-8G0dk6@#f8dVWXoa!v^PgGQrTd`%bE!FQW>LXK<{{Hw1qPv^ zgqkE}O3!Jz*`CE6#xRM~Sv_|UgMq0oO+cIiNIBdCQ*yfq&Z zdVg_dDu0pijbUoON1h9O)RtUvt@K*G@d$r`(p1rYn|bKx#}TYg-{4Csf{%~~ORd$v zCdG?wXo5uVd0&nY;5d;YnJ+Q)c&${L={elQS#yuxx7B^unoS8{-<7Mos+E==%Is{F zh2qQbWYKqiGnI(^5%==-1V2deba|HJrbc(MiujGEdtV~WiJ{%V;P}l40_MDuqfe;c z{mR}&(W3X~BD$EYcJGn4(v;R>YM?W-*gV!?4sWl+pY=-P!BD6Fs&v%Z?48Zf)lx>i zZOe2Ti+tIpO&r(l1z?nW(V%!xd+quJPFw7hp2W$U~Vt) z9g2c}eZBf0e(x{I}q(d3$hWQIZ{7B4Wm1ne{@&w#Gt z*?D4sf?+jg4Yj?(i`-^~bZ_75#l2Qm=^;sXYpG#QJi%?`oK$G8YLyKwQ)r&?TcBXr zZ{|Hvu~+aKybS;|QA*kN3eo7_!DQ*ce7E9I(hIR#dnYY#5NHmGWYbwJIEU}- zJ}`y%PUfEN``szEgtPAltfIH897FFk;ZuXk()px}Rv~K~4SvZ+nvXAjz%F_N|G2m( zY{eeF?k)#=ua@pf+57JN?xYWGbE@XtGi&)bO;bi}yweQSJ(zLq`A7IMk1S6!i!q+p z_h6$uX%7Kuo?fDl7^WTPmYnE`Czu)u4Mn+K*86OX5vXR6siXAZc4m`4G@25dkuA^S9{*^b=9OnvAr6292zA?eAOkuZ=C5}F#ChocmSCg-*Z+hUA}}A_@HDNY z%VVEaj8*#Ae`TSdjSE#bmAf#4e4f)gAXcLD^0Yj8;*xVsZ9xH|+7?(PJ4 z3-0dj*0(vy-kU#XpF8dt|3kg>L-ks7)++s~3aO7uX#I;L3ctW>DgV}Y)oX0UB4r}- z3LP#O$GG%Gwaf2lxty3QTpUt0q2S+m^lsf83@#2$LCnjj8BBg9tXp&HW~ttH>c^U? zjAtI#_dUWlaX!uHOdEKaBCv4-UBQ*6-hsYJII#GkN_Y&Msfj|e$im*SH??vr_La_D zirjK!;igSvt;>kDUGJt%XmS0=LkH?Xny)*~X{)fCqp6e^x~-)yM5kDo7CV(fO8i)+ zmcqR+be%{?_40)6tM(M-7RS;9I66}dg3=}k#ArJABXfBH~&VUOSXy>dlr!_@5)|K7E?lR!%Z zXa*?tx}6?x@Y*`xCA7l)Tb)HUO?+0jd>qOWzF~bPl!mTR677yRY`nF(V*!~VocB?B z4s*ye9e5&si-MhmTIC%Rik!0)(kqOspF3KhM~#mC?Q&~#@kQh>APCDsr|j`z)|U+@JB-GQxEUy~Aw`Z``le!)7!y-+TUcZ{lEcZg)&c}+Mk zc?k+r2OiHLe`avA#>KHEG$)w?F)HI9(Z!QoXI8h1I>)g<`vvCaKU-BoK=h&lF6uUH z6TLR)9#dm}JSq%shI20F9Y-Kh;uPjj&)FHnp-&d>6GQ#nSP#zUKb?i8-Vrx^zpHk9 zJe1GdrvFjcN|;-j;k0Y>1LDXMvu2)R=$E0oaq(kX>~8O)Ju~_30&CZ!)?lKx`kH}- z3KDM(-_Ri;11Nq7(asY=(-h=~Qq0>Lt8hc{ruVEZn?a{9BAFeI>S38^c-kSr#wW2 z?Fc#zY;z#ss`{ycbhaz}u5$SLsk+tzMGvgL`?Kmu80a!FD+QEoLHgmZ%VcBv3*a;e zy2vN`<1*hz{#um_jPRX`_qLUmnriZ`9=V*57b+YR&?4&=c&TKO4Y%lqQAMfi&w-4R zfylegW{t3$4$sSK^(CjmB-a*IJk9=cDZ#^UaA!YjbMVqlik)lEy%|ieU(tOJm65An zw*9*op8+D0#&R@sATC6L<*1nOp67lyY>UUL?y|?cLFxmfSfTEE=If3kzqNNh)Ncfg z5_(TQiP61V7FVspGf~}3M`3XP&iVpLfm9Zw(RRQ z>Vb<*BUbpC;FpOSiz?kDf9g7lQ^15(X2=|fs@RJWX;XP<@k*+8Jhl7Y>r8NZ$xzYj zN|@(k7kSFj_j8sCk)hgVz+hOq)T{m1=;$|mPIb+KfDesLbr>ONUQ?G#IP1VOi{Up) z;8+Ap1Yc37&Y$hDumFi{RFd;2;b;1X4Fq)jRcDR>iR%;nA+k+!WzvvL2-)L^bhdBX ziF!J|hBKcse5_?=$)ZfZ1;nq2^vsGNRY#rE<81rM)K4~VU8No@6o(YNjG*t5jI*fk z^GhS|q9?)_-2|ef_q*LxX%ak|mJtw+X$CQs9h5IM_pUT$``6i>`@LDJJ`+d_VK}o@ zeLLE&%e4Kq6W2F!@^;m+sO0CjqH1LyWYvJ^(-@3*`lM1r7O9WIT1%58uH#bX}nM%D)g>*ppg$ zsLAAU*CuhTXFhgdzM;yDC-Sn7Sjd!s)Bpyz4%?VN3_vWIK}h++xhFDjHHml6?D>8} zaL^5OrJ4J>gMz^G-%vd^P`T%qi{1t*^*qrZH*gRu0~&+-s%uFpxVvY0VDX(E4<}5` zNOF*%HQeY_fJIK+hZ?k(gY{mUCWRKC%)(vlh#O3>ZK>DsMA&^nYAeL3HJ^1R_o&b` zZebN;d^L9R=;LM0(Y;Grf}t8|=$f#t7RlEPJ}P8Lrrawoxv8ecEmb-77o#>#60BZ1 zG2EIzg)18dcsi&DbNPAK8pZhJU<>Ty+0&Z6jO4E|2T40&S@(#D{Y30Y5x`9;a5`{( z3v3Z=-FeL>-%QX1!jOATOHUDAlrrusrZR?gj!mj-S-^M`Dr8*E?X8MdbywKN=zrd; z@YZ5M=5vz*Z&Y@p{EB21&b##pRo){U%F~@_eG5&yDSH0pOl$KRDor)wYRU;npN09R zJEalm>2%C#Lvj5+nCwC4ys@1J4dnz)MYLO_jTZ|+Xl5Vbd?Wef^}(4=6*HHx_lIo^ z+rj}HhRgs=eR7xxX8ug%k6&c)un_Bk=dc7|QQXZ*M-zDVu;xp1(Py#UcjNl4N##=; zoK=E;(+=Jc$>Y`4Hl@TV->l|zGFU{dDYov?4q8}eX-KeLyB{;QTBb4`_lK|Ph;MoG zo2P^^>v=*PzYZR)&_T;~O$cGeC)^|P$vby2zzdL=f*NYXuQ&u2e*a@JyTDIvZ=!?Y)=@&tmzQG<-H~ zukv}(`mU#GI1$bg9Z~$&SlFw~9|u&CID1H04Qi8H_vMvbh9zv)LE&NXVIBaq%P%*e z4P?ep&AZ-rO@&rXGm&jMa{it%k}HKR&2j0U)l4hbNz=4t%MQDa$20^EQSkWt>nK{_ zQiKa<9sQ%OE1i#9H*Tf@5Lq-UTMys+cq~L>X@rp%jOgDS&?Xtv@}?y?D9KbFAl)he zaklNcL$Xf8f3B}^4NsxLN8a08dEG8VylXeQiS)sUa&=|C@V-V8rtxhMR$(6QSn|1q zo+R3Mzvqn}1BkU)kKU5xF>~nJG96a8S$tGoT{e%%rm|Ljb1FK|u@`1DO@Dgyb>Xxn z0$Y+t#b6DSvvKpjdb^b0y3#ddrnvW`N8DQGV{QhpMD=LwNaZ*i$goOubyNhjxY@jx zxj%}z*S?*Nt~K@E;8axSvyq7fs1X&!@@mQl^9-w!gJ`tMiG}DM~ zo%lSS4xRFP~E0F_^C@h zmo#bnrbp_^DQXoSue!|AmObggliZ_VFyjQu+ydSf+KRvxrZk1{+!m{~6Kjzu55SIL z2?sFeH@Ivb8Ud9|ed0r69y?eIi5IIps3)Ycrbl!lmD&MUi2|Agns3wE)8!^RM?*#< zQOoC3$pu++WQ0sO9CXh`%iDSF@67A4Di}&5A6+%Y3w4FO_!BDED9^V)oEnw65)H)I znrOiKTI*=~L9`g5?koV(3&K5|vN!KIw0&=3tetSSw^aq{Tt11#$w^ZZo;9hb@c1d4 z3bD;39gL@H@JRhg((tb~ukV$e)s2$Q8GUz`u-Gn=b^uZCLtdP}vlENW z-Co#Zy8X_o{BZn^`kfglvand$ccRh zG_R|Y%o($1g9kJm^OL+F6jLg2(y_Wiu8vs1zKV!5P#pSxpGGwN ztQ+_VZ1yK^^{GeU7bHdm^x9AK$E*JZh5i4))|~#069{(o%b4YWxIEGS3n$Hg;RK4c zS${$4tUz3z=>LV242aW*O6w(0&^OxfPu>RbD{rF=;_^g)a5|U(VQHE0VL?y~4b*fl z+7M(?4S;s{s9+)_QO8hCGBPnMbXgLgcTJTl)y}${usg++xzaM$3)E z4U@fTi^ZCP@q*0v;Xq7*uT*X9=R$mtjMr{R8C~FEVCu6nj|`%eB~io4Cr}iV55f;H z%~mbn1y|gsrCF`2Gn_OcPx>Qng9-bS?&jjQb8qB>YPKuv@_m#2!D&9vLpco;a2J2m zu<#p2!zvX(9|#(Pn89|nG)?SYM_Xhl#ZFRbB!)xg-p5DtU5nS9>Toa>ckOiEpMI1W zPZ{n-75Uaw{Lza(+B&Wqg_4~tgnoe%m$$-@mrWP!=lz(+J{O%p;I#--60lSA>paAh2kXwCKCWG#V=PwO3W%nFw4tXzYN%f`HaD&)a)!n=&BGYB0| zcnH0Dgob7SO$@$JJSM$HHl3497Y8%{C5x0k-r;!2Bft1FrXVMa8QKju_o8&-|T zpl@jb`nUjLgIdJu?C7lbZ`jzyG)h?X!K*oRFuD`Wf_j&oxB&OJsuY4+@Y+*@G$t(udvk(MwdRuWmb}7BdwC+ncdVvS*tj5BPO$-yL5{ z_lk#GltZD)=^8tPe#XQatgcEL@VkGDd7@ZF;&ji%av{d1ZqwaWjWUpwiD~46d<-<` zcpSFzYHripdwbruLQ(?_@pTGf;5fg8(pB(6NvUz!_0vZpU&Gid&3-LpTHUd5iIri> z#V?0Jr2sb()3`@GwYID70quy{>#&5$L~UqyUsrhZ+;}#IH8^^-_x>~ro48D7vRi2Z zz4-$mr{C+u9^V{)3fCH$FhX?tS8tcheg9LcHyse}hfdCUT-#oq+!yzDl(? zT%w+RSNf6_X!zxFsYidpbzBNY1|Qz2F8oyyZGU5@SZ@|rQ+ zSrxmU1i3*%TsSn-8UH`vFHw+urjZd zOJEydZT>*ulnoPcs}JxlA-om=vE>>^wiSZHj|3cQUheV5 zW*93Y=_$Ybj7Ei5gqIgVAOo3ySDX$J-P z?9J`>!@D2BeM>%@?oNu2u;z+<`PP28^q{IV6%hl`Gc$M&0?yu8GDzA#GlQUp&EGp* z3qhgC6aAqrf7yZ+#K#BWmC30>!IdMA&d~Na3mu`+*5TG;*uc9WL|<*~(odLcc&{H} z?P0pedTwWM_(*M*SeU-4ZVj~_?_B|xUO*z1dR$-QrHk%)-unYznDasggju@s{(!lG z6%Q>jM7j3B?{#!joO{f?z2JZL(6pdC;HLda#{BG|nOU`2exZHQK0*_)uJ2 zVVT>s$W{oaG(MU zwrjh@3y9uwf^}b8C`yh~i@i|HkFZo-HZL=*lAG6}b?>@|xKZgG_0e9G4QOS}A>h$;%`J0~VikP(!P?oK zyz!E}fuO-OZQ*2Tz1sG}XTtr1z?AIed*;=LGzEKN1F}i@zGpi737}tc#K?UP(%Bb( zEwux!cKPK7{11TsLDcVH3& z(w%`7Jr9qVxR7OAa!|)fl^aiGU}&M|5TARr-&ctR4H!X#cNYkDXE}Rx`t%80hs&u* z8?s)MEZR~52Ox&tBq8E>ep4=5RUKGpJ#ib{^WAxqY5Ml$eVZ*+1zjQ9N9I;t0n4A& zMa!5#&tQF*IMZ}q?u~wLI31&o$XBw{@9s%6ts(a~8GF2-kq#K*1-RARl}UeYlo81G zMt~mwQp4kHanzZTR*1NQWv<6$G4ftCq09WS~L*ei=WpvP^tH67Xe_ zio!xGW~V0@Em}$B_-fm?N*$~VMsuVpiqEZ**2S(KL@Z>+y@D0cvT{DRk@MShvXkUC z=p=oUzs9Y}OX#;>LbU#-LKyG%>@MZ)1a4vZUhq8mTz!K{>IW9p8YjW)TxCC_~0 z>`m#4lj&LyN>Q=GA#T0lwoDA?nYL4E(cu-HfPQ~y@krMUln>pEMhcU8)If6O15n%@ zoq0NJ_hZ>AY|!CE#mSTgG61$Fa5jXj3d$Q9g8704Y&Og@N(N#Uz-CMe>x_v4n5zkp zW)cdwtVkg|d!Y!Ovl3s=#K~+pALaJ$7Lks7n4tFqi=&zf%PHL(H?e>%J1*|hzR9LA z@^4~2rFwSoKxNv>QAfO(MUxc>d`G{?u#Vl-_f}|*Zw308^%3OPaVr+TOf(D8o>g17 zH{j8l&k3tje8b%Oa&HvxNtW20!ucI)Msp>!Q|ziirtK4WD7pkXziXRjf(%)Z$rLvEwCdV{!+{QO+Ys&&PgqN_ z-StMu+5JKH7H4C#*0Fq?Gx9F5`<@S@&}z@Z;i2H&M8nDVi)V#^9MC5t3U{#t{mjh) zbpdhy`ed#_>g$RAP$-(eN1TS0gX2ngZi9a@K3Wy~K1SJ_Ootmp8n6zqs%b^aAM%ou zvsh&c$FgTp6`TT!_pu47dh!t+T`ze|RDEP)^r*V`HK4ZaR{G3&HP2)-#iwr0@6@HW z>Dm!Bcw%3#<5Tlv9pH2s5dqXH%>wGEq~J*M&$SkvH9CGxRv-2_)?l9GJfu&!X*+uL zsTkh!N76Krifj)YZF7o~e-SCkCS*RDF-4g++~SO?^lj&n`J4#5UYLFnS^vt&dBhEW z&7nQ_p!E*phB8Api{Tn9pI4Kl;8N5?dAtyd&G79DiCda&?Iib6I6U(Cy>==by^r@` z!KJS%i(6nHV&wRsn(Au!niTN*vZ%DBzD2hwhCCjqCZ8UF#jUf z+I54N^6C~|@Vp;5D(O0NqM!Jomyx99jd*;_l(78nEtQyON=8iqo_rGZzyi&?&$=;O zaF;rAeKh=+``txHKXhJ_?Td7UG|C^WJMXjo3=||Cos8@MED9629VRE#OC_ZwvrKRr z4Yi;6c4w+~gyWuDqQ$qx&G?JQBg|Sq4lZgvF;Jqd`91TYZd!Td?JeF%vG02tz9wbk zwP5G(CrBSQSjgM64UYgRFv{%Lw5}~hORF4>KxnyJ2<*gAJVpADA^Ey>+!a*bpS{MC zKQh(!Vci@V5C6cSFUHMsd5m*uZG&I2SrPxOZjJ$3#5XQP(U6rpaz$?d1r z5HUWsX|HwU7mhzE5YN{ip)W?Kp)eS&tTc|eIH8<(%g$vdWxuOJOZpR@{t&NtV^(|! z`e{Qsy81(ea4^rp6o8gE$FxA>8b@niP%PZH)F9$x?wZ$-$K6-2{LI&wOlN+ z{L`@)@jW?BOA1C(9Q)jBp|c`P>;Xt85_68xj2h^B@G2C|hO*+0*Zr6s883E_&Ohmc zF_r6J>7ZS5LXLYa+*VSlvjVK41?tF6+2EbPaskLJVpVAPk0P8?=6Vd--Yvp0b^M`O#^RFkUu5xpgb0L(B;Xr4?13-E7Lz}_TPD4if@d^}p~ z5B9>Jn8T{s|{Omld?4}ZUoh;N^XpG?cKt2HIe$M=#$_@(Wq)KNhN zBMv${!j+d215{?4n0=Yha{kj*8N11BZJFFRMp|i&viQwK14kAt+ULez!l6IOVp#&! zi;UeCPJ|#Ess2A5*OHT9nizhhUJS|6@YQ#*x<5d zZ+{ci;-#a}ZPCdXKU5T+V=sE!0+mJ@C-^bj-WJ=g>}q?*bNHH^i7y*p{y@Ul_+&c>#X}w zm8EQ6YxyO(+anCLED;!#&}InwZ3lFg1#|SEg{dwPbpLGL@iZPXSEe%}*>)e+y!+L+iW%dAXKy;6kw}|AOjjmt3ohke$-^&^kciBviQP=!f zSxw#~I&NcVxYqPMy%b+^wJ8Ui!s?{iBs_Osd3EZWv8nmyK*xLLra;BJQrgJoh~}Yc z7yh$1bZ_IQyD^s)46Lj}*2xsDV9Gi_A_UO}LBoF9)5RJIdwpcY%iO7Z+K0!CVJeK*K!bzH<#|eZS+~&Q#iqr?i9Wl$0ng0^wNWPqIas)y)zV$F zS<^X^T$<&2-*^1V`Vz^M>_Enw6O9ecBx$?a(a5VsfS30bDYn zO3-;tsr0NdMjGB#p4RXLmCi>YR6bYANlHVDCo00xQ5tJK^UYDvA_Eqlp;cUogZf^? z*`<6mCe5jBZ5XqvI5l^#hrwQai<h6V)K|#GGiD_HXhPGV`20olW$^D zH8nan$EKglF*CUxw!SZqIU`cfAO`WXnZ0dA`FD~E7cOS3WfJ8stvtcIuL<)pwNXhs zA@%NfEeI0FtnwSndb=uX`r3NqnvmjKo!!*S27`@7J*D^qx8s8EFP}x88lby}oik;5 z$^@MK4$MKR?7tvdmLOq%qW=gi^C4xQQ$8aYQJL|aiD6iW%&LqU0S&emEL#fsO_<|J(%S2r5?dTN6@3yG8d{k{6FueJzwZ)TcqO zZD2_5Y#T?19YaKG@M&TI3!2P9($cVn6>dh}IZbxQ8>STc7HzVc?K@p74e{DfX{V2^ z?|`Pn`fw=w!Wy5CtGN12+RJ<-+s#aXR!~Wt`jNLp@lgV9-O0rl*1c~Yi|02TmG~C+ z_(+6(t1PF9bLqL*y|Cr$asC!8BwRZ(K}lUL=y~;0EydQe)QU=7?K4r$Y2T&b*0T&+ zVAM4NKQCK4G`;^qb$~tmF`2%k{N-8Vu}j{&RQ*D>g*DbZA1pP(`xD(N0ThPqbaLyp z3oarhU$JO+QtpwtJNszMS9UbjUT2jIWBR%c^vpp&Y){Tbf1dWFr0;Z~JGU?g*z&f% z$lsW!emGWvaYI7~10tSMu0ZX_#zsmWGESWOiAmzmCQ`NPjiZLVlD6bs9wvSp>h1)gqns zmJ_A>XHg&KF#T&K1_8uL@os{!67(T}A^cYCOn<@fr$ITq zC;EfaLG*vhS)#eS`FOlu3odXB6s%%9^>|mJMq!a;wrWB;AgB4k*k1r8!U?Kf-GI5* zKqw2;t$oi+c}(WWG=jxDD95Flm-#< z-HqN%-TijM=LY{IQyUzhG|_F{(B9`@{NjHyvDcu~<=A}_C-2iMgF>LEFAa1HU5Q9T9{p-KTw^Z(khHvkT~@?T!)b?F9if&JXUC(Mqo4j;DBsS-Cqeo5H$36%Ikl?`F{^=fYGVJ@Sab{ zvLSDQ6VdYw5%Uz&c`FX5sp^DK&F5_f7dYj~DZgPZhvAxxy_AB@-stw#?P`ho-9vvu zQeXAyTipD+Ja=H+$A>dp@_UZ2?g#g7O=t)FVY$J$O*&I<8=mf(*uFpl9^!4DA<=eBYZ| zrrPZocI`uR>S=MLyUK8ur1K!7zFa(YN1Tqm_dZkwHnt9lBhvw`S|3LEe#%$|9>@%W zZ!L_tzfJZq?s-)b)UJR%b^b_zy|3yL0;%@?utlIymv;#JVSXP`}Elvn&g!|lh^!)W8y?B$bVSO)Kq-KQ5qJO@{+sGuD zbX&E6*4VV7n?}I!(1TeS2DO7&Q&9A(8d~lRyFs6j6WHbcMKZ6%4*|#ab~j&vmkgc9 zq*3H6Ul4|drjpG4*yw9RQT@e-Guf9DggV;y-eXA&eKkqK+FF>9>Q=6v*!_ZxA%~^X zXTVmNWn$LPw)lBJzY>A3k&KZ+Zy-?wSE+=J0O(oA#2|V{2*;5w)X9>wdTYV`NNJS*#4|dss7Ur#Ob0qLO}IyQZFbHrwE> z(V4$HiI1S`?51*d-{Xkp$n1C3zG**gTX)MrFFn~4n8Z~x?@fq`4!A=ER#%K5N;WX( zZ@g{_m*b2w_G`#D25ziCZ;y3Ebbfao1dP3J_3E@CHX2)ovnHg-OBrUX81a|8+WbnU zLK@3u`G)utU9jJCu?8ekWDOS^V(1sC%_nKO#~Hpq_|zY9>ZG|Vc$~~Vdgor?4o^Pp z-=CfOSzP-8kryX{)4uh?b9XbR&nCpc|BKYHGXFJIbpoUYp6HLO{#QL30^&qnWV?m| zlA3!E{l~mBX>>^s8gri9Kv9jGdw=I`K=L)*f|~;+SUXrAw@>J3pK)kz=*=?jcPhaP z*L2vETK%2fW6rrm`yT}W0wjBm8P)+UyK4?S387kU@f2fU?VAWyrI+a9A$vB0ZF2rcs=V`#8agk|A|Lhk|>~-gA&xQ-=}0< zbe6#*Wyf1)FFnCX&nmF4MGBT!-I76Q^o8* zpqZ!e?^h4=|In41Kg%rEMKEBO0ebhgCJRZfIQ5(KE@si-;ntGJ%LQ=8TqGj(q(E0+`>FU$fq~^3D;X>N|NA|cO zpQ2uw%Ja8^CGo0_D!gH-1MHpsmu?{p^{a?q>UWP%AMoj4x33ja((8l)Y4QWtq|JCK z2Ea$JrsC}B@?ON=*l%YY0x!njGbft9QWhKKvkXc(T%GZ~a4;_pxw3l=#1cpFH{>oMCw06y{Y{=_c0Z5xZ4-cEiQs@$3Tl|#@ z4{zF1_}0>`t~(1{JK?Ou^2Kz^B&E&rwd-Q!-Af9N%{#gWdB8y+FRo%2D37>?>7sA1 ze$^*q09~_9wT9a6URf*oS>W>|1r(O->2Cd|;JfK}J28R>TN|>mCZ6!JupF7H(rJ?V zlZKZ?lN1~JpG{=0e)Ne=!{iP$0+~Len%Pq~dGZU}MXk&V z=C=&K?oUN3H&strilk15Lq6JpXi2WlQY6Mfh?5wZ!KQtDrst zhPw(yNzI!3Qrq>PFKpsMcVyUux-{=MOmjno>tXzz%mNc5afpU!u*XM|=rFmInoX{z*t(yLw+vR_pU( zfzd3G+tTv|!Pwv-hsj2H&2k`=*S)5lT#`wq#SCkx|BTcCmlidHpU7tSTF?mh5eh-x zkIFYlKkJDnIKJAwX&0@Otue_xI2VX&P%jFJ&ZDSNXT`*lwC4QMe+uos09En|&eG5& zJa!u>m3B@AnIXDnl)jLqH}NvHK#LgG(o+boAVg3`M;MYvyRL-dJgI*<1bZ|}GS$!R zRT9hPp@Y*;--p*xgI`Y=`OC!v8r?zr@{ECWFE=Q#C=0r5eSBuQUphvQ+MAtQ#!DE) zhrNMh+8vie#l%N?ja;tf@FGv_5`Iz6#12VvjnlJ2%Zr6VqHOfS`&cgglz;qzIacP2 z>FNo_#o|Ow793f!RPCeeZJ$5(1$4=9TD+oR?fGc~9bpTw^8l0Ik(|z!GGrQfu=nD-a7Ohq~f3G59Rz@&4WP}C>P!O4jAg_ zTnk7(0&l%GAfGvO{vajw(BgaV^o;e>w)0=W=w^`4f1*EF9}Jhlc|O6xpuPl0sLj)& zh*^O-FwS%=Qe=zv#6dCD(N46#J$5(>y|Wb3=$z-26_b@2AgK6|7iH+id+{kxY?5-( zUT-lTdsC1Hd7A~vc6k$O;e(ifvcIW1EI8+`E#2fm)hco2=OGi=?@4w$!676oCtFc7 z&%#msf3bX^g)_h5#8;r>c%na^`(G{JCFpR4MlkwGKvr+yckdu*2JY`s3MC*ePxJ?; zgAqYczZ(Y3a-0;CY^Sr&7V0LL5bV6uSHiXp;?CKbbKDC1Oh9}zedF5(bWDmv7&y1L zgOw6ubj2DR{I(|%kykA!4@vX9P8uh8!~S5YGXdb=?Ba3uya0zBYqM4cbObWN3qlC; z7Q_ORHzDTyt%Yk`egzofs$$SEy&6TuMZT@En#L2W{m|WFkMFMaLYN`*0%$6KVwUAO z=kVC>?plXP6OG0O^_ohJIrYKl}_vL3po7|Z0IimZ_(9dw?pU|aT9jU|wfD&^3 z@L_p7ODz#O5=aXdQXj|YmfmA0CLS{FV{$KUv6K$8>w-l2Q>qWD2ReJJmoVqGgK={d z(II@7--BRdGyH?Fe#sg0{EY5tgOwQHQQgro!9U^3(>#J~($U4tXA%b53(Nj1_0|rO zt|$8Ad_hx#z%PM!VG!$Apjf2e6)aL*?^MA30hZ2H(T&Qu^h7(;8c6iI6&N=6bxKyI z^%`~q_zkx+q_4X&2)}y-g1BJ~JHJV1nB;n|O72Hg$_c;LqlYcu;q`}*u5M$r_Ut>H z#~&InSYMzX1v$Jha9*{E>m{b6w)Q}pj9k+h;ZFCmTp}w!8nc>BlO3`pdmf{%+~E!_ zd4SOe7=U{ZBilWnWRwDW!)EJWWJQlz}R{Q8O18+ zWlh$KH^tqZsB-a=s85B&$v7HgN!?TjGdJ|iWH_);7fwDlyRJ9V?;O3mXYL(y6X~Ox zJY}JTON}K#DP)Jtyl);eArq^kCZ*x1nyIqy1MWDLVoGCMF4KO#*7(|MktV*HV9n0- z*ETN`i~RFw2D1n!qh4uEMwQA(m?XL7Q91j+xh`aidW3k(RW=)h)7m>C!HrdMrS8dx zj_D$x^|?6)>=?l^wSq&B*0Dg%GZkj{1rn<>bcDQ90{-jwsy_lxFkMYfjnm^GMu6Ka z+3TcN1|B1nU)}_|N&^LITex-5&sxw)$wvivnF!@z>&;0Eyvekh51Jq_f+vWgT@k zb+|RXrI6H}-sSKW>z|YPx7~N3a>oCU-FNArvo6;T-xL7l6it6aRzXX{*?)~HIRKsW z6a8`48!=6x=%AI+hEYGwqD9t?11j^EdX&8Ip5kcydeWYgUyOp+|R=!E#iLI!K^o#Q8W<`P%i&gPA&oby5g8GNFbK878z zB^FcWO&oElw@!f+M;4#UWxg>Km|Q4W`!9k*YF`?LE$l<0=L&e}en) zVVka;H#XA;Oa(+A_cG03ZlR>1z6rVDV@x7jtN@aglgv7&7^}XTcT+SSx)A)<7hSRw zzJ~X$n=T-naFu{fVj<-XKjadbwBLGbwn3euINckL@)Nw(1gTb{TM;r`zk%A#Ll}1v zV@Js_t5e$&~96=A=Z-UP&F8QuZEV#Dqaj=YfYa_=0G3(Ej1s5-4M$ny8s#e=^jH8z-F&W1;tw8^8M;amaoI0Qgj{5|ox6Fk2ev7{{k0{N z#h-mGsdsX`v?HM|$3UQE-6xG;IQxq|+Q83G`|4no-qXgiQW_aA%6erL!g22Os{xjtQ z@b}!86_5k*ME}K#2zmlY^eSL5 ziugb35C3|0m>^DWfin;+ASE#SJ6{D#Xa1G1+5tV;6aDdY2T^5TK?_|()2fh|;X9a< zmMIwRDU(UA0Zo=`G?w>OdAgd#{*NO8M{fiRPcJqKI z>YE?+D{$tF>UvpZED?LL-6)Yfoivl*7!<#un-%~6*HdGzaCBtuEnqf za=aJkE6$nxJk(6+B8&)PrL7;j%RR4V>xGp{!f-l|&ONlsrxn~F{oEH1V_i6g`26i* z>YPZ6MyKZ13afL{6IKfInM1hzi{do~`6<_zE^KptggyEq)%$rfFZ~{>HthxqY>{OF zc=y&-Vr4A6FSqMZF{mx}vliYgQM8!g0z7ZQEbjRI4a&)^nZb^ORM{Zg_+Pzagk_F3A@93*l#ws>V%AeaB|3_9yyK~Fg7 z(|V#mBu+DG&=~K@?hyR&M%TN;`W{&93)9$CJz{6nRx-LMMAgxBk%JHK95io^>=$jb@ zwVTC5L&Zb;h%uDPEf~c^f93}I8vHiNn||zUe3i0jZ#D)Gv~U$MFO#_kk0lWs07zRX zpCn6VrWS!}r|Qbzxyg60<|rTURo~se#fsf4O0eYYq-Kz-O6a6saGsQZq`-`lk=z)# znLoO=pN5kAv^2AuwRV$yH)abQVi}BIYBy;l23oB}&jCCG6uzzu{ZwJd;A_qj_p@MD zzJY`$tp7yt(ZL+ZNym}$!dZ=kY{};pA4RNF>y`M7`yO@)GClrYNhUVI$~<{7cm~-g zygQd1_2Qr{W#3h6Y?nZpWR1sqq-sT~A`=2QMGeFBW(K-lqJ5+KW;__j487rZ(^;7P z--LMD*HDJP&P-I+@K>$IJa#unyn=4V4pnKt4YGW5mdjp7C(IS&yA~n=V)JFpc$HF&{&)SE0K~j?ph)0h2 zt>mASGRR!~MqjgmB<6|!kQz|w<3A$_WgGMmx_UWqyzEdgsL%y){lMWHIs?LDz5)qE z%L8irkcpbt7?0zO9I6-40Q_fl*%-mf?Mnx7hc=Jj~ZBq#Aqj$fmwuvlJR^ z;l2xoSah!)o!s*;ck+DZY6OcL{hi&J4y;HzVzb{~l*FIXzUym~Slc zyyfG~JN$pl-xCBrvy%|A`q}$DLEwK)?ED`P_@eP&onW#BL3F%A)r;*xf#4QnRlbBI z@Ips=ZL>u&p*gR;fC`E4ffSA5>`^2Uf{f&9AL(S)Py8kg(9QUb9`-Z;sa7uxEs z?!FtfhNGV^fvo_KGpyuFzaVk$Qx#Cl5eiDQ38IW}=>n?ml3l%7i%s629uXrmt=EK-^$G_Bcv{NMKB{QuNb(|Dngi7*9pU-iG87c_lMnSNDk>^Y2$?9wBuguE27Ta$%=|ZfPZc`NWtct2-6^ZrnZA(;`)l?Ber&xe z@yqOtyXiWxRJoJ{>|-OY-xHphE0Lw)T&DHiC#+og?*CBRBwB4hb$9DOGcO;`*K?!3 zkQlg4{+#wT<-_8XS+=(SWjY61N#~`s_PWQ}PeWuGKaHD#ku}xS4$8;jwP)4bCqeqt z7XY<(|KA1aUwwfmkL*)&3M}B+S%PK{{q`z2KOw69>5Zii_U-FYEt_=!S}hK>mbp}T0lF+cJn6eND zU{dyFVLiJreh>*wnbsc)3fGo`g+Oo|-yyxN`7-xS=Y(6vdQ2WcXJ$7FuZqA!8Cuqi zl6K6ynIjlA_o7nG%)SvO(F4;8Z*z^kW=pdGPOsmGnXW2HNxXIvqP6lR-Om0rj|7ru z>|P@xUHu1f9{gd9LBoB{%02QN8}qf<@zY5xji~4yFf)N6j}~hA0}+x(d5)lC&A`R^ zro=w9>T(kNLsVmirh#v~!r7LQFw7M-!v+#vyQw#3UD>wjr86ORXuir*sFa#7siGDX z&c4`1(I*%8bg_6IHpZ1MN$D4-hsX912Q=AY*L8@1CIgYfPk4sDpRpVJa>(gZ3UEmG zO&(gZXvj^(KA40)7o%W28k3qge}6|OZb$^>s^K^Yeo3vZJ}ua6&S)}QcrWS{{GpU# zjA(XgKBQ&@Y2wyJTchJ{gYSS!>w5B}rbKFgF&RSn68Rd8koh+4TrzT~U! zxH_29b_x|zat|KiM?KaL!6>V-d3r{vll%4Behm3`bT5(~oFr(5`f%`Sr*v5hICjRE zJOdYEVIk@;px?54<@-*i?~Wome$sOT2qt90R@#wCDuZiX58&5#AY}Zon>w=|6AnrB zj8M|uKya9xiie`57>h@>rpnb#kO)Tb({=TXGl641i7x?TotXS)3WqaZtK8N1wm7(W zW1YHaP<6)JUKHicra40(rAx3^&#rf&<&_wUvle4*l%1#kZ6S>NhJcQbZaT5Pi7d9Y zbmr}OsKQC1OTK<5IJ z-#jKc)@2@&SFVW{3y{j!Z#C$3DBrz^742gj91gEQB3wHyP~vQPsmfB$Keo5BTW( z)~`-{aj$8yxZmBx|6(ie(df(n;p;7<>gtlNQCxz%LlQK&yAvR|TW}}A-QC^Y-5ml1 zcemi~?hstgJ#_NCoty6d#-RQ%#;LvclB!y@X3Y}bru+tVtZL~@Rrh$k>wgh)sDIO_ z{7APGH_HhaX{ZJTJW)R;E9Z6B?zNtMCm8k`7sSN={zEj}UiGF0PtN+zEsvVvJLilg|rd zEf^8^D>|u);Bpz4otDG=cqp9=e{{6j!Cq=5V9l0S46zX-ixDXJxp^}Yl*8^j{aQ4J#EDw zZ&$$TXQbebGzw;`=ptdK&$*#*n8~N^(ZpUHzFMeEw{*$;Q~#Tmfot%d%*c=$9J2MQ z_9GyO@h&$_lZ^bFu?=TU$m2lTOv-S(++0=HpsAX>Gwb%#qLC2$BX$NCA0)+OO>0|% z%vS2nf?HURE;ml}o^!&U*tSzY`k7;*GVaj|Nn_;WU8ZmA_p9zy+LA5W_SWOe?dx=p zTv~F#A2GmdrDH8*x$i4#ChT_>0!WMS51tY63y1-`_r=rV$f5VzrzNFHWzp!%0NeJBwV#=-fvVuyez>oO zfwid~hpmiyfZd3>0QH=W%d*<0pT*D8A>f|G=2xU9uMG)BZmR4vD^;yBL+nYlSyM>+ zz5p|yja_p6&QYQvMtjbs@;sD&;E7eW9a(UMh3IV$FNV;l#2|4-?6#j3!why{$fOPR z{=z3t!+2R++)b)NuqT@N{4UUXr*26jGGnsMsm=NNJ3>#USq?5jyhi6?1f!rZDH@a) zU8!y5xai)-o>f$}$n$IiszWXs$pGsQKZb6n*W;7%5s9h36TU=RkFk#$Lx>p&@`zS~ zR^CsLR}pGp8V>=S7OZLPT3V6~?pf_xot273#xDHZK#&wqiV4ANBY~ZeR(7H&)jxAj z5fRd=uf1(%{wi$;%2t_S%C>p}=qAhK%Fs=zN?+KtquLQnk+d&CQQQ2`+kZOGIf6KM ztnFs{?0&_iB)`54+o6s)T^S#JFL^K|oVffjqNc5nmdh)Bwl#a|p!~>xhWGD-&wpcY z0N#22&inljfYg7DS6?GXRv0C(*P`hA-+a%nOo>dtP_h3blc2AIZE~KOz9GbumXp>V z60GZunU(`(qLcUWcKw#fP-ogxXvs4d1kLRZDU6n+N(Y1fy9g)&C>*XQ^PMPYxfhRL zN#Ml}4mN~p)SavdZx|BIH)wV-)~q?g{c?1$CvX$DFlEGdyqv1S{24}B$b#AZDg?Og zPFU-fkP1u%f} z+OBrFYME-`K%`n*D;~#Q;ORNG=5%RmOHl7uMwuCTWG%))N4Gz3oe}vwo4crBcum^j zr*<~7YDOVNHY_C)H93B}xG8oL;EZp|c{4V2SqcK_FnOD%FX-X2S1NYY--T zw4)4}Q<&Ph52anJT#P?4CVEx!)R?$~qD$f%0aULB;h{S_LbuPG1Ri2fX%AI*5qY7c z>-#QBt{_#+@979Kp^HGU&C#0PD>x%&7~UzS{@l2hKT2Z+m+%>?Wu9V0qv`L{fbMOU z|1kKKaViuu8zk&MG3JIMs&^73vIjj>o?t1ZU8A0PKbwU!4<* zDE{g5j-l!f*fl=`Mgu?SVaQBRfsE$%2UKuY(gRfy+?2I#%HS;%@4j2HA%j>rCQxJ3 z`IxSJmkw&gCYufq%7)qPMFadabjA>*ShB*kv;ZQv?K-oFy}i4p@+tn3fKEte%XWtT zXYJZ781d+{l-$ht&ryB_qTrTP`ZnKoy%1yqbp5`ph(0@54gZ{@s}q1-R51aEr^O)a zfcuEyGFrIKF>vdPH~i&5(~76RtSh{fH!1e;zPEA9`B(z*;^$|#YXqjo3evIzJ2*1} zZT;nZ6mJ(pCfY)|1LvH=_%`+p>C2$TW`T(Gn1Z^NdRR zxBT&M`o#b_h-F=pa1@$QlCqDu^9>L4eaefgaCLn&U{$p<^MU469n=}Ao#biNo@vx< zlpVuQG-*b2W)$*j0_q`jlJu1YCwufnNm%<&JWytOxw_CJFjQLOf-ZvfM3BBZd5U#0 zQC$yGtq3lf(T-N<#RNvipRVbv(bZrR{0oi@5(lF77)CZR&zK0vw~-OG53FS=wcD0^ zBPozKsw7L*GXXRbtSM?%->>~IvE{sH_L@fqzrXh|hAc1LOAur(bvN{^Tph~EEN+XB zT{LMgBYoet#QM+O>ZFt5)-MA8R<^%9M~-Em`9kZzjHlXVq<3TE~XN$9;1@mGT{~#j}`Tp)GfY4 zi)r=h{IJoQYyDI}ud7A`eUnf6SC_KD*+#)Gxpe&9<=bsQFk0lv&$+p1m`dTKC;g1s zg3J=Sv+r~;8RaMor{4t@z1sqKp6YlfppT~CT;o#P;rx)$Ff`46ib2>zWG`Dw>oLuW zj65bLLAxL(ewoYI1gLR`8Z!j#zZ5r}BCAKBy>|m39k}l{U1yuEma&X*cVz}Huo1iL zBJ3c|ho4swRT9n~6l-6S4Zvx&Ty%rG#2komWB(E*xJ zr4wf*EnqnMPi~nJcro(pPSXx(K40Z86RH%`88HQz*fB-w4g_BE7te znJV(eq^p;;n$TMm{bxqgO!S3uhOdO1eVvOs6Bc@M1U2St+s3EJ0I+WPxnoDO0dJ|Q zLDvht#dDA{;znItF*ILfcdJIK5Q0pi^Ax5E0}DfJg$Ow@u+ae|fZrrUn@r|1YzwCy z#>LN&A?4X6%E7S(+Z^awJ01IVG;Z{0@U`kU%OOx*aPK$X7&kX&{}|B)r&^t%NmGH0 zFT2qZ;XpML77GsGIUB_g-k>ElW~-`pFl+OoO#UK{jgr-6db4hlHnP)Tqd7uwSc-~=fA~`2^8Ue>NHcCWv zx$%Td@2CVhKd`9My^yd}D+vwd#^0yX9=n9RqyQ{8nF!S2wv5Kq7X&C{CrpFF>KeS3AILP z7YmxeojOcYwD#}C`P!zQEe%O06By;b#w-6S9iZ1{|Ak1M1ZF;8<*&tgGRGj%&5sU! zjs+`q@FOfgXikoE-oy8X_zs2hD25?UQ2O~j!Or_6HOQ^$dJo@-AH88d*~WVBZdZxx zrYX?}iQe4r#I%^&Y|w%PCXvif@f;S3oLu^J6L8+fvd0ArQPD!J>-K}mn={nj5Hit5 zo0O;aeDzOJsr>5%*BiF{+rY=$jKH945v+SOs#qw+ z;u_Z&N6sx8BfGxXIj6qZd-^MD*I^6-8y=|&tRv_aHxL~D^+l6@QizO;k8RYMkA1ul z)%*%}HfTM*wp-Ib#9LCXyH3pD^&)^BB%yCnY-lDCGcHedw#c<-% zjGs9@=5|59y966zvGyBPSaP(9W28kzuvHZio1irxqZx#r;nKJAkBJ^3FX$pBm!nEd zbr;PyjWO7UF3^OOG3f$35>MxhvF(Ih_Z#0NU6A{J75Y^08EgM}b+`E859an)ezWar ziWV2(?Bf4E!vHCI80ddZ@Bbh;`==`qz&tcsS@K$Ao-m&-n!>*=44UVSpv}JT&-Lsc zp$o`kA4qLtQMt*{a^`nOA8S{{&RRb~*9`WL@G(&{G3@HNR*`(*fa*xGMf${{zZ#zW z)(1w;>RzW~0SWGdsvsS+{65(g7-0~`7H@BV#1e*Yz3-30{&=K0wDoYuH84G_h*Ets zNR;m|0-`I{^l34k*y=Z2Hf3}wH43$bYr^m1Q4%cU>E%o@{BK_rYOYl&TGB&|KWN%Yv7A*%7Is-{Kjc5R*lR>3p|# z?Pn8H#KT}C)PMiJXu-)I?TF_msxpYTs3g~u?V3LALr&*XmiC_i_wEiu+J-ZR6v?MR za1VD|{E+c#Z7-E^%r|>lv^PgbP*{~oma%PuZk^<2pI$a-)MY=fb~JY!9o@szCLtj` zg!l@OE6;D!Bs?}9o^MW7bTZ-jV^Z=1s7y+PGwkIJzWpv4N9LR2~O zn-OIu#|IIP*;!non*5|nAW2bza)rWqdFiuj7`23Q^&}1H_A!QgwmgtX_O*zK%4@n-ln3$nbk&KZr zV9cC^+sK91K9??G`{rGkYEuz^CmVi~M zw0B4`@7X9)Id*N6dBeL-#su`lSQcvb zy_-{n*>g{|xFsG~GZ?1S(-q1jTaI}onRtu?n68jaq`_|)&$F5F4UgwW=3y?2tI-?j zS;0)t4sMvNlBam`6q=y21(@f$`mLLOc$CCCXk3?&YtCjznftxzCkU9y)&94eaRe@B z(;ZMHJ75Sz1*{VLS1}0?L-&j1B^wz3yvkpz8F(s&gy;xS(#e9{Vv%Pigul!$g0K{A{u;UHGFID0|HLvoQs`@wqQ#1ke{xws5 ztRF&T1;|0>1)^efJWg^UYTOj)opiDjwn#r#DFqxb`1pCfCNR0<%IhvvO`CIJFl0C+ zI$cW3nVZ);XY007lShplg?)m~ss=50M_mE8Mr(pcBUcf#C@!-J28b1|1{l43gSgmw ziJ_YfZ|a0 zQbnZjQ0i5=Y<*JNY^n$$n(Mz2%Zyz|A{oCgf8kAi&^4#fQ)u^ACcQyIo^>?t&nkZ4 z@GmpnXd)h}%8BQ{>gud)qwf9E%=_IR0j>8+WIj^PFFI}Eh}njcuq<45#97BRl!Kjq zPq0Zt*L8ywL5tAApm2T_PSoXrY+EbXX2->OY{xp9K)RQDXX(8du6WHoTS+Em#@o&- z{`+325+{emVJ>=59WEzIcQVD^br8u}Yx`UM)dIX$=si0xg*8*1cJ3>S&RKKhg0qT3 z<%K#roU2A7Ry^xG+kDK6zHr6JqPcSwR;w3;z(dj24<}OYsa#*%C7&@9cv-Uv4QI4R zi;}5!J&jJZKh@STnmsuO$i!#F=-GPMC;p`0B(_~0@#NF4Y*}lH(xsXqY#_KWVwoXg zXo=edL6i(Lc`58{}&pL5~xzF18n#;^1Aqa2f^}xe6Ywsb+7W5%9Z$E{fFp~XXLS+yv0{b z#WlGU^$x%p>_ZGf$#u&F^LfEmo#J6Izbj1-%|wK{^G?&(Q37iMo^0C2*Y1%(o+A0t zJ%^zCT>FNNnAc~~yIV4M&HCdAL2J#-jnt}hcDfiouxyS_jkZ1!<-sFld0H zDPEf&)(Q|w{@{u!;KUy@v(kNY4io0~ zSF>+0(FG`Sg|vxnIVq52`AHbJS(eMIpwZIdeJ3)xLIOrHNsBhFqPYp|mFM}%B&8V9 z@eRPRCP^2)SGH(lLK^JXbqp$hRmgE`<%jQO} zMa{$F&}7*3OV@beJ{#stMGTyIp`M}jb5S3hw591+d)u!sh8bLj_wDYdyOqxm?x*5= zyrqn6-$pe2-`5HfdJ3j5B&#HQdS5!lKB@tZHhb3Kd)dT~Vf}g3JWsipMQv3PTz*15 zcTd~$k#bq(uU8ZyDx+7pecew=nd;{~U!&I7k%WQIc_w2{^vkosV| zJnk?bN?FKQ&zZkjpu_e$J7rL9fA~PXS0&8woi;yBZ@|Jn^*6mXk-{169 z1Vj78Uj!wAc!I$0^t5+Q?h9M=G23-|b_+!sG1O_nR!_y{0s35OJ_K6O{fH|7y6EQ_ zr6^ol68Axey;{pv*Q@mO#PYc485y>T_~0Gykkn0^iI^LbzH~2-J9ZWprp`Dm6}w(&!xX2Oh6zRX$$FHorMb8xAm+(qc{UaV0apM&r`C{bmY(7SIb zk1d<<7_9zrm3V0Pxrh7k8UwuQhc}!Xhj;gRqh^i9jFSC<;NM`_i2~jI-3c|A0u0Hq z?WTV?YU&R@z15`M4;AAh^sT*n$8>s?9 zDRg}UoGj-tl~hAakIQdDr2=!-Kp;Eo_|Ak<4d)GaqT10vnRn{K;E+-p&*TMKD@B2& zm0lKs)yc8q8;hmGre(Mg+XuOTtJfNKp3RsC842vDz|R#Bd~Tdb)6Utxe{Yv!)TtNg z#kvH%L3i1T)y(Rph~`vVPN@=FMp3c?`z7RQEU_I%Apih zu#NJ}o$;B(Ms)c`xsVBxt=r)jz;Y6gALZ{_ zw&&e9`Gro+K;%>ACs+8RCo)Y{CefY+V)V)|A-`+xpV;{*qImDw#7!J%x*%iAtCp!n ztocH46dD1GFXHlOBpYf&pl@N@Y)n=7ZV8Y&^(>Ql{K1oc@F!qV@|kF&o>P-xizHn( zbG9P5LtKcnZLN!)-}mo4Vw_(BAf{ zjQR%vQU{mad;lS2%#Ts%icEp$v3624Q zM$1HsynMI-_7o4hz3k!GeSF+M5n!*B8f(>VRE|I+VECKJ6^IJ_Z3Jq82H;ixdfrT& zlqo(Nc0UVVKchtFk%ZuYd_E64uJ|M9oAPuCTk$sjj;8DHi2j1KDe^^@&k*^mF+j#r zfrG*If{c}(p58zs@FvnK+Bh<6#Ek2d2(E;^;=Jg(m>@ANc{G-&~%!@e4Ep4k4o|V#X%}7`~6*^Wz zB$Pn{puI|`Woe;Q%f`b!Mz}7kH4g2-K7LLT&olw+l{ERhL}P&V@rSRK5MCnV3c6Fd zCWyJ__%>`{)C;0s@Hf=tKb~7?Fw?=;&0acmAEve& za^sYCQ0w#A{DcI(7ZyXkU{+ETTRCQ6I!mF!sgM21z z$CUdsa)t7-ATW5cX6sVPoF#an6@X~EVowlnZXK}74?YMhpPq8HLs8u%{y4ab5C zW72OSe=$sS8DdTZ1K733i%%e^8iIIAhFP#4w`Ae;UbSD}sjsInR31q+5S{#6fL1BY z5)!+<$ADUtj{`!h^K7_Q=bZt5CijPJK3kBjc*`hU7cXRxcPX-?Z=e-d=&jNOKTWy?OBUBG1`s40o$A>&20QBs?&^ z?ERB7g&1fhI-6m>76XH~r+@OD4F8uk0|lChSNUt(o=pF%s~pIL7#{9~-jP&YV}{ZM z67phd`vwtnudlp#?b|y79&x%>7i7E%q+qs5-=p&0I{hCk%}k-HkTRQuxP+r)W=4+C z>z;0=$JTwTbIMo|TzJd1h_;MeTNee(mm6`=E$~f5smt=RGoasKdHl6}NrZZ`L@{p} zMZ(IaxEKmWFr=zXS0pc3-XEa^SxOyoKPfg!OZLW4r!LlDgh7fNa59YbQv~Iv9wV4? zRIVVV8bFi9QJPe`M?WC@T(SkCEm3$&`K{MC`2i0^35z-O zZePEYb0yOwNIEL(;;QyvEUWi0Nng<^r1s5?s|g*>-oou6d}S+poXrK_M;Vqcp0-e> z!&KXWHtMBg@;&>Bw8r7hYdW9hgKPVF_hKrkxzMT2wzoS_nh!Sq7V+Ov`fK+tAzPY2 zgFoB>6R=+67c3zLILEK@*E|EygfNFVyj~PWZ(jn}&!AE0kliehC#yVXN}lcE;XD9Z zr*%QC{o>(M35AkY{-7o_H0Gwzu9gg$Y_tqv{fF$yAGXMtw0NRl~kd)B4 zUOD(;-B1O5Z#~?7(f#Nq&WYfYAhX<{U@}q20a&;I(4=vQ9XcJbrOLGq$lB@+q5&ro z=ogSnIUndE{NQ0Q<|v#60D{Rz_xTwg_!~eV52GjK6j%im4b&SD7dN!c%85TcJQncF zLYclZSOCB3^;-7z%UFP&*?$KoC%^%EmA}4>CRV_53JB9*>`Lh zcWh)9^`krv;oH=oQASusR=k8Nxv|V^py05x4ILTkPPNZ9IT_DLPj+du{>TnVjVx|318oWH>P!xgtAg1u)cq4%C8jDOcFRX)m1_)&W{ zdyq=9W4&*$T@zKK%Lcv1q}XbrH|FK*BQ_he%5_PDWaJiNxknmOO&E84Ago*>p{1ep zb&08L)L+;HzfI?j!`NG6L0&OEMm{yCvy5azq483ZtN|seqATuTiAvT2Bl24$qv(0s zM%c=nG`bkA1@r{ezWN6@(tc{rx3#9?V>axUVVUkw6_sQ|Ny-GP3bv+**%=dp+br}Q zs{YfUmnA610lYHjm|W?VIw7Z`DPUjKblgmbl~x%$)6EtZ&i&(sadWw@CzeXGv+eh+ zWK3x?xxP>A0S9oh#mr%kjoEA%Tzp8T^uaD0Zt*zxTeEdKl>Oi;o zMG$=SOI>B68PjH}!WTkz(?Jg;7LDz};t&De%VNy?*duc6?cHp9bki_60Y=#Xm?$9?^0$!(Lo>KMMU>YV^u(fu!-V;|{o3qyM=N0(!RJ9A5u} z-r{7s+PsS&z3(CvjpPjpzFZ#nk0t}KR3BbfSq5+GPLMEf)h^{85JDeN3VD+K9trWb z_E3d4QKEWW{Z*2!a9i$lOfLc#Y8%^HG#>YT8!vU=-xW?|x685T3jjzb7ks>|34R5SWRfZ}I{ygRw8#U(^XWf%&Y(51;;rPai)3g=C(i7nso#X z2=jV!+@;&>>%PmxIJQZ;8h<3;MMX3@M>~3cT5FJo&x&!*F89*E`ttP-S5v55Y9*Y@@DAT7!56MY%PZV5x<-$tmg|t&W)lk$BO| zz<-SA+A)}EUnbX*L1Z(cPOLTR3rqBnsgf#-7Ym~%Qn#FXw7NRaD%?6vx^&h7H33zaMNkCzE&0c)@ zr*s8q`hR6hTYwhrRsQQ7*h441*d8kKf3JC?N>Wlx58pN z%6LQ^7U${NprbQpd%J}Qwuq^xs3GH}SZ6YE)eer$^Gz$u9&nM|8}2@PT4I5?$@=6y zclv(l2cyK<{Zy)s^McEq1;=}_fgTOwXWcH*dFw{0ii^9^M|S5r{}6!rUrV&;!8(`L*=yGf&CKK=$iy1$!b122kZ9X4&vtOwvnE-3dD$rFA>Jh@$w@z z1XQMPoq?AikkLlDBYFdf+D}>`t=Wi zI1UZ1E%iKbI~r^mOkVmd1w}@%BpOCJZU1C$k6WB~XEF%c5j-E8;*NfKiW;!q>Se$r zo$JuwcOptJ`mjV-LsMV9CE%#^O_-keN|jnbW4(yu0UcFUJV5vyi#sh4pQHh@;THTm zyUq4KQtZ_}NBH|Dv-!l406fKSnYt1yXO31H<8Wj{gf7@XKH5tb(quoQOJ^SI3LObT zbq(fdqv_I^@*`m1a=KgA{1%w~2|8N%5CiyVOQh24{#dVLj z>0x5|r?*fwP|K_QrzR_}XA`#)q%9p75;s4p8R&{(mHDag$qn@UPgc;FLc9zImy9#>(S0Y zh}MW#(iuUFmxElI}eSHEADmxi^uk(?ChaR>pJX z9DK2>{S3leuVUwNe^Q{*}B+$hH~sAq>|(L6UNnGxg0gDIDiyL}S7Pt!j+j!}G&6f1Tn*2sSBph9>L= z^#YmI?6uTrY@EC&5)~$Lu47h@!yxK%8r8!_$uf!qCEXic@!cp9?W-!yYOmm_;gW}5 zqLc1}#Q=4N@RmwdqC?2ND#Pz}6IWK>;OD`ca~7-}ar6TPp>UY9BUQ zmeUWV&o4|4cao3pUN8EqVEa#hY{S>X3^Vi7wHfeGpY+dKrvJx<4+7WmtNgu|V}93R zkPGG6d9|XPs#c%F{EX+s3a*ohskRBY1c4cm*YZWlkB7m_k*hGqD-`RMw;!$ic(GS| zHr5XQ^KhnArBbWav}Rs8KzJ%@Y&-_oi)rl=aii9`n|7sFdc6b~y<{TWWu0SD_nX z54Az;?rPASWcp5BVYA(|yHy^{Jzk_-*K=t0e8|DD-dgaZA_c=MHU`#n4}8zBSj5n7Gp2kWY3 zJrt#OgGFVp``wHmqYqsgpF*TWLP;!o9lY*rIy-_lfKUo370@OQ4^@aN^TJlo&$G)G zgHoXn^s<}vd^Mqjo@5q;&@DNpZVOkGLCWVA3K5Y`=y}2iRG5p1ZhrNmFA)YTLjyWU z4vLt}QpwIwHYB}wLAZm?*WGfbBD!kixXfd-sll~ui!Bz$lMaJ(ZKm=v`aFBh)OLaq zeJ*2cE^jl9p)T#Hx#&*o$F4P9lJ9*l(O@lBAJ(1`bMhLxqd3g0GDR9oO+9oqF2W;s zycdGIp8UUx{r`B@!mYHnjc3C(5glh@wDp zRBhC3{ciOrO=G6ESF`zn>(O;ni?fQFkN&0qPjJlZEoqb@Ed&N|p8uI>pnv&I;r2gn zN&j(;>>UsPYB)E&qyOiD+!d%3yrHxl8>kW*xPbmene$q3^()m-0`!ot^4CTOf`r2O z3Hbp0Jh*Fw;gJ=D>En@o#((O4E%5)_jlZ%Q{JMlF0osmN`Ah9T@B061^7^VN5xhyv z^UtsTzkuL>Ynt$VMIk^;1B7;F0oeumFTjjPpRvdm6Dp&Z;%&LeRL327IKZ2kceKNU zxs4n21#ml%cHOQ;Ai7(Nh0iZH^0M(3muQCm1`;rr4MV?Mn{^pkTM6(V5oPkd08kpC zGacbzPu>;L78&zjcY59cD0n-WkfMES7{Qb*;h#xys3s0%0%~_m$NGIvojqk&U1H7@Tq~^X&wxw zGdG6%y>MWBk#<|FrRK>1ctGs{Sy> zH<;`n9fs$L%i9JfvFl|HG_@QyMTRnaQ~X(@iBYd0iCaCV@=<06a7%B8DTg#MlJna! z3v04h7P6R<2U~2<`P}ruYyHrcnsAyow+3bJJ06zJ`3il4YnmzZ+|X-HqLK!AXY&Ut z_LC7y2lpFrU1oE>C4ON-z3OtP;k{|$SgwaUTk!I5JVw;Q&~k=tsa|a`8WG57icom0 zZXk-&tU4u=`siT1n#wlo{RM4+x2$pwkSi!y5 z9o^O}pLHPaX!z~TP=kU|@%6zQldJm9ZEv_#)@%BUG-r66#Iry{30*D>&KS!m)m(kg zd8;h_9qy>qnItOuA5Io{G>Q5>O2e`kqL{}Ma(?&Vd=fSLwKXM8Pam6n+nU(pNO7e% z-|$h)#bwpJJF2Yy& zYa#YdwVMKiQ|R-v5ATg(rg0^R-CXe&PYI|20PSAED9W7^JHdElv-LyF<7w@ z&AjXC3_PZ&yw7Vt&2S z`2)vKF^Ym2WkiMN=56mi;099PRnBxMEHm6WW%iSdO(D&x?77`dXRIl{2@SgNm>&~v-4Y*+(y zNMn?`p0NsM^O`(dpVf!&;wGd!T4ZdhjqnJiA<2G7_xprO;o2i=`N|)T`L%^k@Fm@Z z?~Yv2+8~V!J9w-M-Du#ec);VPE4BQ5e3`O5&pl>Q^=Lk2ftg9nJ9=_l(L_aNSvJjr zQ`V*PRr=v*IqGon9Km%J2#DO^%e=JQ`;#vl4!BY(zpJSd{$X!{X>8VCsL>gq)qa(~ z778%Sk5dN_g}emF-d|Hqpws7E904MMocM17fZZVeZ4M=Y%6qJhyF-DAlC0lh|S!SQX49?DyXAFv7!M+o)=6q#{{DI zXSJ|&fyCKgx3x~bj`$oR`E!cQKC79Xij$2My*#;2e#uPwbkKHvi(}1k>4Obyr4lP| zX0^P`(0CYsxmVgiPj~Wm|1r_dk>ygjhYBllWBbR&I|fXPxzg?2#bT{$8P!I_J-X3K zNLn+{oexs$Wqx3ZWj+9!d+#!J$dR8&4##C9cOUEuJX_`;o>ZS-Gb$K++h`T zc3d93s3EcJ-a?_d_S*q;%y)JPDrHI$lQBIfS1jLS5*zn81k* zvVQ$V%iEpLyv^t8!-WH)5Ievb3>@J_%6wOQEITJ~PgCUDG|i*xYr4m~^CYwdK!kkPH@&tU)pq_? z_gE;yuJcJ|_?g(45#<9x!$I$U?BVI}{Oowral7AjBIhwt^g&rZhhD zl!&;`?<+R;&G5Xh`T<}k6x?|{>+q{TV`q78+T)gd=EfWB2oJ~d=A#2Ic%n|@9X3WW zbq(hLyeVrXofr9L_SoNW-A{M0M{IKaM2@-#AS3wfw*KV>%^9NM%oxLce&R_;?ZFv( zX;*LhcHm$f-qm%soq1gadAt8RP6pN>vsNb268rn=8 z!E#qN>Gtb%VZHiun-utSibSn;m@W=Z_nU(?N-Y(?@dE~su+{STdj6vu7V<-O)=0T=kfzAID8}e7D zj8|sjrXNwF<$oBQSMKXy1X%xrnYj0d0HV(;_w^Ums%gBR6olnz(30m+ClRK0odM^iaf!C#^fyKZ9Apirv03c554xF+QK zY1nN*5uw4bFr{=@x7R_AtQ8MV^IG=IFBA-~HL?gY6lSv#ZuGC!nvx6Lk}|1hyuYNb z?G?B^AKO=&c|LpR8%yBQZltJ-)~qP;?^XV?e^b zq2|BQ^m`x3g{sa<0Euz$zq5Ds{5WTyEAp(hGboal6@=Zv)PZqPe%Tl>2!dgkiWB7` zk&RhDaY@)nkUyp=B<x@N=k^`dzPZL;RNSIK=dahI0VNVaOkqga|keA-^m3nSpGRzcc2vz(IJGzXxK90T{l(chNtU z@*f&lQOivf!h#&v9f9fe0?t)j|LtZ#fa=le=5{atI1&SaM89dtJAnS{RsPbh86yw@ zyk!(_??<7D_HUp@ZWZqKA%;-a2qeXQZ^j(j)K>h^Qpwb z7(^oaY4dQc-D3vQX8_8p#mAR7_Y*igkCpB+=|*67=jDjJKAvfu3tr6PL+Yr*&2K22YeAmA~jDH`RY>du1xVG1SNb89FCp!1n%_klj4{0Ka!E? z-@LoddebgdAs=WE$+Z)F{6QdN=EU7_A$_1>H{d>|zxac0WA^Rm#4FUMM4+)gg$uoo zGyuIKL{xNsnL$i8-8$!(wA{BxF8=&Z(UoB3K_F19HoHb{^V6=f;z(voulL&b*v3y( z9RXMkhw{uM5&np*hw|Hjm$tas)ps<5)`>q`?1``2)@1RC>TYOm%dZe_%z!9M&04>? ziOQkHiac`X)(HOwsv|bBjeQATz@^#o7#ut96^{q?uu3D5=B|h6sDlYqCf&~xhTx+b zkYwCBNrv&vvec;afiQz>n+2rwP@Fp#)YL-j@X7F#n&q!|6{qqyXJuM@8GFT%NXfOD z2j!v_^16H&i1{zOdFoFC*G1qq`R<&xzMg;VOJCrE$u>K+@dh5#o_^n00dvK_k7?h4 zOYv3yS}-iJonM#ukpqlLqglQc$E(AT*;smG#z0ei^yb$h?w^owgMa6QarvGTs$u$| zybjbn#Y?+;Lc%)h^O|3+$wTBeHvEG~Enwt@sl<77g!4XS(O&T5Dz%^E2dS%o`vRl3 zpaVwI4QN8e+6QJbwk5{(&SAHFp0nts%d#LrE@MrClPQYJvfu~;+x?r52g390wDCA0 zF&MO=55>%L)A`wk=#2z-{muyajViE~LQg|jaZ+D8DO5?!`m{LTh4K~$S~NN73yHI% zC?|x%Uf_8mF-n)vHh{K7>Pz>1&|%d?{1zngT+e|u8+QN$OCAwVpE8NGZadBlMH@fU zU62vn*%y+P!(EDy&fq!b@qPj?)bZh?O9I(+D{31!5?+KgY1}6G;kLHyPh{uous16L zM-qq+e&8uFAQ#N3vePvK8;;J{6v9fMplO=5+;Ru9r=awK#->AImOZwoiE}t8;{1~k z-Q3&<+Ndy-V&3P})?8V2ND;HeQLyPB&WSy{bu)#U$vP;q-!`xT;&z{(oalt1*WF#9 zM7hv=5$Psh>a9M?t&uW!sTRDsIepvsN%j-Y4=YczwQgDNIJ8Mcee@bp0>f_8(sX%a zn?Z=e23^)u=VitPo@7rD!pR(212?YKV0f5aYfZM}$y9&m-5(A37TAyXAskNi;Dnz! z+BdyU?U;0u%`bfFC0WdLL`maQ3LO_;s@WINm(77MoG7$X_=+v4a)fSyA88T#u-<1_JU@kT z6t~LEBWPPVpf~32iBkv43!u+{5U$y5!26#-YL(n4q1jRkyVd6gHF=4QVDab6X$3=Z zVXQ^PUTj{QJi4*0{oM2{DZHwVyZ2yoS*33nA9u)|YhS5U<%ns6%&2;9MEU>tdh4hz zyXActM7moVB$aNEZj=t`ZlpUzy1P?Kx}>|iySux);dgWNd5^E_Ip4*aKiTVZ&z?Pd z_QZ8n*$tSjXU`Yk?Q2vx$KQtm7;V=!yDBs=Recyw-5wF>o-~y?bznQ{a;}7@_U>f85xM|`r`Y@T~sg+3d6KbcUzFKh?e#Y|f| zv4xv{(Di01Cx|pakFpFWM!J9$yEC>oG~m%Q0DTIb`n=NY=s0CuN-_-R=0|v<*W6aFO#9cg63wxw z2g|FD{7MjCDl^qG^}i(G7<9iSy)~cl9aR51xNSk`BB|6b5$=KuyIFd(W+j{7u;npC z+z-^OOddj1nhoGZ%xNmNLQ&z9ba*=Em3Y=bnmdt2n)!!E{ae?@la*21H%U)m_oqwd zy6m{uWXVknV@D@x@Mau$RLvPH7e(NYw@ReInSxE)6a#dV5uIHXiv^67XPhwQzNxQz zC0{FZ2_x@=k0qoXfvuo>oyFI`F`{hVI?kG>f*i!{K*T)9xP`Eg>von?_bT2bxPfrK z+?(9zi9V2rDbtnu@URDMvpc!JoL4_yzd#ME!J|!6R0P(Y*)?dN}ne$asUp=#57 z91qJyqXJxSu0yLFnu6HPV3U|HsM9`F6gPE6Xmx0 zQW4mC^?JGp5ZzFR&%;iA@eH!H%-P?fb6I;#+u78iBtY9iH2V*v8%yVhub`ZvGi#=g zPq}L84o`=|b8ZdHgMnZL;4ltvYMh!Vqy>eh?xNDyWbvU47mPY zOj}xXfvR3(h?(<0 zVDHstQ!aXwRxB!iq`Y4MH@-OJVdP*epwhJeu}Ow@dB^4L&3pZT*!Ja|%~x=wlO%D& z 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±HCECgTMw*O(jVGH_G zcPuApVc<*mP|8d&<7YdKOMXAs(RSwI8YchmV-neAx6MSaL+XQ1 z7DNHXhbRmS>fu@SWL6FSSkLgcfzHj+FQR~D-A!xb)o&(loBZyrkx;ITo)&YeFQm@K zc+)))cev;-+7Hu@U+s|0YF=7~D$0>>C_I6c|83eCb7Da>H`TFJKR@UA$>|x+E55kr z$n>T)H*zB~CC2XPqAsJYdzuk!2%qR@52jkM(XuVq;fk)Gl$dNivXsnk@nxS&bkZ8C z%f6rBA`F*Dm#SbT<^fmJLAn*(UYBABl@$22*a^2MI7y?b!~jUCPFh^3qH$#~v2%~m zWOGg1VFV{h#rcWYF1v%Dpmu)TlEipl+elE~23LQErdGEIN!VnmQk5s;9l|~HzK?U( ze(QTN_4@^^*?Zn!x#ay7R`AR(PKYtvLgIwMEmn&Mf-}m1CIw`H0R7i4Plp}8Z0q9B$YdB&djP9=)5P1 z?EYb?-~l&7z;igQ>Rc1~jH@x%Y0^y@pp|Gikj5>?6EBPR%%}?))COjJB27ofx|?XT zIQc}ga>l8Q(vNMdYTe)%tT!}k>^iU+q%4btKT5I_mY*cDB&cvsS|{PUHAaG!4euSO z$gppIVhxD1IMP*E*=4AND)MeF$Mw1Vtc{$!A3h*wLuGS4k0j9 zprN0~_c!E0=!Bj`Gah+gGu;0*(?)ZTZ77;pPwQp)f_@+fd4O-=2{HMJ;Qzbc|16IN z2C@Hl#^3*>Oa3|18+Y*UJA(hg9sI8&z0q#AhqL4={~^r1IoiPPP>ig9>z;uDlc8_+ z$JQJRtcmUxc;BBo5mod)hejO0g7tx>MNko4WyK3h*Xu)OhcD9^@_VdoCkp2G5}<*z zy2d6=lT=-E&a+F7TREgJgKe+(7Eo&h=6eehW z`lz8vcvqS|Wa^O{OAx)jTM~=Up8+2mJ(19Zq+AC|fm!k{o1=~;Y8*e%&-4bxs1!lY zf|L#@gB-o{(l)Yyg?HhQ?VPaRUcY_^;TK$)b`{;mvxbRtrnUOI^Kdd5yV0Ec>RSRU zqB%=xBpSKDv7&@PG!4x-n`QV77l(5!Gx!CFEw}!PO*IC95QaSR%4{ZK4-E zhh4svco1NO`;4~`Zj?6OK;B@@g4-t3PL zejGO*yeJCnfkFZ^{?%X2J!n2*px*&SJe>DO8TuDH>Sx3aeIow?-tDzDBHk^P3n_}i%n|2YxTrnUs{tA&oJVI(tpd`gf!B=NBq(n<2Gv|B6w1?mnV9WL5k?}G|t;;`> zVYj`E0q&KqI{SW?;0!?LE$ono+z>9igT_25=a)!+zG%OmrvcF^cVcLepX_V%9CAXE zN0JmY=T5aun4K7~E4DRgLv(yZ``m_f9U} zh*5b}N(PJ1k??vK0n-Ha6Taes{p>P>ii}|v*W2^R@{w&;PyJEi+g$xpYzUe~bB4_z zMB&WC+YV&jq~!Ib-ww#Cm$yukc1iK!-Y>OBN0&!8{7P=&JM-hn)$wqKU6p#IHRLbfCojT!>a z7EJ>;s$1kVN!~4QSe>XTUX}Q9=_3z1PCS9X5o4q`9i?-uh z6(rG!osasDT!T^$=evfwF6PW&*Rsup&#J7Vspge{_xGnOUmjKS`_g0;0NOayYwodn zwVWSd@9>g!z?HLl?WWxJhe|y&;k5QXIUdKwd#tY0lU@n+mUCNums~wc2oHDulJj6N zM*GWk^@pL@(dDGB@v^9VE5Pb7y8eUuXcfCv#ck33Z|S|us(wsoq z℘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 rockfalls = matching("Rockfall"); - assertFalse("Motherlode rockfalls should be catalogued", rockfalls.isEmpty()); - for (Transport t : rockfalls) { - assertTrue("a rockfall needs a pickaxe, so it must be plannable", + public void theMacheteGatedJungleObstaclesQualify() { + List jungle = matching("Jungle"); + assertFalse("upstream data should contain machete-gated jungle obstacles", jungle.isEmpty()); + int gated = 0; + for (Transport t : jungle) { + if (t.getItemIdRequirements() == null || t.getItemIdRequirements().isEmpty()) continue; + gated++; + assertTrue("a machete-gated obstacle must be plannable: " + describe(t), Rs2WalkerBankingPlanner.planningCoversPlainTransport(t)); } + assertTrue("at least one jungle obstacle should carry an item requirement", gated > 0); } @Test From c626321c794ff42b811274c37f4c3f8f65cc52d5 Mon Sep 17 00:00:00 2001 From: infuse21 Date: Wed, 22 Jul 2026 00:05:23 +0100 Subject: [PATCH 48/48] Reapply "Reject walk targets that are not walkable terrain, before routing" This reverts 5c06b86e00, restoring the pre-flight guard. It was reverted because it appeared to block legitimate walks into the Motherlode Mine. That diagnosis was wrong. The walks it rejected were targets in genuine solid rock in the Dwarven Mine (region 48_151): (3079,9710), (3086,9719), (3087,9720), (3087,9723), (3087,9724) - all produced by clicking the Motherlode inset on the world map, which resolves against the host region's coordinate space and so never yields a Motherlode tile. The guard was correct to refuse them, and naming the nearest walkable tile was the most useful diagnostic in the whole session. What was actually broken was collision region 58_88, fixed in cf8cf03003. The revert reasoning also claimed the guard turns "degraded but progressing" into hard failure. That does not hold up: walking to the nearest tile to a rock face achieves nothing, and it costs ~30s before failing with a less specific error. The remaining objection - that collision data can be wrong, so "blocked" is not proof of "impossible" - is real, and the guard already answers it by abstaining wherever data is absent: no map, unmapped target, or any unmapped tile in the search box all return walkable and let the pathfinder decide. Only mapped, wholly blocked terrain is rejected. Not yet verified: this has not been compiled or tested since the revert, and TargetWalkabilityPreflightTest asserts against Dwarven Mine coordinates that cf8cf03003 does not touch, so it should be unaffected. Co-Authored-By: Claude Opus 4.8 --- .../shortestpath/pathfinder/CollisionMap.java | 13 +++ .../shortestpath/pathfinder/SplitFlagMap.java | 14 +++ .../microbot/util/walker/Rs2Walker.java | 75 ++++++++++++++++ .../TargetWalkabilityPreflightTest.java | 89 +++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java index cee0e1570e..f5365853f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java @@ -67,6 +67,19 @@ public boolean isBlocked(int x, int y, int z) { return !n(x, y, z) && !s(x, y, z) && !e(x, y, z) && !w(x, y, z); } + /** + * Whether collision data exists for the region containing {@code (x, y)}. + * + *

    Required to interpret {@link #isBlocked}: an unmapped region reads as fully + * blocked, because {@link SplitFlagMap#get} returns {@code false} for one and {@code isBlocked} + * negates all four directions. Gate on this before treating blocked as unreachable. + * + * @see SplitFlagMap#hasRegion(int, int) + */ + public boolean hasRegion(int x, int y) { + return collisionData.hasRegion(x, y); + } + /** * Single walking step permission check from (x,y,z) in direction (dx,dy). * Used by {@link PathSmoother}. Graph expansion uses {@link #fillTraversableLegacy} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java index c15ce436d6..8afa384bf0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/SplitFlagMap.java @@ -69,6 +69,20 @@ public boolean get(int x, int y, int z, int flag) { return regionMaps[index].get(x, y, z, flag); } + /** + * Whether collision data was actually loaded for the region containing {@code (x, y)}. + * + *

    Callers need this to tell "known to be blocked" apart from "no data". {@link #get} returns + * {@code false} for an unloaded region, and {@code CollisionMap.isBlocked} is the conjunction of + * four negated {@link #get} calls, so an unmapped region reads as fully blocked. Any + * check that treats blocked as unreachable must gate on this first, or it will reject every + * target in an instance or in a region missing from the collision map. + */ + public boolean hasRegion(int x, int y) { + final int index = getIndex(x / REGION_SIZE, y / REGION_SIZE); + return index >= 0 && index < regionMaps.length && regionMaps[index] != null; + } + private int getIndex(int regionX, int regionY) { return (regionX - regionExtents.getMinX()) + (regionY - regionExtents.getMinY()) * widthInclusive; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java index 3a71bb7aff..0851d6b491 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java @@ -19,6 +19,7 @@ import net.runelite.client.plugins.microbot.Microbot; import net.runelite.client.plugins.microbot.globval.enums.InterfaceTab; import net.runelite.client.plugins.microbot.shortestpath.*; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.Pathfinder; import net.runelite.client.plugins.microbot.shortestpath.pathfinder.PathfinderConfig; import net.runelite.client.plugins.microbot.util.bank.Rs2Bank; @@ -625,6 +626,65 @@ private static void waitUntilIdleAfterSceneWalk(WorldPoint cancelGoal, int timeo } } + /** + * Whether any tile within {@code distance} of {@code target} is walkable in the collision map. + * + *

    Pre-flight guard so a destination that does not exist as walkable terrain fails + * immediately instead of after a full route. A walk to {@code (3087,9720)} — inside the rock + * east of the Dwarven Mine, with 0 walkable tiles within 6 — spent ~80s covering 100+ tiles to + * the nearest reachable tile and then reported {@code partial-retries-exhausted}, which reads + * as a walker fault rather than a bad coordinate. + * + *

    Permissive by design. An unmapped region reads as fully blocked (see + * {@link CollisionMap#hasRegion}), so every ambiguous case returns {@code true} and lets the + * pathfinder decide. Only a target sitting in mapped, wholly blocked terrain is rejected — + * otherwise this would refuse instances and any region missing from the collision map. + */ + static boolean hasWalkableTileWithin(CollisionMap map, WorldPoint target, int distance) { + if (map == null || target == null) { + return true; + } + if (!map.hasRegion(target.getX(), target.getY())) { + return true; + } + int radius = Math.max(0, distance); + for (int dx = -radius; dx <= radius; dx++) { + for (int dy = -radius; dy <= radius; dy++) { + int x = target.getX() + dx; + int y = target.getY() + dy; + if (!map.hasRegion(x, y)) { + return true; + } + if (!map.isBlocked(x, y, target.getPlane())) { + return true; + } + } + } + return false; + } + + /** Nearest walkable tile to {@code target} within {@code maxRadius}, or null. Diagnostics only. */ + static WorldPoint nearestWalkableTile(CollisionMap map, WorldPoint target, int maxRadius) { + if (map == null || target == null) { + return null; + } + for (int r = 1; r <= maxRadius; r++) { + for (int dx = -r; dx <= r; dx++) { + for (int dy = -r; dy <= r; dy++) { + if (Math.max(Math.abs(dx), Math.abs(dy)) != r) { + continue; // ring only; inner rings already scanned + } + int x = target.getX() + dx; + int y = target.getY() + dy; + if (map.hasRegion(x, y) && !map.isBlocked(x, y, target.getPlane())) { + return new WorldPoint(x, y, target.getPlane()); + } + } + } + } + return null; + } + /** Door / gate from main path loop vs {@link #handleNearbyRawPathSceneObjects} raw-path scan (same nudge UX). */ private static boolean shouldCanvasNudgeAfterDoorLikeExit(String exitReason) { if (exitReason == null) { @@ -1268,6 +1328,21 @@ private static WalkerState processWalk(WorldPoint target, int distance, int part if (debug) { return WalkerState.EXIT; } + // Pre-flight: a destination with no walkable tile within the arrival distance can never be + // reached, so reject it here rather than after a full route ending at the nearest wall. + PathfinderConfig preflightConfig = Rs2PathApi.getPathfinderConfig(); + CollisionMap preflightMap = preflightConfig != null ? preflightConfig.getMap() : null; + if (!hasWalkableTileWithin(preflightMap, target, distance)) { + WorldPoint nearestWalkable = nearestWalkableTile(preflightMap, target, 48); + log.warn("[Walker] walk rejected: target {} has no walkable tile within {} in the collision map" + + " (nearest walkable {}); check the destination coordinate", + target, distance, + nearestWalkable != null ? nearestWalkable : "none within 48"); + Telemetry.recordUnreachable("target-not-walkable", Rs2Player.getWorldLocation(), + target, nearestWalkable, 0, distance, null); + setTarget(null, "rs2walker:processWalk:target-not-walkable"); + return WalkerState.UNREACHABLE; + } int partialRetriesWorking = partialRetries; // When the last partial retry was spent, so route progress made after it can refill the // budget. Without this the counter is monotonic for the entire walk. diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java new file mode 100644 index 0000000000..7e813a0383 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/TargetWalkabilityPreflightTest.java @@ -0,0 +1,89 @@ +package net.runelite.client.plugins.microbot.util.walker; + +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.CollisionMap; +import net.runelite.client.plugins.microbot.shortestpath.pathfinder.SplitFlagMap; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Pre-flight rejection of destinations that are not walkable terrain. + * + *

    Regression for a walk that spent ~80s and 100+ tiles routing from Draynor to the Dwarven Mine + * before reporting {@code partial-retries-exhausted}. The goal {@code (3087,9720)} is inside the + * rock east of the mine: blocked, with zero walkable tiles within 6. The pathfinder was correct — + * it stopped at {@code (3056,9720)}, the last walkable tile before the rock face — but the failure + * read as a walker fault rather than a bad coordinate. The intended destination was the Motherlode + * cave mouth at {@code (3060,9766)}. + */ +public class TargetWalkabilityPreflightTest { + + private static CollisionMap map; + + /** Inside the rock east of the Dwarven Mine — the coordinate that produced the bad walk. */ + private static final WorldPoint BURIED_IN_ROCK = new WorldPoint(3087, 9720, 0); + /** Last walkable tile the pathfinder could actually reach along that corridor. */ + private static final WorldPoint LAST_WALKABLE = new WorldPoint(3056, 9720, 0); + /** The real Motherlode Mine entrance ("Enter;Cave;26654" in transports.tsv). */ + private static final WorldPoint MLM_CAVE_MOUTH = new WorldPoint(3060, 9766, 0); + + @BeforeClass + public static void load() { + map = new CollisionMap(SplitFlagMap.fromResources()); + } + + @Test + public void aTargetBuriedInRockIsRejected() { + assertTrue("precondition: the region must be mapped, or the guard correctly abstains", + map.hasRegion(BURIED_IN_ROCK.getX(), BURIED_IN_ROCK.getY())); + assertTrue("precondition: the tile itself is blocked", + map.isBlocked(BURIED_IN_ROCK.getX(), BURIED_IN_ROCK.getY(), 0)); + assertFalse("a goal with no walkable tile within the arrival distance must be rejected " + + "before the walk starts", + Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 5)); + } + + @Test + public void legitimateUndergroundTargetsAreAccepted() { + assertTrue("the last walkable tile in the corridor must still be accepted", + Rs2Walker.hasWalkableTileWithin(map, LAST_WALKABLE, 5)); + assertTrue("the Motherlode cave mouth is a valid destination and must not be rejected", + Rs2Walker.hasWalkableTileWithin(map, MLM_CAVE_MOUTH, 5)); + } + + /** + * The guard must abstain wherever it lacks data. An unmapped region reads as fully blocked, so + * a naive check would reject every instance and every region absent from the collision map. + */ + @Test + public void unmappedRegionsAreNeverRejected() { + WorldPoint offMap = new WorldPoint(0, 0, 0); + assertFalse("precondition: this region genuinely has no collision data", + map.hasRegion(offMap.getX(), offMap.getY())); + assertTrue("no collision data must mean 'let the pathfinder try', not 'unreachable'", + Rs2Walker.hasWalkableTileWithin(map, offMap, 5)); + assertTrue("a null map must never block a walk", + Rs2Walker.hasWalkableTileWithin(null, BURIED_IN_ROCK, 5)); + } + + /** A generous arrival distance reaches real ground, so the same goal becomes acceptable. */ + @Test + public void aLargeArrivalDistanceReachesWalkableGround() { + assertFalse(Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 5)); + assertTrue("with a 40 tile tolerance the corridor is inside the search box", + Rs2Walker.hasWalkableTileWithin(map, BURIED_IN_ROCK, 40)); + } + + @Test + public void theRejectionPointsAtTheNearestRealTile() { + WorldPoint nearest = Rs2Walker.nearestWalkableTile(map, BURIED_IN_ROCK, 48); + assertNotNull("the warning must name a concrete tile so the coordinate can be corrected", + nearest); + assertFalse("the suggested tile must itself be walkable", + map.isBlocked(nearest.getX(), nearest.getY(), 0)); + } +}

    zVNBtBa}9*8eScS}2kvl<(zBMO1=I#RsmNTVWY#ds1@=gUK916>PY7&&x=}`cySX#$ zt6yWBb(fJEa|VsK-%V?pO%`xIttxV7dj8GCtHAD>s*w4oc}1svA^1H%g~3D z8-={*hU-$ z?mQSM(`E^3%1OcYayWubBh(^XllkuAjyZ>dYsWTd%9SIYlS6V+s5g_{7hQp4Rp0j@ zy}p6jHbUzeYW;jYA63wM!)#kTV<_d(M1|QDK;MpdjVSez`RadwZ7i$gDW&LxDSWlV zlnA$W7)Iivn0R5odnkq}tOY@ir>HC@6JpPAzRu0L;IpLOdWbAX;(w?dTlPzWf-7P! z^Jgtx6^0K*f(u2S8_6CnH&+?ncXBwmr4`%Q6S%jfl{t}0D^#(xdEph$tvy2ydG;0!t6E?naUNrVux z1*~Jd5#4-vaN(Yk0lMNtk07orXr1XFIfMih8^)#aQd|7Z>_QK{7Ff@6OW$i>u`EC$ zy%<$aWSSjg$klaS3hTV1!PXT%kyUKLRK#iprMSUhVa*~;^awcUX$#~JMj3)f*);=S zmK+kt;JrYRaTu$U*5a$wU~+fG*$sV$qSl9X_U(=c%b=|8$rV{kV`~y6j3wj7j1mT% z%J$(#m6x&VZwA5rWH6;YOS^t|KkV;iWi&CmrBF}XDj&>(D}A)tb0ZUkVMK+4N?N{y zG-8-eJv}voD+gypoi@owMqOXU)%n>3MLg_&gx#w@JFWD3$K1g1#sWDaU! z>x=$i-24d%0+vhvmwDX0RyIZ=piJ5W?5g}#_%i~=cq|6G+0dR(aKJZ;yH)B9<|v3= zxPmh=GESemhkZZA_Gy8@;mCYtBZ$X!IshWpI-;J!)dr$lw5oimfMTlTf;djb?8#g8 zFM(^7PyB7b0~R5jAs~W4Kk+|+-9o>2<%EV3-J5zQOC0s%y=?KlS}XFj0k-#Z%uq74 zn7H_0fIA^@))|s}Acf!Fz#W|?zJN*o-20NqXc*pp0 z;sIAb@qY?RW_rMy+<5}M4S+N_l$BOWN-Q7OBIs^pWcCcgq|qg8QYZ|~7w%3Dn(%~3 zEm;?wg|3rHbUD4Gz+ zdH}#r%D$Qa2_57U>z#gxGg|365c;ROieInkQwZMLdG~?7omTv|Ly>x ztv762dIw8`o;#daC@`6%m?9>moKIcpcO@`YzNTqrZ@b z&2yqpT9*7;`RjLQ8EFUkV<6YbW^vKiEn?44&6!o3y4_v5C0OTBYeoK7-@Cr8K91=K z1|p!8z_bhnfNLN47RA~bl}L+@k{dikMFG|P+LZUyDM6>S@x5=+8^V!DcWR}G^b#bl z2%o@WTqN-2S>qQGPoSSSh)csVef#9SMSf{}`~1U?+ODkday_=Gw8xYtMp<;-q#kM? z5x0XsUdCH5_ranUE!MenUX6LuD=QL$QXM;P{GTQh_tFZQRSn* zws>tt3JCg6jdg%shPWG<pz*)cSj9(A6x zR3A%Fad6vii)LV4+*B$uxP7Rr97uVc`o8IRg%bd7Es#cAC2762)vj~xi?|hxz*j0U z0fShtEXBF%jAmJ}S?4+>Pi;=3n+Dlh08;||QsDXQ!Bvej!MylM)x}~fXSF4K4{T|@ z$Y6Nz#wm!z_zD%n{CWDYQnBL1Y`S=s{(1d2$-Jm}7p3_5s$J8f(#GZ9@Tyz=_Wz?( z&J5V5_#c9UFBW6KVt^>$`cL)%aATR+_hbL#KHdO>h7c_k96j>j28@~SkUi|c_cbs_ zD1;j`lTcALsW(SDew9#^rnuNl68r|=NGfia9pFHIneKr2l~SCeu=Uc|*yJE9bff8=N1@|y}>a(&)YVVOfNgl{TnNQ8{qw}WGhMy_Iu?sCS(OJ9n`Aa@ty0#fsNi zrp>cP-R^=#t91+pykGzHd1xf7Ewk(vBLn;V0@LmJvvC9Q^ZeB7qP-#U38hlEqhNyC zqRD}#^;YJyKuSxw(n1++>@4?9MSXZ5rA^j)1VSC{&F7CR{LfUy0uajhA8M7Y_{(Cw zfWl_xpN^gdFzh;4kP;uHL-x$_*J`$_LPvnxLf{Hxy@H%J;<+Na00XztrTEekWPz~K zEVnWf^B7w%rWF#BJ*8Hkac9JENqPsC4NfuZ&rb{lsk%Rv2SROxL6>l$%a7b#Yta6N zmNEVDzAvB6+$LKmIHZjWjFav|$Y-hgkg>IbFT_RLH&mep7-aK!Hwg^~)@*7q z=csn_RNG_*y+Dh{3~jht-X&F$^R`#k`4T%R4^m!N#ife#qJ2GlX|n^_c^e9XeFW}? zxy?3mr$su=9>F>G!>TLl@nVH>6;cthG1oR__5o|>tkStk<{0|5N(rkwqF5kIHa!aM~ zJw>5C)|G~eJ@>MZ{osq=((?US>1)q#7ta^aKpg=!rn=diVfTn6D^N!^TDZto^mir= z=pM`ZnsBuS9JoM=0|8OfsXMlB7lNQK`--eRzToK+JrKp}^ylPQ>V7}*kuE1){ZK+w zhrbesB#(@gv5MvERdph9Yl}+0Pse~4!?ZO7>xnBBa*%)3l*-HONT>CXn>5G2HbmMs z7!(}(aT9To7o7)RHC|?E8Na(nf!0>P3;H>NvQ=2;)WkvNo=b!>sD*0(+G>pN-s!Xi z{6NTHh~oHF(JK~(E=2)#>li*;1eXS_t@Y|nD%p^TSBXXU?Y9$x{JCCLe$3ZC+SGtZ z+WY)ohUjffnG5P!K|f>#Q2Yrz--3XL(sM~%d0w|KvQM|SDRWf(n~tQTAP=NW+`{0{ zSzd%&Dpz008XMQDDS zAppkwo}kM`lKiE(w`MPGSx|Ps&uuMS9_+cOO#ksf2`9tJMK zs;SdYy)*N!4r_*DLspYQ`6hE;;rTAzC;fwrY-dVs&`BFh+xxTZN!7l@`PgUv4^uDt z5haJ7fBhD~oyN?%9@7C6zy~diBR54%xJFhU4?|U2Zf6u9gn$??6bq9r@a0;F$M0qt zG(V)xWoeQZ=o43K%lv`L&1kMp)8;NWAWU*x^u`{#p2!unSWI_w=4O8-Of*@UPfXQb zESZFss)fojpn9Wd1so`KfN^mZi1aDwU<)Rze*)+(y$jH=IiNJdaRq@!Zu=S}H(l+e zJT~BULsDCtt2(z$y)EIfHg1eBj3qApa8TW%3l7+OmcHd9#xwISgAbkxKHMDmqr+UX z0GDw87YG68Uh~1R_z)$$6KOmt?Ps-_=n$F>dP<&Ak_B<@>n1qxigMQ$!z@bd zZ$+O1nXE|gfc$Du9m<)U-MZY!D#WCr@yowm{XJ$mMMKxGE78WDvXjQ$vbr5%xr^mB zM$OYfIppUuN6+)OQm9sVw}%$qTfIF7Qy-d7$B_;F4TI9?_Lv=lRKz=z=C%A5u&B_b zV=}{6We_-+K2{FHz{mVv6xLP#Sexol5SehQ}*>P=au!A&~~lwN5t$$C>Tth9oNScu*I!+`JiD| z$=y>f3Zc|b?w-@(%c0dwe;qtn{QRS+IN2m8z5oo*9svdH-xK%032hNd6Xt8m$RGJ~ z4#9TS##g;Rr9Jnx>~fA+PFuvq74zz$$pr5o3RP}vEN_f0r_A$HRvT_Vdcp~c{%Je z*ElF4##;?6fgGC$(mgW3s8e?dyF6oVfmIc7-U4@Cd@GAIlVu4SV>zn*LOBM@ZDrpYaU@8WCuZ9{l)YxP2?f`w&i+I!`vr^ zImCX<1FG(g-zwc=Vqd6(!yh-`T}_)1Vu`4`1-5z?0Z^OPpvcp2&|D%h=HW;OqE@ybec@i#$F9!@V++;{~?gRS79UGeVn}=-0kH+77ozFbgS=ckrEWV z;E7H(ZT$49(0&E8uYzYirmxU+I<9?T)AAbN$rPL5p$QH zkq6#%riS4n;!cj?cC|{ zn9-?}XrW|OImRuc*hC+^;Uncp>{K3=>zH%e3v~4+XFoM)!c#rHm5xkjS$UYxeT156 zMr*S^snS^UR^3D2`qaYh2+V1wd-mYk{jq5_u6*eHGNcxc=&F5;XNy)nf1ks`w60#v z82QVh?0h_-1f~6Z)+<+Lfl*Ox8+cdw4$ehR)R|n`C0L3n^U@kV!{|zjNI6#S&O{Q5 zJoqkXiuy2=-P10^Z*;6c)wQLBWCNOdB}7S_nO@RkY-F6fXYXL~o^WyE!D65v)6}Zb z&%ow|Z)aGI+7Vd1q&81d0TJ|@=2kD*xGaW&H88}k{yb2bgpKt2K1ftxaJo#gvOj;- z;OON53+(l$$LB)A^5iH=8fc~%V#%wX`o=k>eYZE{5fnMu**X#59ED-06YIA(tMbPN zTM}xQYbc9}M8{(OWprZHLQuV;gYfk^wsrA%yNZAoMLT4B{zPY6>KqOJq2i#=Tw#l1 z=+n+nYD1CRuxf&SL`S|wECSB~CS~JLKJ5BE&D6(%jg!^fnM0+>>TIx}i?hT63JEw6 zifVp+h)s^HSUS^-2$l5O?F?%^GV+X)8@c)ezF#_ZT|DO)H-_J)E@eioynJpDG3y|QR02j#L z^L;>qV?K}X0xY2*5AoJ{jEJ(Wp->6Jkroj7sY+Ze;OUlCD4Bm_@A<*hY?0t&0A3az z9k0BB{Xs~o3T8D(lMYa{t4nfq(Y4ubO757PI7_?qsIw7FjBkk2Ika3I+B5wPx1*{I ztwFQ1blI(Fc<04hFNY~cLZFtw6oW*5S|b{kHMl=-nIwR)+qClngDJs)q>%jvVT4I< zw1?(uhmO!sfrrLl`@L4H;bGxxY-FLxbbx49J3`hx{3g%uVcx{;@KCOJ!;Va1msIoQ z-Vs!<*0Y!{eVWD7DPp{IhXY*j@U-?|^q$sN(yt84d=ZHoe!tGs>+ouUXRF>rw9lHs zPFyN868laXKB|+PXff@;VD^uMc&uACdV8c&9g`rMU+kKJJ(!j}gRwa<^F_oEE%$Y$ zS|sqKsTZX}ez_=aFyNO9b#3T*f}}eY&m{&VAAA3TTu$HTIV+R;V%uE@;%QhXa-UAh zH~sr@_*>@809G{*TZWq?WEX78r<=gDBoSscPkV@PP}Z!f6ka_S^vX|Zt81|}yoY0w z+;7s>^_FyXW>C)w5~Dr3*7FcITq|(OILFd%cckPCs*v|68I}Ft4~{t0SCR{BTi7g& zjc9_6_4V!Unn%CWO!up2oHXf}cGPKmw674f2jy#S>B4%BFmqq9U#2HOL)1?QL>tOm zL&V6v_08E_zyB6`G|EtUl4Or~D`xB-qU}gMZtifwvMFL{UA5N524h87EI6jrIna)- zG5k3#g<#iQGrT=M(_D!e!m^$sR2x3`d8(t_PKe5sqQiPPqpdM_?#7!{*3`S0*s`RV zB0?M5H8$j|t}EganssAOzQePbNPxU^MGFYuPg|Nd3pwh^TitLSw3utt4r*%NJK#{0>gWBxno)7pL5DM zt|=r3jWox=iXEVukv=ROVyWcbVqWwMq{~i&%T?q{xHo+<1Gz zBZI{9v8lF13D7|E1_OWn{emqF@O%7M@vS+gHYWqO^$?g2-%9y&h zDE6nK`TQJfrQ@33Nk_r%XL0^(6HY>slZ?oyJv&fivX41d69+RuFp2y7!|MGXD0fKV?+vQg+-1tBkW}pQ8*o0 zL>{W?lHW>Y7i+(3TqD(&y+l2${fwJ<*2Z9dyk?IBU#FQcZ zO@83uO&Me5yfG6S0>@DCeOFB-i?_|23&~49a7{$=0c6}Cr_D0D2nxD)2J(Ad!tJY@ zr_qDLU}JABKrPq(l#D7irh{eFZ&Eo-Mp|&C&v!3jdk(3lNJM;RY{Wk}>MpjPSf6&6 zib>)J!wJYR*^j=b8Z(GM70e-{TTD2q(%!_D7+bmnsq&mk87uKF2t*jcy%q7~R8@WEZFR*gx-bPkP4^`1!5-6Q1q z=oTOlT|rS0ShX#Ig2k_LB<$3&)ptOHs|1i8L6OD|S6}dQ%ZC(l+!w76=yX(6?yElP z2ggo4^B%QM!M3tQwqi$5CPTY-o<;)Wn^68JBBziupM4U{?BcG+pS%1nJ6p#46aPkfzN>_7 z)BWgf*hmS6?wDJxv1kAOSk-|rLp*o$E#`vW6|vmM-{>WCFhgc`vU!SWY-n6f>32(_ zlIhVwX5>P}8{!Yp=FRB!%OuGyi*VU{$N-vs^ zDQpMjm>EvFw>Y?0`yX4c_3a105+3hy6pG)d4FCmSt#*+*TITOJ4|6_kS36cx>xFMr zZHw1>Z}&J@v3eaewQAJ<1kX(IUPJDT8OX+U^N3cIVdbgn8+C=)MIg_Ir$a>tNxyo* z)sUHt^yz1&>L{Vo3@SBLUMgL^(w{_lWhYq_ntetZ-%Wmle)0V*y;3y^WJUO75>nrA zlVIc$`=Bp{G|V!{yVtK|Ue&R6;~vy5178i32v_v+pdUnL1M2jv?5$D^Yu3y}%4A61 z8w=gOVWc$~_|Q~C^Va??f#txhE+SShMl{6Lkh_d-j4&hDhOWrFuz7Ct#Y=X6^%RKG z;oE|f#;1@aQ`Z&bF8@RR3;9ei|DRJ%aQEs4e!#_6_0L}RKPz}(J$|3}PtTV(vQMxy zG-Pi2rE$RSP=m3(!bjjVo!e4^?AjojR^MD|tXCeDUW$?~SJxTs31ME4( zGM3u~f-KRP?^)TDQPFYZdp|-BrX$$Gns~=k zrvnPWf-*38zwA*pr9R9R4kw+Uk1=_$O5m#E9Yh9O$GZ+*IGbpF5=?~;JwJLE`b?tG z4sx4N;BB&U7J0cn%)8o;!o9SSMp<{2^O)DIzepA;Vc% ztw=3< zWisPXXTa#*ZG7h*myLt@1Vs4VY8ytPqoG+%dDNl#Q{s$E3Cc0ot$FVGgp zz<|&L1k*%S41bk>LBc)@h)1w3)z~%7>1IZ|mXl9EqooHT>+%S@*>4v8Lg<5xufh@3 z6uV7rNZh9}oB(ZuPw6Wesb~V@)3s>z@uF05%bDV(*q=&MctPJG*_Dm0Vjz@q&O?EU zyvsA;@_2kTzJQfzTGSCE<05%*?T|Jy$C{Pll%+CU0W0?S?mWvQA}ri1bI4ct$vfpk z`}9XBt2NqkcLTa&-2Y(b41dYl0&L@LumJWgUAt_V!xbTY#KR2hxB?UfJ7B@0HMDy{ zPoVB(JN^{-?0d4g>SqW24L(4SBAUIJP7YwmF)77lA|GJAB}!-s^w>L<5I)mqa6@fh za>RYX?mVg=85u7p(&jyEhU5uC3UY!QQBM4MnSnd5+;%{t0&iL>8nf?nzhcR5yu*o@ z6yX*>zAOc-FnHT=ng+PH&tit}S_I*(HME61`YZtuT@IWvo6D8O1k~5dWfaYZU)mo1 zi8Hw*xaA-U3%QJ41!UPal~A7B0z9deWRbn9^4S*xgOkpnP-ixpuEh!ppS8iFbM!Ce zUrD~+*Rf7D-;^SQj9y~dw}-VJts#X|H_Wqsh0_i~$%?EA$uW5cg_^A!%W#1^E%q3~ zV$kmwbcSca&tu8YZ`U)A!+H|E)(77JDLC52Zmx8#S=nC(HOK2FL2hvutwI_=?nab+ zyQO*RAZ6wTO1=y7;^J0I;xOZ6>BuXR9s9CqgGC?T8JgBa$E5{CHz&_a$RekA)^~x`&XN-cU?wC z2gbNPl2VPZl3o;O!D4HQh1D4*_6nk863!sSI~?3S{bWelz5gC#Y%Q?mnaN&A!%oDT z6K-ZbR;{LA#Wv1M`c`ssF|@BpLM*|>Cho90>WD#SdcPi*V1w$phxk^F+NKD;pk8sN z$NNZkx5o7yDr(k|C;6I4gV!Lg=J&X-m@<+M8t{XHLq=lu>}$$m#Z8H~nqGU%J%bfc##%nYbP?+Xgb1eB+_4aEU!UPW*{mLJ$gul4vP)*CuN`y{Pe zT4y%vf{$$PjvP1(>1_`jAGqY7QO`%P@Z(l*(hn2qb?h^s@ya8_~IIBO+jJCC3TLZXZpat=o$@x?ECjMvQQ zG5pvDkVILlVa0eLBkQGfcT3S8Hwx>^eDfU{u1z|g5Bu*!oU!f)Pw+i+K1)nY6NJb8 z3U7q7UFV!bF29>yU6Cir%yssjS)M2+o5BpL{C*7%Lk}Z+U~4UyQ}!Yt&QHltXwsgF z<$dRTyc23{N(HiSaCDcAac9t|0K!mg&|ZlSFJiC7lqjm((va^rZ+F7f5%W@*>j{X> zc%%r^AbcB{%=hN4!>>sGb?({d>^A!>%vov^xE-l#*=*az1or~ zOx?2Oi!@co;GCGU`4Y#|EIx_#FL~PSyGp{}^etyO>gg0JcavB|BggR7nD!h&u4pIq zKc!rB_{yJTFH|+f3VX}T5Gmq^6SuQg5A*qZOiYk0$T z$h@mhm&Ba@(~ z>)z}G>%Z}qCRaX<5kMf;|Kl0}nA0+y&;KRJfDW_AZuNs!os!N``Cpiy|Kl$-t zYJOhFOKJW6XQp?BBVqDyF(@xLWX1VNfBW)-Anmm5e6h-e-6>3Irm+^LD+wPcbn~02 zuP~m;lD-1s8Xc(Ks_Do_z(3SRCiSQA2oFfbYd$?s^-Kb;?vo&jtdXmD@s(uhuI7LS zXXH_uV2$rbEx-+mB-4Ld5p2RG=is{>}49(+H)f@^{>6;(FL!Db6UL8)XdC#rHn z3eWDQCXa11)uM$yOI>TlUV2KNQWISd*0N~I@Hy@HZud6GmXZ_zo$M8vN+o^P8GbIj zLM8%QBwvJu#NB$YnUn3zWL;UuRsxX=Hzd7zxHI=v_T(j@`~KxlM4Il@>{XUdIBP>8 z`p2%MZREUvxq1Rbgh5X!n&&bsRw(W_`*F=1p42{fLfdIm#m&Z@L_#qBsp+SW?#7qF z@G7=Z1}4n=FG3*U@|Ua>&XS-|z6*ZSEIm<|-@k>Dqg$MS-eaj!lO}ci2I<%GEMc(i zMF6`9hAi$d^b;$?XLEsC(8dKTC2<$0I5UDdHsgC#b8JOxVp!=kEQoR8l-ezn#hPa8 ztO0K>531g)$AVL|Xn`v)X$}!VfQ*;%tyT^fv$%q(-F&8xhGe^Eik$q2r;k3gE!}Lv zhx`(yn^6dodUFF!R>_3xP~mr4cG3U=z>L5UA2i$&`<2ohu_OH2E20-?AxqLkx>VjF z_M}Ugny#buUB4)HmAc#-^c#S1{>0)|u?Zw(I@6|T-k`cYM1J#T$`;G;G{^Mq!HhPLW6BQ=<1?DGDU z*VgHB8F@Z1p!46c&aa9n@dRiQ{@FqU7%MR|E5-7gWAVcaS#S|p>Bl{+(BHx6Z|Wwp zi_pN=OQYuT@hwgVKMM)ItVAaM0Pc0LJ zlgzk5?TzS^R;@s^boZpQ9&*9pG1k;mPk6ky-J9&n?pWJa?L|7f8$w~Lpsp}Qocpx( zm2T*|0)NVqc?iv*l?@I#eF)N;M|ubQL6PM%Y&FAQ^{p;v1i_eZ$BAZkLLXeH zTSriO2Z2@2OwB+0-s9|@D6p{3F=@!kzT z#lxFy=8lG5&MEeBUC&*smnbol%`F65THw!-=2460`E>hA2b~j!^co{m2Yn09`DoP2 zcnjvWP;;0<8G#CRhQsa25jRG&2o2;zrz~~6HQfTc-o-ANHRBU=Ta{;)I;PCWL7KSI z;r2L@)u_`|MX6#MB8Jl(aa;gI!(Hq)a- zj_y#WonrOY(@T#(ohlGwNm@ezk&*HrAqv1|5^ug;Q0%WcL*~84<0Cv|* zf;$k{OF0hCWhv8P!sqV-e23~;pNQT>(cM^l=%Z%o(1UbH zr&~Y-88c;_j)z@$ttMoSLsU)GqNhT^=-0BEbFh>sVm^G4n7_RvePPHfjiaNgC@saa zKVu7JC;LIV&PwF2|9X4+SckKPr@wa<$$nPP>%hhnJ!w>e+nFKQ-n1U>MyPxza@iT~13=M%4=dCN$uI_ERhPJJfG!TPo3A7TJT0$t>> z6K6Mx=9o{qwvWAw8#h8YfyIj$PMsC^JJ=tlzlj-+SMfp9abS_TO6ySD^ZE8@ycV)W z#=jL8yRU2!g%J$Y0-q)n=^yXu(=FKyxz~da+YCf3Rgpr=5Lv&@~O)JYFeG&da$rttZ$` zB@P~XVZG;NFDl0$v)vDz7@R*u%K?Zuv#9S<-^i_{z0_=e}y3H|6Kf$&aJP;_%|8} z*b}1nn*Do319^41rl*}#EtWuHNJShG5*Pt*CAp24(-7D%P1g*G`ixgzi9|ABR*>E7 z0l&oCcZ!H;cL>!oaen5#KT+WU*6$biJ|4x|m*%E6W-$@u)6%{%;{R!tqVdpm4xXaB zFvK}}41r#8{s_EvNngvfrl_J7Y{f{N>2i1y6!Vz2-D<#8=bRf*+X(c3vGMvIx5*%mW1SWFf(Gc#CB7BfpV<=fwV^PW2TbVW$0{A$4XHNj6pums7Z4+U3t zjD^zJ;S_U2IoSnz*<)qE^Wy-7dml44`%8&`3Cfn((hFUId|V2eE}r)`+3(vB2&Ajp z&&zvcW4!V&?&PBi_~!G6G$5mYq%^x!V$A*3X;r*em5nX@Etxrg zMP}Q8_zL%3Q{eG-pE}85F%#wDTfao&>ED!QJ(L$R%uEkX_*Xt9kmQY|f;}_LcJFx^ zYvaX20Vy`FBFd#}hy+$V4}tD*8w8+*{oV@Hsb-e)>+wa3xhc|)AX8+Xxf>UZN|zj+ zVG!k<PX+R zAc{MybH>N|J1#8_t((xc1FC*3d~<7m-KsaQq{PShjg3Tek)rVCZqvr?%f?a8I;f1( z#;?KUCVZGIj}CACF5%T}qgq~`2OB8l#O4}g&Jq>ff?RIl;{^-3xzHig9Yc$PEK z_s^IDOX91GElozWnajS0&iv19G;ntcj^-~4!a{jx!&K zj%w|-03+_WnDR=2#}OI~fgiqCoPLfa)kkha1W@{Q@y$3B^We%Q z*~imLbNw6A&8MD%Q~DwdxZDLq8G|I*pU49rh`#J04TccF6Y-b)@OM>zbwfFQ68>TC zw$#@t>157{Tpl1^gGm+(?R<*OE$KE125WmFWfW3ur%(;I;Dfd zMZs{`!r~6neN)h!pBjAf8ZkZ8pBv_0mb-uBo2a$t!!{4uJ8e>CA3T;R#vN)8f8ga1ue$6Mw-g8a8U6qRpRX!4 zemJ?GYSSQVNXNs|-SxTi8GS{aQx#cye<|{+rK({~`xk;eyN55$;U9w6BwD@eyQm8LgWeDI9nD&-~UJ%&0`~oJn+uOBl`XDHCRSX z((%@HdSbCww4F#67k6^Q(-_%jHf+#nT$iPV?9$06{RyGrGQ@K!&HWpEu$%5NN5*~M z9mg}fH^#TSGMEAfu0$7$aJ>DfN$cDMWceEwQCyrC?DOe2g*^t4V7Vh= z&_{~;V;0C7IL=JeT$@X6z2EO4djZoOh=>rpYv#k43xoLj%q1q&N8$@Q-FR0d8W0&& z%6n0}2sXNv$D6O`B09*-yHX?bKL|x;0w$W?3!2wAHJ1TyQ-I$04{=ssu$guOn6XCu z(>MnrgWO#Ei5>D_!YD&#dj@iB%F<-8{a?UBR`F*vG%SrL=q^Em+a&VZPt&&W-6_6k z6K})82SQ?CeATfXKL>4t2cs1E%rda?UguSRQwxB6jL;=5M5J7$4NXM|9_FaoN!C?8 zTB>vwD0rkdGC0Jz5G)~Cyzjz5X>Ix*rdjivp4rHCxbF|@#b?ibh=LM#_N~>%)Fs0D zG9o;6-z@c0G4&Hgd!w^yrKO}#{uHyQ;k56kV_Em=fj#S6L6ReH1j1xTBQoiotC^eF zmdq4%A~LeYZ{D*4C@ANu0`j0Ftutd0D46U>7sQOWo>-u+E{x)?7D{iNK7t&RM4T5V z`m8x=eAKA~>~gkjvPk8W&?^J)S@WtOkG$E}OhtK>%GHEcyxIL;_Jv$bp{+(~vOfui zjSvp%WjPe-W3DlYzi<2W2cu&#!+}!0hd+<+aYAjy4x!(3MU)MU>eF|Aa?!Jxd>Y%y zIgm-~DwB|>&!R&*J+~-ySw_8E`41o+vURBaaD5hqju zghQOZj(tWGb#i&;yxmZI*)Ndd+O~K@&)C1X6@2%r05Dfe116-D(BKE+7q`2kE!J*7 zzE>+Byg>GW;Xv-6YMh-@pNs7*sSPRcGe#(~Wxg;vAz`@7!KcfKEhQW|Z2fLAqL7u+ z0_OhBUph#YD7z-7oWH#D&Md|(NUz%qx}~IHdjv@HdA-VH2C@~2R7N`Ife-@UXSI0` zU7M_$jB2X(r+UBP9^8Sul)E;@W;TV=4F&ej%~W($zZ_Y--c9xGt5-z%1H9D4{iUtb z1?uiScNs{Mn$|UNgjP#0u@Kid_%(}h?6ms^xU;MK-76xHV*W1Bqp2>4_)fF#)zz32 zasAQ`sP{`xJ~puh9mKL0v`L4vr@P;N3s;WIU*%uYc5Ppc@%05hq_`D2xVweG=kV`J z?XO=t%Rsyw95^XLh{Hbf!B4%SF%fJc!%GfG&U&o0L`%GcrKf;^S!kr22&rsJG2PDV zDI!4z6;D5+ZpI-sV#kpK;rFVbQEe0CN5SviM42y6hy3E(3!>EYKCqj?5=QhDm6f;NYEBJ60yoVS!C-7rG_fQ6szl2N^shOS z{D+bX@jCBbsM(G}zJxxKO5?mIWk~|xGO@+J;@PE~wMBYz-*!J5-W}l)Dk03FSRL-MU_d-3&-DnuZ{Rqf>b42rP(4eD>M}@?QbbzXJ+NIE9saU*-%0C-{Kd@o0S7fhAq3~|%?lPsilKf=wCUWDv@U5c7m(6~3#+l7> z7w8PNROpX!Yeec2sG&!uLP@*3jWdgWp^=G~IJ@J!UjZP?~9ZCKEl zRdmf7sc*?jvIpZ%pw!#MM7gGUxIgh5%fV?j2qx$?YLZnRpKyz?VSM&R+Jz_&z8=7> ziQ?w>dm`}TfqM8}E#xVbzJP?*94;^QaGXhlg>|5e^xz zUuSG+kE&ziip7*>Y^XnKwfl>6n|e}kJCWvO^ioc6V~i`8PuOOy1y}TPYbs+S2zzO^ zo*;@4<&~oUf;h>3w-t0~MID)lmD|>fcw<03<=pW}M6L^UhPw zNsk+MGytz>(T@1RxQdPiVbOE`Bv5&hCv1Z9%NhSbm6p__8z%OrO5M$Sqt3W9u?Jn` zAT>UPw>nIdxAjWb0`HBE<}~RG$qZZgHi_rquYVxkab7=g1OBJv9hg!5H}#{aygQ*d z@F=PQH}b!LRiHpN^S?w+#6T!t$zX$T>2fdeU{cW6975Fa>v z-4$`{K702yHPS27R1n!^Oilo5S{E3r5K8w)D^^0A5fe(_jaq;S5%3=bXy3}o_Aj9p zFc_4r7$6o57Yc7+Cbr+T7S`)xA1Ay`?A}16<^zuY0Y97kx zeUkvaBbMAn2PvOz^J$5IU44jU ziMSyYpMdXhntxjT>|FXBz}7<7U$H%?%P9;))zDB(vKH1X_rPn(Y*gj;D?D7K6z3}1 zfo&-s^@;e}@A=-;{ZDOT&PGQzf-9Z8If$=7(sh{n6uBT$R!nB)7pw%1`fOy7GKSjn zm-`c&jrq#6u(q&Ob$>VkzLX{EjEnPg)Jfgmmc{JNVtp`Ka#uMRu?Sgh6%8rMIw#5k zHl=18xwOyzYr;yOd6@kz+nI{?d39cjE`Lm22(2xx4vaDtBHqqa5{nC4;NrOP2dz$c z?U zKW$r<|F-7jfKl_01nz;Se@IopVH0Ln;IJ%?`DISlwkUsQerDJA2*UuZ%zP+w1A>kB z0))tCJM$Mi41+*q0HB`y=C9%pn|&2-gg<1IAl_?%KM)lc36L>Ei8V7oF%aGn#eMqR zxtJ>%k9gDoO>XfD9tokv9sGD?fY}EUAOaIYr0-(>iibmtXJ628L5dXw&*p(eghvC)t3aKHOOe|Jo*lgqZBc1M6i}>U#OIe9(6Oskr02xz6D{ zD(sBlzK9xm%9#vg$%5Z_T~8y|V;`{(+iu>NQEV>sDebqjbq-I@c+K9?)NOWeAwP4y zYe4%zznr;Cwr|0U(a0d^9aMrMmEpF_fUxR^?ud>`Mj9rIJI*+y|cf+GrVVzr0yUbMaX^XEgB`2;X`a-24gZ z?-9>dSAeD3hi^(?6lQf{~S+@wrkzvND3s_55s-8O02)&662_%5{)J3#_Fmpr=)SECz z4J3e=fwk@VS)KT(t+e4k9()LqdF+hO1^+36{1r9>4mJ^k-UCE;UI74o-zg^5&T(iq z$mYkN&+kiq-BW&1qi=q(AjC14)p^RVg_G_cl zIOkYK!#84R#=f0vPWcFl9$i`t%EpFp`|pFY4qiBT@K@H8N}Me#>2+(=p#5gaTDxDZ zvXYD9Y@HNIOz0Ta3WI7#x$VcxATvNQc>H$A_k{fZh;TxX82Zgfpy__9GyR8OwhsIE>&COC%Mg6^Ghg@zQa7Q;I2QmUxZ8K+3fTVN3cxpdyXrA=Y4T~ z6&83o9;35r)cZvfty#tQ_$!Cg#5~5tw`-CGM0*H0_rziOcKyccSlzM8_+kt(O^w=4 z*A=<>ZP^w|K0k)~J{$0fX8^>P(7Fmk;oTz)&1c`_**Jzpj3SoOBcODCYDpY5Jp}w`#?wYv{|XhpxaY(&s(o?ne~7 zymT&sPX=#Hssb<2qmQD<2%RVzA)}RMxsigyA2XFG2%7S#|9oYjY&Fn1s1~kQ2mxvf zuqpx(au3??$}PjSy3F4p3}g9(&x3I{dk?|Ct^X2 zgSJ~Xhg9(BzEQac=q2bO_$4Z~X#S>0yv!W!nbY`jGKXEBK}q#+&@GFW)9}s$L3_|| z-EVUBVC|`JYd*6@7Zonk9z<=Sgii_Z>e1yAf|aoTQI(U{Ag4v-2KZE^TwgJTSAvyG zGj0Q9g?IeITlU`hE85iJvvOP#nq*ZBvucx(z!w`nqh|Q}72l(C41Ex)C@F@0&jyB) zqklpPGnYO)%UL2&N{1OG)X!!jx;F2gIZ^S++*^t`m%{2O=y6@IvB^l}(}R>Zn@mp& zcHOE#L<}XPYD?N(oywP!eksX>StsAfZSANp>3$RrNFcTc*R9k^+I3j>qkkG+(I0}F zR$b8D%fe|QtxC{Tdr|%SPo&k#j407VHB~{K^uAvFGxZVSjJyIhAv5XF~$DLjW#zxW> zodWeI+TWsYZJ0zC^|SxD@b~!T5Xn+lba$3cnq`+J>0_283J|_;Wc8Y!rOP=zs9NKp zVAY;Loh)=M*fkjSJ}0Twx^o$*+pQ9T*?0>3NU3xYV~wH%4O#PIPfF& z@!wefdB$fmOMT*qQvMaDgVNxKu+jT{WK4e!C;cU0IP!NJ+BnSdu*lM#Dy}=Kn=4W> z(tpU;9p0y30^LqN1@r7@VjK^q<2vKFk5~0|fRkDI>qbsY;5qIJG$~rALts0|N3)yC zN7G*(d<{E2cj21uS%)Ca*7A}UHUK*Vhq`%wi1BnwQ;5qXZoSFJep9nM-?iT$=onh) zh}nF%lk#%XwY?<}EE(uS-o9%t=;;ITFwRcwxES01)28OGmOWblx-ncGx4zT%YX7S5 zF3{_J`(X_7WA+H_D6ljCuR*hqvLnD(=l_Z9Nb3k9d@TepGNAmA66SBej`c5dZ&wv% z=#cxolUAgkKR|k62vSKraHFN7K85TZt|}3H0v1+$`A@(re(A5-P^pw@bQsc=33Z5` z2v!159dSvYFAJ8Kvd|NJLk_c+e;h^fog}X#&OB~TUa~>YPbbe$0hVHgEM)l|#{H)2 zIyGI69iyU!9iT=daOTyQoFc}#3t3wK_+lP|f?5r?Xn;wTjNN|7hdcBe zQ@!xXFq1<%xvtQ2(n#r)fmLWyz9M}V=E@TLS!IZZcbHvB>spO`$;|5y%#4PM^z)-$ z6?B^g;+9%@>yd61VyEI|a7qIM;-3N}e=tlTn0O|o#4?SWzz}hZi7Roo-akiWxJx^$ zOAjDg+7MoLd7deG^-QAwjcqc8<{1GXARf9}7 zy_CQ84(s3Q(#ksPizVhlB}{DP96<4wX}VwV*PA~alEDV z+0MJ8mxMJ!1G|dYFoDn`8#?wJJW@G-1zv*`gn3CBe9hKsE8>||( zXOAcr%Nk|MZ(q)fcKY9rd5(*^G&62MoV|JdHjgJU`Xv^Eb5Ifz2d(wsT_4FYxx>rUj@BEN8B3E9Mjkm_nztX;0PqA zV(px~)B44zFui|=Hl=*W0}*J0KC(mqbJ(EM1xP*_@oe$+$cD+`6x%xX|B=EjbMoA+pAR+Vp!FVNGPrx&L16_#KKTt16!+u+^%c4;*DgRI60JRHy7 zevWzFUs^z?r;%%Ik(dYFa*PN$#Q}AoEw(l94~XJ*dU*gv_Y;4}El`8G8iMGDA17jz z7Ot+Zv5+Jpx!x-63f`s@1vOVZ?b(QCoJ0l%dLA5HB-@0VvvK&Kx?z~->u zby%}2J@ofiodeR=hgojAMR2>lkP%IiR=m1c+Eb(&tIRoCY#wJO`Q9JcPuO*QYTF_a zejlcjK1NQUCJozvBl7U$n&rM8m?_-<16lkPFyuT-WLCgu1}ZO!1}nvS4h;%9nOIps z3kU~9G!O?=D&tBHHKNKVv)t1KBZf#rYZsACLMO50SDnTFL~oUhDqy^|zp2j73iekm zRSsi(LQeMcotm1u_>JpdCqzeMH4ec++)Y=82cvnmjCxa8bc=%8!c5fS^=bAXfk4W{ zmV2xAur@^qY-?g!#uXf7%=o;R1$587Ymo)y8-ibr7Uv}O!Y8Qq#=cBp+DiIOE97u4 z3zO*^iw6+Iexb4I%%HRL;3mF8-NJ0O8HZzqXbFoWBKryZBb6Gj2~)vP2t=p$+)69h zib(f_#TT^i&91O4zY6Xg4CJf$Z;jQhC~c`$#9*V^sVnt|$Tv7 zx3vokY~hc<$!J*D^s*j^M7UU|(O3j0AUW6EL`FxA$V0f?FDwL!RaA#ZW8Ez zdiYgs#f!vdZE3Af!*t3|4f-$}zNP!riyHL~KFn>%d-YQh8xRO4+8>TrkuiKo3?x=B zhBc!!)To_P@qxKTE8I&FuP(Jj7!e1D&YZ%m1*OI5#~0tEn_61MzwIIBoTBM^xbCi_ z=f7iTFPvZf#8mpD>0oVldR?$r90C`UOk9hLZLk2jS1I6X4nGeQ3N1VhE2tPk>IZ-H zJ}G9TWtoXd*{tZrmgWvrh4W(?QdN-?2Z$>C`N_%KBZKj5X8aS4{r%U1nAS(WZrkvw z{@(_u+&}p*5SRfmdc-OIx10Hf#FyY}>%_Z3TSvpB7 zm3Y}AY+85K-^PDcM{p4im@agb)agVwN7H}x3M&^Ij?cGfs3REJwByK(&|y1tYTVNZ z|2k%Y%Rsk(8#%+MA#mPYtc`HHAI~3j)N||{tp2w4l`!x&zs{Fq=LkbgJenfZ73Ig( zoy8D8&F8W*(P^si)+04>xsJBBHW2V0IyploLD!}+nZ%bWfz zYzV{JjSuOYnQDa~6A)yFzRe?asBKBI^ma14aDs=?j{Isn&L;CXd%W#kXn7U%fw^G% z{b%V=lZElBgFgb4L4S1G0^V>*VF8Vsohr=LtstG4n|+rK;x{z9ogeovI!R(X9LZPQ z?oJZ|m#8T_N$Gof=;J)YfYiMRBI1X^DNFsXTeHwttilzHV^KOZ+=CQmWLUuSz z@yp6hF%wA<4L1>j^csMzTTHWbam$N^*%#K$ap`UVOHzKjWZDu??{5m4o&-Gwj@F@c zT4`|(M(h_Xk}TSU+69TkvHW@&uW3ZM3+^Js*!Q1$;N|c`@T6acKsMdzwd&h%!$Ig5X?!&bu zPntj%pQpx!`uao_c=(40?T5M~n$cg@&O1)Mhr;T{#=(e-uE7zJKWLQ7np4TGSBYn! z5$D4tz*Q9zcN^g<7IdHe(GJhG8PpuVZB%eT|L{qZkYn~Y>uSWcrN6M;{_YhTlMD}1 zZ)8Tlc}I4s8SvtYCzhtxZ8-Np&%V35uB@Aw=>uZ$cIaM}6T{@?iz1SlTG^U@gl~LU zj^9ilFsUBR50ZnoC4lG0T06i!Ry|5-#GP=5wrSIdncJU&mwLZKxy4la9m_Ztihp3%qX?_V(J8&G~i4J5tT9P1?IN9JYQw$Wq(x zYQ---$lUdQ+QSRK)~*d^d#ufhT5e=)v#C=ffY-N#LO=zltBU7K)=E`}!$I-k*%hhq z>DlWC0K|E2r928)6W#q2J6V9BHp|&`En@FqBb$0q+z2una)?owG?1AZ=yG@RFOteN z64KJx7&P+Fzuv!ggREa<)BC;1_wQc0^Z6yrzo*nmqg8E-HVIDA1<|2sHej>5v8&23j(=F@6K1aXmq4 z*3c|QCiVC<@a3D~qNRSHGpXDLNn5PI6bjvd$QSFyPm`!N_c}hHS1c1l>rdRQ-CdQQ z^(V{ZxKOS;`$=z?{Lii6v~yi2Iuvc&N($eS(5#uB81OGs_B_!Y#3u^}*jN7WHv_b zV;O2qKhG1-nOwArEtuOSahcco`X%kadQEmw_W(|)o@Tv=D83>c{!lSp-x=qcw&}EF z=je|adNDCe0ZcqY{MWwQVzE?=1u$lT0iVXdVipj2VPOG^+WwE2)xpar5_mKl(O)Bv zed_-T(!(Q6L}Ah$wH`v!p28O)O&T_Amx~Fz$F8bv5W`E#l>XU^N*iZKDE(X6n}w;{ z`%wn?{Of>=;}bm*9f$vffon_1RfpdU^aF9P5>_+)qW}R;E~*&4?AsbMN}845d$@^z z4Mvm6=I%trI@hq~z?pCj3=&I4>Y!1rV-ZA&cZ*peq^o`Xum{wipsWkciNH4mqncw6 zIx>0In126CH!?DOR8r99v)|6-RJ#$9J4iM8;!L_NNF=sX$@a7~Ox12v~XeD?2TiYdD1UdjjsjKj8TOSsf1v!zoA!IGr* za+$_aGFPfSq^!r}u+s%%*C%Lx;RV#GFvJ8Oo*|;lYJxs4vm$N}uxUPN*-{XSQ1nE| zzYIMe_IrPG5Q1J@b6bbh*n>30EXZyp?^oKzYep^&SZBeQoFpgvX@okgnMu!kDgHXSODr5N_|mCb#-a95GB zIMza~1gUM%gQS;-c|p>(6q5ih(IN_K_)yItNWyot6LS0IxWH2Do;Q3b8iR%Jfl7>B1L-I>-aSx8)JY)DoAFYWLKraPxAh)goO2FJ#XS|VB8@m<68C>T=PNdL1T_%gquMo z$9cE0DME_vraveF@@~$&<@X=+wq(cpgb8?*lRsr1U`A+3S5WP9r1RqRNK1Vh)l8DC zxEJ7>6kmY3LjroBM5!pH;}XUL}ZgR8m1{0r!BajlvWRG^YB@QoChbG_$~cu zSy1U1K{ zynHATXATYV zBl9Sj2=d{3AKxh)z(LvnkTLcP{`mVoe*ACE{r}+OKqIgJ&V<(%>8g-{~T0M(XZS3?PxYASz%8~;+WbZ01IzD#K3sLM@d2W_PE~#kdX!z2et)m zhAm?X7MDJ)YpGo2Qmln?wk=-eibPZ>(P#-CeC=M|c`j~e$<-jUdpTLz8C33T*2%?ADUUd3;7Mo;sjn)f-hvX0cT8H~D(fmF(6`ng&ERFU$#m!OWF`tY| z(Tf0*xx0M@i~6_V!o~z#o{YL2WDeABrO_d!`17<(5H8sjM|<#8{+w}CaXAqmoH+UI zR88y>?w`ELnxv@aQ+<6A7N0#O=}(sP6Dc$wA|=}TkQ&~wFj6BsK(!^_2%>0Oy05{*c2Wp+)O4v!Cm)BH7Lu-wpjN`z))92klAy~%n|YP#k$c4jNqfm;wh@nk|y!2p%9 z=-A~k8r-2xIn(GL6H>>Yht_x$GY=s}AWv{vJFDI2QX?Q9udbty!~;+CzG zeceV_Ihv4GjBd&e4VlXGvA9({!TJ2%@A{#R9Tm6fyR%!rn-3HQsXLJ%U*Ka^{CDLD z6cqxh2+ViM0N;Gjmv*z$i6mz(35t?mXpr8(36ve29o#Mzj;NJSH6gwNf)SANkQNsP zlwU=8+(x%ZitJ~3Z_bAdPzQwDNw*WMHaa@Tc(;cCq&FD6pHkrPns!;E`W`!$pTRMSkFoe&ccpA*?*guZj0wRA`;gyj zj88XraY9-)r4TA8d&>#-o8|Fk-a@9(A-+1L4^?DX)ITyoos!drw_O&zuQgF9fgq=t3RXL}oXy;^wJm_=z@&$CP3+34+eu#!F4 zsA*e0IwGNwF?BpA4xc5*QK^OLw^!|i z{7BtKs2X40_f6j7$F}Q(y)dU|D#sGhRXbNV*xdUv6(&CaIPTYH-{PpqyaU|3k!1`y zOf_za6w#bbT(FvMuBiY<={|J-!vwegnkWBWe~qdHhT%W|)J18=$$UnOT+0WQL#2UA%9kQy4(gJgYZx+mPA zD&ttAZ{ReH40SN4y3|#L=A1Isx~qf=KLaMzaCBPAvj8Wyu(5azp-X>vfv={!iX5#_ zZA%yU{<5ue7{xQ#zYlsW(Xr2wqlYlqeqJ2)9JoZn{b?O>`dtQ|@-x1DX05&U;7pux zgqYcIQUS#}|EE?<8)E20T-u~meyCc7PYYZM>wj{t9$gtZp(BDAwcgO+Es($bd6D|9 z>Y^*ThNRNoWDmx(@Q1QEagyiGRjXkDVGvE z&Cty|*$8dj-tpH1bE5j)^|07K24|pGnppj2m~b`x?r5focBJc$Vll|hBj|7^ z2x>)KBRcvC&;%9JE1R7-dvAPyJjhy6G0N}-qDJ>&BKIQk4Jk$N8jFQ;K15ILj89iL z$M$V)!3r$jCiS)U3S+%2DzEfqrRT*&XJsxzQ|g?wV-pG>?~H7sq}$}TU8BfX+Ru%D z^0VWJYES-y5a)t+gfbdiBy5P=T5e1=~^{ua@{4Djx zA??t(JZ=n!&V`X5!|zsNd>^lV0N=Nkb^D5Vz>hG3S5ec;@G1A8@LuS2oYP z{|!M8*!lnOavYzF$U~~XaUW=A@vpiW7@+>9A;LhnRt%`E6x67rUU-<5sV{b09b)F) zMPE@)9e={de9ppm4>IM4bJY}?U}BO>O{o&=0ZnT%e-VCpE;*x{$?H^0VFil)RRdVY zyQ=3_c5Qi8+=I$$E^-UKgvPMWNrm)gPcYN9Ewtk2X2llEdv_q3!b|Jcrp{B{xcBG` z3W)z`THt&6%=$8pO2RGIPWcea?57g;Lg)gk`X;xkL=89O^_VQ* z`D6*YX>yF4MkG}9j1!(rK_+Qd;`d(@35EpD!HC=Ynf0E&n|~|miVUK)&VyI^tkQK# zTFIF~{{6w2Yv%(yqdMX~h!_}29{5%f+s?p)fQZAz1O5 zG7*^6d+gryHWsH&vJKpK?CaW+qFKh&pW=GvtK&9AfF5|3uyUGG0egt8DGQu^ldt2i zfq+wYfB4d}Cm6*`(c|vxX{aim!`7V~eXz)l`FZbwFHLRK1iOo%1=oLiPV6t*3 zs5+Q$ISf*NvUK4t^~qc8%g|^sr{d~Ff3AB>&AG?DBsdD{cTysC+V}Ser6Su2)meI> zeflby@sq%ek!*lWEajB+y2S3zlIc&~J~<0~okb3V-}INK(&6oaQJeIcWv(OnR*acN z8>=?bGd)JQ+Fb)LaELGTMGwDi@up0h>X4L3 z7;=nG&S`JE_jKs6@sX0HKc~j#cdVAuSHhScjLLlvO}t4r;r&Ikm`N)={-@GjARN`} z_g~*dAK9`%$}}@8u%!BbD_d4BqaxxnaJRetGq3%ZEen)L5(Y{n5e#f{sAH)q8Rbw% zUEPMGhG&+R4iKQpw(7vHLC4ET>34+SQ{nf4f{^EqLGPdGlhG}&GfQW z-3TOUe_m3~L5<*)-vMC5)6B-PDwvJph4xVE%k02{eswX9_S}@wSmXKL-BrTUUR6}w zQhnXzX=KITT~#%er~R?4-bUG%xFpPzVtQ5Oxk*23vy-BqUy?;U$XQJyjL2vlj{)tz z=l!Kk`wJCN6N?OV1*O}O(cqM!vQvB+%koeaakbfZW-tByyKOaXye7(%nwLV?>6sok zyl@Ldt?mbMWyV9H6A`#m$*=qCBjHd2Nh2vT=NpZc*AE7bDVE+2C)axMu=`8kwfDRZ$=-7%WMlOe7}yv|bM2(8Kc?3*ZwF1GeUz4b3ROrh$0V|)p#XIW3@xnMm;o1Dl@^l)eUIgxKE ziW@j<>_<)OYeSIW>%Q!_8E+#Ql**7|bn!#KN5Ug>@%<5F9$|R)n^2ukqo5sdCvKg7 z_lw{EEJ*yuzz@OL$n1@jDT7-r)VVJQvIgQAjgW`&n`Mx;f0WA@=4tK6g*49Semq|| zPM{#)9N4?XXmE#CAlyzu$&qec^^zy}mIN>C$xkFnht5XOt+~FTDFbN6l{2Zyizc5L zFVC9e^JSQhP7}aEHX2nygi&gJECwP24c~kmvDQI7Jj1PDDd>DTWORV@GseO7q2GJ* zRXj1Y*MO&5`Olr#gR%1iXvoC?VmBTHd&emue@E0g5Y%_^x4t)~;)2+zI)^Dc$5Ag2 z0ou(m(JeV<0AnoH$=geFs$E{l233Q<^LzPT19;&WQ1R-x2+R-6xfr0df%>MB9rm=@ z;0?UHzG_Z1FFzmg#mm#f6X1h%nxtccTmOHm=zwMptlaxEq-g(Y(^r1)R*VWigoB}2 z5+=iO#QYZa-Bb3s8NRsE*qky)N)pF44HPumrCQFfsjC|x@3y6f`VhTl-T!8Y;z0%o zUaf~W-gfu@T&Rz}qCtf0gL;0oz$RhKj(P48WGQE7)0i(z&d>=kOZaYC^~8VQX^?|_ zbh=v7cTb?({43EGv_YZEJQ$fHk&m9Bo}ql}ldy!9Tu(g*E@d;#T53{dFD|}YI{I|! zqxrsyQb{u)c)g&x#_wuGAxj#Z^S?&AtrbI;N8mDl{F8OF|6S%;EYRZ{IARA#k;HJ3 zvW>-b*@l5_`ZF9!yCSPYPHqVut?0Ic_eZ_-N1M3flY~5}3m*oln$d`$#``xxLBALR z)`OT8iHb0dUc~0^D>6E<3me8;Uni?31TKsEwp{%P9?;e7`X&6VpT&n5LK9|PZ?`{k zQBSF&b=*=MafGlL(p=O%^l%|fM&|X6I)7GxAs4nhU=8%f_JXS=xT=rFmYVt0-4@l= z(K|G5gqsA^--T(=ruq^^X*^?JzKidd02018VlD~vW9YF@?`fhr7 zJz+ek!+Aq`9Cp0Q71ZtSsfiD4n z5D)4Jm?Ge;jFw`0z&41id7=UVanjh9kiP;9mtvaWdH^`+yMGC?R*B&MrtifD>`eVP zSW4V)aB^ATouB^s1;D-+Guz+S5M%)esCuP#!|_s?nhpX20!cdvMe*n9XuQ{M&?rCv zY7!uWIOOFJlod|DD-Siz3q&n>8$A7w8icjzSN-nGFv18r#fwV`q7Of>=ja{#KQ}I! zIrZ6qU5vkf*TnAyAkG4ucsZy^ZP}nnQ_+)vpiwiC{UzeZn3QTikS+%byy~byGqJ-0 z#|PFeWPCa3dnwTaF#Ndu|HC}B-~@>F8?=$K@^cJU{gIg6G0$<}!R?#(0^zpG zy-orl9=ZsqaDGLCayL#i?s8g&o+P@TL4B_@!0GjQLfJGd4p=;5C)@Y9j)C&G8(JHc zt|K3V*n+>Dt(VpWZI=9b$X%Q1Z{Sg4ntg7-@&mv9#|Y^7W9zNg^nea}EQ>yt_h^o9 z&#UylK2=4WlLi6m!NKjD*>>O+v%32aYJ6?qP#tifM>sc5w?kkgtR_mm4PvY#*w8oq zf^x5!8iqyrR05U5B(+(XsG8gh*;FD(+f6-Yl`mb`PG1!VLH6~%);eO^dw(^EMy{n<&u+N90 zmpElV7MJFIi7VvUwc4QNmZ@-EyM^_$+kUZbt2dZCc2uEa?CW#F?@^%k{AUuP3UdA z?s;(LZ70_E$ZkwNuvKP5buvf@N8gSmfxucmkg+?jcj4g-s4qX4zNWvo?MHDu>s!1D zTrzmC`QUBFRY!5G!T>azes5lVXy_6Rey<$^9-gazh?T%1pPTt?fgdSQ2nBMh$#Om% z68bY~?ffYIqf4%SL6I-4CGy877r%Ln z`JW6bh{-bJ9N(k8iMkWXU2ewk-FQH&wP} zr_4hY<-v}WQhYtW!h_!!3%M+c_k+=kdDu zB}~}jF{2C(`CE#qh3L@*w>X&-lPF`sMz~oZZ!fBnxho<2AWn)MJIbpr5|nj{Z{yTT zeWscoebkRiiE&11^h;NmS~h`0`_WQ2O4$b%VLtCnT+zRUEyt6vSQ}Y( zTt>>ln$v4h`xz2Xs5!!f1wyt1zu8hd;px>&9=6B|$_D6#!#7W4)({b;3r4&ZxQnsEruA670cEa@VA-iV*vQdOp-{4Kl6WW`J!SahZ|2u6MLm zhEM&E=y3}Z(x?=)HKt;8hmj0!1vlnbq{Oe!7p}EXGmImk;mhFguVi(O5%lQ4WRzpv z#vRaNq<$ky>Z?J$Cxj0CuH&t2qd81qx}@1F-8UjV40;()=8PwbbpP% zdIZd9(1;LOMy?EfOZ@f#AA_?u5<3yD#r2K#IX0}{3;S3(ZpF=|r&79!S!J>@3pDmmXm*J)oUvPwom(juSS|KyV@n6}R)|eS?)B z2P%iI&ye2a^!VnybAlwt^M5h-j^TB+?b>L}#%9nT${jmWgzCY!Xd7|K0(NV|FI zabtu?qi#6_PzPSe*{Yznq2DZ|-VcM?7sde%EL= zDyg?}lthm{DHhP)-=;+q#rpv;K)-=&bVmGAe}rYw)m^ZAoAC9Wi7qu1a&m$~UFGz27ob1ytsuhw-xI1oV_FuD|5q_B<@39{5AZl^|3Ac|?CgJ|!o&=rqa+kQ3X2(t z@Jj7Vpv4JiOjCpc^+$vD+GxRFt6s=gu61FgezWZzn-nSTo9cAqQ-8dJ@&+|_b#T1D6wrXjq}F_QV{hjlS?XAS^1-mh z=MT^tCa<1A6>xc$z~%kUg@6tF-__|kX2f1%Aa_Tci^X&?M;VsmC9hnp-97cF%Ox1) zEj1sQoh(7FCqYQKWJ&=WxNtcwz5!h+K>j%KN5W9#|3X^;7|Di z48eZ4{ehgrfAKiL1vpY)A-$RlJmwK(Osq!q>iY)x0%fFunH~=~S`@5AZTc%XFe4IY z^S8LcQ>)Nwfa?c*1;c~}^AVq(B@0~mKHst2-+g&9$H?`O2zLhV!w1wMA1Ej&(89+- z01@Ev>T&Q{0I=8N6Td+c0RKk{_TO?F;8_1(*byN4|K)#2MhF9(`A~t2|0hRb{{-Z# zebJw|+!FYNy%%>a{sa(*Bl_R&0VGua4_WAem0{X%MIp|=O%td&4Jq0DOtN?t=L(fXg_K}UzDBnlc2Xfh95oZ=^^YTs6ap)X-q{0 zx`h^Dq)Lw?CNh=hg!LydrK9;k`m(P;i9^VE0rEZc!^5a8mVPpR#{xePHvvqBIPeH1 zpXrrU=#gscdu_+}WpI>UC%>N1WK5*%*C3t^zQteL9YGZUK@YD;?JIFDiqa^|1{(7y zc22(^qOI0LVm+tsXpqy?ocGC^is&XrTE%5WvIB^Tb~(*PN`-5dwr=!I2Tp{GKfNHu zGdyKPw;Y{nBq@O;)tjLd+U8eEza}n%>kEYF$t>fFFz+9;;!Bh6ERgdl0{A?TMZc{0 zT59uy7cv0W;?|E7U@tu33orL7?9KQf#StP{p$*4E+cZL95MyOL;GWI+cj3>Q)76Q# z;vNvP^63}EhO57%&9eN;b1K1BVR8-_FjuJNE0t{;i%U&(t|Qr5b-+b7b2I37)2wnK zmp&Jq7erbMYAZSNtvqCkwGD+ZR6d|IY)6v$#Rm%;xAuC66@ZlpMJY5{yO-l+V=tje z^1VI^s7Dax*r`}+7qC9A!>~lJ4ZDX z{MovVzo+}>sE?@`9gaO?QYObd=9*vps_c`3vy0E3jQRK&teNK#}AsxXTLeWA@>M4soEMRAUN&$T8)Cf*JC-#5bpzRQr~7+ z<8p|OumKK<*~QTp{(On`4qmVB!2XCA6sGA9fpw#hK>LnP_%-O`_;!c1AKDypviGk& z*Ws_~5I9V(`v!ep8S5#YpK)e|P9D`0za`OG;Xf$3pMU>!r&as)SZ{8U<(r8Y?g$aF zpHmtl_S~$zUqa)zIJ;?G5!+Ox>3#ny#+3y1o#GSO*8GF28fayC5Oc0O-yJsDl<*pY zEh5~!W&Gxj3Ho&ozoD3}4w(sJ)oe|eu{ecrYPRh5ut{CuoPzJdC9f@G19F1K+f!5U zebJZesp2QcVO*}gW?v|^C(__U1XEhiRyloM94DF-in3ymHu zxRRH{gg+bc!tvc&pOVxIAtu1{d5%btQgYvu&4w!pbBIj;GGjZ`H&Z|Pfl&Mn&&lDX zi}&qo#)H}VXco$olrb$mvGNE?5zd^<5+ubQ`bA#C)pWb>=o)E>li)svWdA2MSB9P` z_r0M{bMNaDwuczSX{EaLTdg3{$01yrj$eIO)}1ixX8CCfeCL(@1(x|ycRM3bjw7rQ ztUsIDwcVa_t^i|{){E)yD{L>EZ*z?+e7l(_Vh@hb@O@NhXVW}rVpP|+mPpt>N|ytX zCQJze=y2UmLKz>AAwHD|LsKsz_F@vZxpH7@-h&WZG{m_0I;$vDEMg&hR}{|M2~k{H zV0e_*IJ-@-xxU#B-aJd3S->5)#VKD8*v=|S=>Bx2nNehT`DiOMr8$B{ZBks)Iz^k#x497~>|3>*3bcYn^e zD@PsJm~%ZcHU0Hzg-561JF;T8bt<>LKdoS9OQ)wbHIqA^Q6-yX`GC0Cq-eAU36G2|-7lxko)j zDCf68i+Wj|yn&R*w3ydHVDV#S>@Q&EQ{hg6g4^^A!JiySh6xXGf| zHATmS^tlE^YnPvcU{BsK(EYHJZJM_59TAnCbKmGetgkadHz?a|G~AB-xr68+77B`5 zE)2y0Lg9+s_@Tk}LjZH=ozyW+cusXFaeeQ~l%cm-(%Uyp=d6dfgBcVLJOnD1I@kjv zK%B!GD<3zA&-~&zMXq&K%?11Y&cHa@ZYLpCT?%wqZ(`c2wMGOVbk9}}sZQ+)dQ|W- zKSakjXsle1u1JBMB4+@Ln|{*5rU4#fCvP5L=OeuO#DVpjbu;{pbM+I_>x5@!l?jGB z?zkw)lt6pZViI2PN1pV06qg{REI&3VtZUc)S0gpc?(rudrsu3G4#tWHz%$+$yg{XS zb0v4xl-Pl{3**69t<$OIrPLLgXCRN)JunN5ez-&exrs3%Jl63dSD$WE=TJr{k^;xN$+-x< zZo=!Zw!?1Vt4>}hH}U%1KhmtVGdd* z4>FI^M*Ql;`{~0g--r|sE(9V8GlLW*-Mbnf%U|vBD|_Ddj$DeN zEu&-mw+DA>kmNjU%z&bGR1iBIW7VC^_1YRy8U>pP{^k*)88@rwE{CTSlf7fMl@2$` zU;5i88H@)j&fo%&>qv;hrnWq{PlTJ6+{`TcBVDBlYalKoSC&&?tH=&e*d5(Xb%OzI zQ!uj<_yQjgErR%Z=cpJ;DG;6@Y`;c^bzo+dJ|QC3u}=B6(}@s6U$~+YxS&cjhOm$? z%ua+#8-F6-eToa(84|3`H;D-=rp7h0Jv4&#aE*YkS-wKy{fNTX&Z-HY#lwD?j$go( zqg!X)xFtJzB8@_6G{C8!EYnXJAl;3b<|uJ3t^B#~Qf5ih%>JvrpVra!^*HDHB%-4zdi$(~LUnIu9*ceS;^Fr)yQQF7 zH4^X5N&*y<$0Zkmz2f?HskfKKaB9=fU6RA=%Hf9-zN_K9VXBR7Y(h#i>KnrXcL3edy{knyj_dSG~fJ7N1_!-#%}Ru)LClBS9NtpDdJccLYi9FLNu0}vv?j)P5o)jy{##8DTBwJm`4PJ7)-7MC-B#|hgndH^e`*T z`k9ZkJ>cc808E)ER8b~!<28`_*;SmZa>vAD@0_SQ9nS<9h1t^(3$P(g8W8C5cm>EI zPnv4{^zLNP$8!j%)Nf+KY`dQILa4;7VYfLT^W6~L9tQHZHmu&8iuFQto3}&YyTxUO zg56_iakg;1Jw_{_9J==Es}k%%Lf;*~2-6Uj5F_~5=PKR^FeK(7Cl<&l;x zn^@DWU_rk-=3otx&x~pxA(geD3@)RBi;H)rh6Ywr&gFkR(J?C1hGlNRP&{X~PU3kQ zU^LxaCcYmE9_vqcCXGn(zy{Die&Y{U(&5tHxH#cChW{?<YIlp!Z*pguL zoA<|(7Mfk#nOmIOr?`mp8Cz+tto3em+lUFCX_kWOc>OAxD5sxtxMH_`R|f@PC;Sh} zJ1m-758s1}@8%Pe03&`hfF7my=kVOPE#UBzG&lr0&|G0a1VQd~JkKTWh5xqR-=z@X zIn562!vZPP1^{IsFT05AT#<@MK1fSMA_zkAt>-Fbl1q17+|U{7%u z05}les}fe6i0|(flRk(6g96J3$sp_A4Cn>)y?5z>L;?T;R4(+U0T%f0pw+Dgnb~DZU7bxLAdbZ26yz!x{;r% zm(u!F7^%qm7@H7a!M#K0wKUYmx8+&w!MC@*FnY@0&@TQ!0*6_XJop`b7ACkxk zJRfuMpct$9W^;J1H+xz&OqeDp+-NV1kXiGJi1Q-fF~VyQJvJOxM1;f|be ziey1}7$>;u+_=pUF#{PL67`Hrd$pb4CA9+zz&y>oSC-H9eoZ7;7&3B=DCF)wp@1lSy$($P?Ji z1+CN#42bG|Yl_hIKO(J~Js^LFmc6au#?M<(7I-vS!SJp|7xRemTQ4&izUUole_?cO z#TVPR`epFt?4>x$GD`_{s0poNTh*8+>S#Q>g@4Ix?QZ+y{5t_*aSVFbJIWOi9>MZD zJNeYMhzw$r#y|wY#SsDfP;66Ef8~L1)pciu=J)T`V1MRtJ58npX#cW%n1KVbf3YJj z;>2?ny(+#_0{{*Oe~wO()99Y=4ifgu=ac;E-@j585rS19+3$ybLf2iYOjSaEso~-YJZ(*%5M@u^!)%pSE)5wvAYUOP!AZ_P~u|D}u2Khb@Q zXvgR#7d-L%ImPLa_Oj$}4?x3|0iL+OgOcBz zudFPt=r%@6pv?4siuH0|Qv-Y)WGHo_Qeqg+C;+g5qWu;s>A$`)#cF{{0e>jXaz|jqY zb|C6-p9B58J$rOWxMt+#{Dr^u{gU##YG*fUbnIB)}!Wn1>c1zytbz0d$8w(cmaVfCc{m$to~q2R}aW zkT4h^{VC+u0?X?L07(R^`{~+0{Uy*lhT^$AWv{(FB&nD2nJrijGp|R%y3CAz2&C;PdAKq#nbMR%)^yEw}xpwTJP{mc%{y;F5P@LbB&dRJEQxU)dQ`+VRe_H zKr@1LBng&)o)&isYVM(8BQJ!djt@ebLK&pjq14o_k`Z$At-`qGNtUg;$|-blcjxQ` ziGf(3XFn~0Xiw`X`X_(8ubhtpUzeHJ#cSJtk6x62Jv|0a)bGOi=J(-&9ZyR1Rg6gr zSobUMxvyCdErHK+ z+I&j%=Rw#R8oQMSSwK)D1#-~y$tV6Pfi;ygm@ET~=GQ;`SGWS?yk%oMOZ!`Owr<_z zv(gY0X)$N)AV+yQ=@9}3to>JsmK&^FwOK+KEOd;KI*|x}aOYlK>DZP6m{Um=lSp`R z@}E6vQVH;e%BUzm`jI-8h{m-P<$?HWb;b6)j2utP%gdtzF`B+qC~^{qIoO%0ovbgr4wW9}5-E?Fz0KBR!bIRdCtf@iQmB%D_v&J}N1W$Fjyi5` zC?kk~qqm(yp+ykK>NZy@BOwp0#ViBwgC?dThb|sMZF6XtB+np&MB%1jK#Yt)FN+$B zzZWl@+XfAfy2Sl#4gzYXbk4T1UB>mE-okHS9qM_DMV4zvsOdQQ9D10)QX)?DGorJs z00LE6rc`b?#NFqaVyAK2vug|F24p?JNxHH2Y{{c@6VIL0bWjo{2(i@`V=B|oIUQ9+ zq$zdlhhETr&IOLQ(~bwifRez+`>+0E?Q#!^9)~y+ zqgbzcCn1Nn8~4Z%BBe^g%5!rpIuQ7Du5{#2r#~+t>-dOOug>5>KcolC%VvavZEmX7 z$jnlGXr9d!xh^zE&Ci&EKMxPpAEa`%=n+8G)3({DF48pNZ#fiwSrNbR;O?unMzC`y8j z7h`tEMZ{COMDI!KUnvrBBxh(T{*~(ngy+ybLxoe>dLS$dN{}3Vmnwoc zTAhJ{I}_&Z2m<}!R?xy(@NNsM<>F0&@Q|yaMCfC}9>KJ|vU<}MWVM@?mRXyIl^H5y z0$=4$olElgM+@E$>2}l#3rgpt7OrOC2}Fzx(Q963FeC=auL9JR7-~(6o<_lT$RA`;kQqhev+b8PG3YyeA5ox z;vXZw=rVc?C*E?leAFd>HCelSkXQD{?-LJ)&08~+&gGXu)DW6@^iRL-8fgDf-9axy zUIX#UDR&R;OQ{CJF{}}*26FH%=jviqGe9!7+$=4+4}+Mx6dzrit{be0rRWPV7Zdz> z7EiD}K=o6aCVZqblu1-ggU1|9LwBrsW>bhiIAO#Vb}S2rgJoj-Y@12II*Ntu{6I5Z zn>V2&+uS_Ll44?wMsJLMa2Ow;PAzLiI`&quBS>ZYYiG4N^@%K`Az{^AE>JObPsG{( zdlSI$$x=Y#PO`F2cp~b+R1T@`#eDaue&g$E)~sRZnC>wC23yWO8c5yi-GThRb<&94 zZ9~!n$GJlqYk!vKeDeLW#(S3Xi2iHZPe596r57~O}lVwUTKV`KWIhD54c&0 zXNd;1V2*+pBYT*~3u6GAAe*@@m{y}^nUd@w2{lzfa;TP$trzI?-JJ7mppFXsGQe4qQ*HL2f64JNls=f{44TU?`5YT!0d?M4 zv1JYbpqc**`zSjw_T~Ja8x6uHyT)a}Q27}M_4>WS=0YziInS{LC%=@U^PST_ zGx=WOnxOvKY=LFtbUYRk0Cw{OSQ|j)LY%iW=5cUrrv_ zS>~-5$vdTSfz`%!otvmloY|3(R4gMX?VPO=YPC@k;L?EdVg2+KosdE@{Gu`Li%b+P zS5g0yzveNPsiv%GBmq7{_zTfR+}nV52cmH(zm2#F|Ls83kD$tV!;8p-Z8BQD zhDa?Go+}VO+0vA#i^E?D#=MV|h5cc&W?$h5zg!5Hr7*%7DOd|jXMGsG%@;e)#68|E zz$9jd&4>;lBVJ~<->Sd7k3Q+m6Rjb88o(%uA!1E@O)iYFAF$rfqpnwCT`o1JB}VI8 zE696fDm0@f-N1;X(=PpvuwV2Z>f;nC#-pW!$94Xl3x-Fl5qHMo*H(|y2+Ot;VOG&7 zIti#Q{;8xC+8P433XfyIMkChLbjeX9HEq7Gmy+?XlZy+u%LcIT@$?{cl)>%SqYgyL zUuHI^#zs26U%a79zv{Bup*gtIuRHo)a5Ik&Pc%(C2TgYblq%3PM6$j3h<`$}X{8kR z0OzolCCl8r&!ldmy$No~@IZRhPe_HYH~c>Fey3q0hB03#S;S$Afu7@TMU%D+PWW-9 zy;A&4kHM>PX$28qRzN5UL(Z~s7C7L{aGYo8<>^OMx8{CL;??j(seJZ_>Hj|gHdy{Q zz=m5Y0xgh2_x~HUfS3o=7QO*V18`yV>`37yvD#%_8-j`LaH33Ng!wnE_Je*k5f{StE(2_h0?Jqu%r0Me^%gZy~720nDcrb9c?9B3JwKP5L7{u~|?D~JJ-7^#D$ z9{Z4uTG@G0x4P9!qji)@6$^hif#C{vUgGwxD3 zQT>tos&}WcNZuOKRybL^J)`a+x=20DVxBmCQUVNa+}!cJ+^m_ZFtqH^$Qo~+CabEj zciZX3h242#2T@n}gUgQ5B`UTDiGqe3ACR1d94n+KXgcIwDfP#Jp5GnZe zm84t0X?iM3rbn5fCe!tqC%U7 zkv}j}ny62_Iw&~V${0n*H-wH89YY7Q9}2}cCU$$9Kor=BWoJX-P@lNZaejZvb4Gd{ z)Hk{f&Ph-;aLg2qRSkqrus`6!q`8!BS7vSY8W-5?P0C}^Zg+9QJ~nKAiwO*@PDm1W zXthZ|I9mtRRiD7!?_q)4fwl}k14%+7Bj8{VV5B4jCzB-n2p<_4!Ktm0KejMVijcsT zZ~yty!Iwl*DhB&2Y3VBoDLAjUav%f6MD)hC-iXBK9>-Jfq|64pTr`Bm1bL0xu;=${ zvbnA_n3GoF3`ryl+z2Z;UD)d^}64vBwuhAK2JV(l-%Ztc-}>!P1HnY=t4gkQK$66kM%scNMksLv6QAEyYgC= zelKRM_UkXX-~kCvAmz;>%b}kVr~n`&)M!}d+3<#ayOX-fhcN~T)X>`a6%hFy;5Lc9`S=7>sm$C^ z)azX92BfAcBOX~au<bR(Ysg?|lVP4a)BDvyQMg z)@dPcI?bqaxw@cTf-Swd+x1Y@RA~vT=83o}`JP;t4d1mA;d7Sx#ioWl+9xDLCl+7r z4nBsh$p5>4V}mTxtnh#a%d5fLVyYUhCyKIvT;K=XDh?Yciwf+3{Z~sHk?|i2vyc;u z^ay3PyF0Zk+RM2f$&Fwt%NThN5$FMYc7S*&7jn#1VS!Zjm`BO-fM1^OSu!pL5})g7nO@F2 z&Ks4Duh8i9?`Wn7!e44P2tb>;F$>w9zAc(_!dOv@KzzAw=*Uy)`+kp)qKes-oy`wh zr-zbILNdwqbk~=~Dkcoeu`Ho3cbfDwMS}YB6J*Pm9Nj3O__*)2%rnOBbO&Px`CS!S zg8p+j7Ou$cRWFx5W#Pkw=a7gCzO`e?eU?Z)mbGI6AVubF7@df{bZ4Zg)N|$Mc;5HD z(ur_RP{8!Mblq(zqYH^w-~b>4@D9J^&jxymj%D0-fZE;+wu|VeP_tC|G zG56FeIrR0yTZIxhqC(*QfRjON$c4@gs(98^w{UKc(=vWoi#1PDzFfpHZ=|k*K(D=k66S0&&@~gl~%cQaIarq3kQl z*^9LdwQt!OeDt0W(QY93%gu!(>Y=iwYkjQCh)`_(SOD?-X}^M^XPvJHq=CJnU@1(~ znClpbGF(HA&L)WN=cQQ;;xg4#XE3>fkM_XUjqjFYOkNAs=i1@s*V0o|^9C}M?yuR$ zGdT0j%5qJz_e}ncd1;TlE<}OPCAil#?89B2MY}zCjOW*XSdte637Xu$^e}+DacrMt zrzd{XKm&!W$)!0gT$8e97mpOn6^QaFV1pp_3%%HcSF$8r*^3t!F0tABXX}dFR)RcZ zZZTz;>!{f&Py9^HIV|^UefBTxyI58^jUI#>(A@Zz1KgXBb>qv=Fg88i^Bvw^Gs!Vz ziW~%pyevm-v*cScQR;bAsAR`n6ExvEn?BR3n60nX^&JH@EsS?r4!^B_)kQrsIY;p> zh|v%;>nq^ReI=>T5R?A)ndZSynZ)i~JA=S?$6sW%`BRGG^0QbhAQqQ_B`>iE?_1G` zS^sFM$psddD_)DF)wSlgcQ$SLd82aLb+u0~l+krJSc)Xtd1f_ww0wFaCu70sdqOt3 zA4xWL)#fm?`&I6i9xEH|cOYAQxp5h_RJ+1W2D8nM6@%m7&)!vflE(|zBKjd0rb#jB zXDT5}b)Dr8{7mu3ayAY|wbBtk`$I-ljXq-Sz)g-3hMATyk!ZA9+r%kpdzkON_-39? z*5tP>Jz2GM_4Q6gjRV}B4$o&N<;*auK$!@#<*5U)eesWgV}G^X5X%h$?$>XTt03L=QEBPSRjK)V@s04+lvr%oR-UI z7^vzd*0F%8lcf&e=!h=Xs>-NI zte6FoD5Xq&(*wH-1Gf`s*8>0EL;iF3{f>D5gI1$Sm3Y$)@T5!s2TsAJ&(7JO+y;bG z0EgR`=ru=(+g&O((h`&fCDTF=1Qn%{XH7ESD1UORmr*jy%A~wM;TADpKTK z_8VDt5JXsCLo4hjMq9=*KnaUi(wGm3(9T6(3%--uG%|lia3HK+l}8O19qkgX1U|H3 zrEeJ_J2cw6YNM}Sjnv$CpaK?{^4Y=MhW+imGtCkyv#U4h{#tNnRa4X4o92h4Jc1-m zy>+}$myqtUb@q@85+Wxu3!STQeak?pbVXQq5ff|sNZS3n^C9xaCvGwEE-E@S1ND^b zu~PR*ooO%(i!oi(x5X)f$e7RV_K^{kjXo3~uoM=;CfJC!PJ1sA$b|TtWV6mAEVg3x z3k@l^21vyFUVB4%Ks|(tgUm7z)I8U1$k@j`fXXNFFY$YH=VBAo4s9FFM^n&~m41v~ zFX(IA-qnU-dpb_Aaym!mE3%~@ZX#rzE5vj>3OOGAkE@2O6Mr4xRhqx+7b7*v@Za;s zdQlx9?ar8|5O5kZ1bZZ2#QKArI<%m;T$6EfyI?|L!HTUO;QWAT*)oFu$wKIXJ4RZWM9qRPkWKN$UPNP++wf}eGb4cA1$$QV@QoR8 zH)FXW{(cQg9!*OQ=QQQP=V>H7KBv zL+W2Fkzs%@ACMiusCAXeM$;KQgIeup-9`*VmY;D6gH0~sA&^%nstT3}dToMaFPUPK z30S<-dO2X8yJyxCcn<|O^;dSmXOdTSlYO2#b~Bg+B38;b&4HY*eGl$>aOav>ry2v+ zn$N~>1qSBQ&Z*!jaIQf9qpMKD!cMx;ybbM?^l8}lfRiU)U<2OjB=^U5uH&|ZXT(L$oE^{R^YNw< zKbCult|iY(ic@_N!I=f1DfIR`5hsDC1k<}%-Z@%41sm*@AdgTy-$VT!2~RC97pw*` zMa=}@Bv4oHfU@R-5dt*gW-ssOJRW_3!IYVv8a6}$)Oiy7;b&ypGQ9RwLWuHZT8ZE& zt@vC@^1x%|scjVn7Xi5?X;c|s+ZoCaL#64r6t==#3st<971ceTr(MAp0+>#qn&q~6 zuMjxhH4z9bUpYihYPA{&-oV6*u6c$JKKL1{@MZaove2t+d3wd|esaD^ z)lmj(i?INMU$37EsnoOTO_|G}ZU0eHz7abRgb}95KrmKZ)E$R!VaD$`PQ)!sc}XBj zm8kLE3onFw_y*nMWBEK(4@AZhbQ=HMFu?|-U1@@RLgH-`mA`=js;@10X>f@B#~<@g z-5k9AAHz9pF;9!lnl3Sn2!TMT&OqoeUICA(0-FRq2dLX+KCRAL6izMy18}N99m^G* zZi`((HR~iXd3Kmj@!KD6dzXl#^r_SUDU}=Cnej_5!ed>g#e;Ch${Rm(1!vucd|gT( zs@~G&k=|{0Cv9_+8~9DNm?HBamRpC}8}2%0&f-K9s|hKF!4x) zk$;1u&~gWTd2=@PcufSnHoRH^2$U8$>jge>f&j2e0x*P7aNhWDB@&h+^ylBqwx__Y z`&azM2BcW{4LUm9obdl>K(xp50scKo)u8)N{n0-?&2MJg{{YNqVqvTm{Fjyg7RUku z^MC(cLj##JY+hB%UcI1HD862c0~vASGRub~M3YO)RV{p6z$N#J0)Cfke(u)I0TiC1 z{T1fohpGPT88;cVMV0^?lB55??SW!i%xCix)_CGT0!xmlQ#PrnJ!xCqrW5H%3b3mR z1>D6TgyOV!*!zn3fz9Me{U3Z%j2-s^@!Hh2=GMEPg(kx+oTX4g7n_W*lJ&eMi=*hK zH!E)$F2>HSC`1ZacazPlUzdnj?ETskKtW=t0=(h!-(V*}_m>7i=IuY{fi*CGTme&f z!_KS{utM0jsu@jSGbGMzA5s2Dv#+Y~YTHQG_;L$G=%l zm+tOlHnr92ZXcE79e^p5CDg~i+mDS#ay8}#;kUIfQh9^2z;*_6sZ{YLMEof4LQdCr z)0FzS*qYqjek zK}6BGlO<4|S(mx>D}o@-Re?xjB^mckjEEpc>-!oKXK}Fl%X9Kel~@*t)rLRbkud{O zmE^eZVQT6t8d>}+G=&=j7(0bOPT|i?TP9aYb1d-ghV!x<$HBZ`q)y(vvEp4T)~8}b z9w%7Z;M{W2;$!e5Z;nPp?;lhq!rrbn0Mq)u&HChwAC7Yt6C=I$LlPqzQ`|4>9Z4fC zjxdz@8Nb6j-e!^VO?AkL6Vm5{}d@8BeIhz z-&Hc7k$-b%ah<_7CY-po-=VZMS;o5=yT6T4U*IZrV85!}Ob4upK?57?s0qBSB(segg25h&ZKo7@uhIT7U55i7%$d7}-Xlv_ zu#>V1aNOLyW!(1ZTxx?&c38X#3S@-uHy?lb z2o7AWj%TM`eLCzH)lslC{0XW0_(uz5zLH5w8yJ=UbISi#6K3v6>iA7L6)LY4Dd9qW zDzT*L0s6J}icu!#JKT%nC$%FGp3kcsM;gW8X5WQ(gDZD9De>UVBl)QwE_BS7&hR=D zOr{c`Q!WZtc&{m;72ukjO6C_pCTsl~$S15AU`C9rA9e$WZxn-Aa-ruDmdtoReymq! zH$By(*Hld?AW#qZ5{;JD9h%UPC0#%$1A1!UjFwIh;v#Bb$p@{qrzyejQA=lt^K+u~ zR2c1WQ3Z^gg%yM-U>b5B#5`V1B!j%`f(nr>DB7HDi=X&Xdv5@w&ns*O+n^cbHof2` zxIUpDKYw>KJRQ6n!O!75FIb;lh4Fj0>*WKm%RVtq(8sUTUObieA>zdqY+`M=LD_R$qp0N?#qaxW4eA)4u3&mfO+YjAFk4+BpsiWiR(JT0dv5S*Cx0dOJ z&3mxRpk}42%mZ1KmP2lVIAr}vW5H>ZYp@*K9b>$K(IjQ0-vd;ShEq1-*$7rofd%{!@-C?+7&$~Q%ApG@$-z4$|0-Vr^$r~Y=x)SwQ6TtYm%gQB&8g1?hj@bv)?}C zf-isVwr_M|oJBW*L9`}(p8J_wB`=^y?16+oOfl7~M%S#vBKJ($7nl2?EZ{aKm}>0+ z|49>ELKRBiw)NaC8%e1lP^sx=0CSoZL2jovr1J0*5IGX;#+v`Ds;`_NQyEuKyX~;v z8>NHjCQI*S&%l|2_$g=iXG6CZ52Z1MXn60FF=9eXHM9x-gvrn<<1@z-1GtGM^Tq*W zQoIGwN^=ptSEf`PRF29|Y-NX)NSb0$iyLAr_;djgCocgrZJp=iKDmAwc@0+U4W+y7 z$gyRwI_12U-Gs8TdlU`q+1gnvcckr&=Cyg-Ork-jxg+1kVEKo6SnNnWS$C#lycutn zjI?bk#vciK1KVQMJ!r>EAN~9GFD~jw*HHkiww>>I|DK15oldsf0MCKUzw3}d6aYKR zSt8$Wrt{FjrCtjfrw~gN1aTPgEpl>g$C!#flEiLNHy#nwRtwX;f{dCvNnAK`S~02Y ziCoVNB5;4(sx-D4%TQI$MR9XK{0`q_aqVu*YUd=z?)=po>JgCkbU6YOgn)(S2quu) zU#QJ}DMkHb^unOJ64|**s}4}dXuxqE5aK1oZd)14M@iJfp9P*S3zoz?GDk}<)n{EP9#!W%=@n-!wV0AQ#yw88 zLVb=5McSFDTrhsn;L zPmF~`-ah9doi?WrPPoi8JuK;RoKrUq`n44HU;43+oo&3w_*u&1+1=tY*^JiwA^<#Tq|M{+*!CgXp|krP z_z#izrGP^qI`J$O>nos3AAael|4XyN>Gv(chAyZ%HsCkR#rLc9@8B{3fjL_swb1NE>Re0F~AQ9 zu=x64fL7REL2SrP^JwZuOm^XFw6u>o#blhru#B5`=cLdJgy#=$_ZI@p^HH}hb{ai$Va}ID}u{P_)lT6EGUb1e!*-*Xw^o-LU+X+=w zNYwLosC%h_`5ccQ$>%xswqZgkAlL4RsBE9xcO>D~-yd(@!8q2!1}W^XuDuNE;O_S7 zbnnw*p|JvGrq={6#ZYvvJ_0lUDPY(JDLLls!7cjppVid=mU8@OTDuQh$<4ny-`%NW^ z$Cyv3x_`ZTqxw^$pI}fH#D^!$KEL!ej*AY@8#Ch!XI4%cRt%F8WcU_v*YXQcC$p;< zB0}gzNQ{pp=CM}gpu2DmyPAo;DfAR^PQBenaFZOeoD9;Ha0*X0?GGYxUxFx422d_h zg2K6PmH9m~b+O3{d0h|XV~fH^-KLIs^gb19VNaZ6aSG?%xTMLFSPBe!Kzl9=lgMPO z46c0)m@VuJt#)HIbeo3Tj*J@3R^dqEwf3UZG>dwoP(93Dsy0cy;i~Hxmme%vO?2NU zk8j_RmiVGGB8qpo;N#`TU;Yp>`XK-fmuo78VgV#zfG(yOw!y@^)tDK3mmZxPd6}5I zmoVguX>AxZQcM|$ztglHrTj}PE9sq2I(A5`)JDbQB1bMAEA#j_dWYtV3q_i5;Y#_F zUodl7bH9}zQuF^T>?F$Z12mR}9hS@nujD}uDj;XpoKMuNcQw784R==iH3YGYokI83 zSNB?Nmd}coJS<+TmARzWyoU@d4keNG3)F5=F$t4>GfYzP6x}xsgTl3~Po}DHaL`j8 zwCKT`C`e(im09b?kcp8O!bMlHFQCs_<-8tQM3Zjxy}5Z}ikt9+-{=vdw`sO;S^en7 z_Y>I)PYOITu~I!;T0goSp87~>fw_%XR^Zg&qXPSaQ)+^MT1ZP!ZQ+aP0L~0FQN%!1 zUFX2tSI)LF(ZECNYdqGf={oZe>L$k58%elBK={mBxQF(eNa8qCV z%hX>-Uj}_0e!gAXVs+M<9wQ`f-h=2;o}=TWMLjOZsd-967F2y<-37CNQMUcV$o6?p z>o=W(YcEHDxYLsvKTjb?`*AeKLC(^yNp%VUa7TIa#-OMA44)$Va<|vmDro*4o*W>2 zmR`migm*fkADPz5n#IeJUU_5ie{uF!QE^3CyJ!&t1c%@rEV#S7I|O$L?(QzZ-5r7l zcXxMp*Wm6@r_!hUzug(*?{UU`;i;;q+I#Ia=lbR+jcu4Zl+;j-Ba)T4uas2Z462JO z)kZwlY4)f23?R)h8g0Q5h(&i}BF zj_>{hEevdmTSO}aw9`VAoGC+;#c0CQoTZ^EDst4?!Mu~fG|1JH z=F^bIh_WmUq2A9(P15vnaEQlb_7lqPU3q`6tHvt{+ORk4?5*nbs=e^IID^AdFr9av zZPGdMHJiGh56g)QO~IMN%y}$AQ*eZjOOXNB-sArKn~oyRv?6ROc`vflX_4h>K`vX> z?o)}M#P#XJS-dS@f2vXI7|P9Ow!z0ZFxkc-N)f5mLHk;jlRJ62{niNqA*(>)^EgN* zP)3O9gil9FrCDn>?iTr^_M3N(VO{l2O0xn7Ei6#o7jYFG67?k$|>omJx z52%}m=S`tsrlc{@sm|Ks-d%XoH<`qyL#zsq#~16%i_8%gZyA&#*1UNr;(nhAL%I<^ z-&v;bo8u$3yeC>I&D5d{Pk}9g?dTwiXC;&UJPw9ayL2jBSS4SJ_1mEyfY%Lo8h7|5 zeW&FPc$^G$c%Wp6W#kkfFKc0W4lXimZvMr_rSO#QB~bC;TF~1-%W-ULt`h1*b4Z~V z;dX4uX4Qz~oP=hmTa(!yy(UANMl~(Lrje5E>HFyp`zxMh+3sUCo^-|!+vi3(+&g-{ z>vFh*+3?Sj#)`p0_t4 zMdPFO5LuUQ9f!P8p2@V&9?f$e&p5GsgmH=E9ARUW{rQ2*_yKnDEE<3Ss4@y9A4U)f ztm=*m?1oN*XU1W8T=k`23O*5E3`O$Nd(d`d>`>Lrq%|zJWKWB zMHhc({?Ycg6B3~Z@h{w9`liAk&D!!^u{#?X!4|SWOwJNzzEJD?p=#u%IPeA}pR2s+g zq;GtWH#wmu6UggB>!c8CYwx6n8~`F+2D{iZ65}&ZO|$TOwx`9%ioqv>_&y7r%iA@@dIxbq zcK?z(4Aq%4aV@4)KiUF;j|r&=C5 znZ*R=l^}&%vdK21bq)@4vkvUaSI3uN(KHzOtgSon-PaxOI$e`S7f1T(^qpEp)!^L> zTApOr24XG9^tp;!2&GIQiheeHNxq~X3{YNMpUQSvTcPgontaf#?KnTm`rrdyaYVr4 z;=3<6QG!n0Qjj)LVaY3bp^qn*bd~ zI2gu3>PV19VK5ydhsim^TotQ~@ z9ekm5eSS0`+^X*#>FD>phS;2k)Z86&ZZ!*#+QZYKiO}qH<>L+(hCqP@ zd-CwFDWg{-X}CG!=~UUt^>+N@*t{2HCs5N$kq*-=N|YM$5__D!;D|#(cwK&oehUC7 z{H`Cx99!Eb6oY<^UOaw$+LMvs_=8?N)0Spd(kQxe_p|6kYs2rfPs4`uObmSquZUP(*_BuX~t!S)N39Zrg7}rq;Kf06>yDX>duA}()L4wyri-@O zF!RR{YUZOJGy$Z5wCEzhFtq&2sc_|`J{S_d5QkKVH2>5l7`JkJTolW9r^zzR-$YgU zLXdVo1SiHKc(uK#e%6Jd0WwVxz3>mgu2hHAf;*tu3bCJ@M(b6Bx&*Tq|M zfrc$H(Jj5jNUly+LY)%exK#bZj}E3sz%h-Mpy-C@S~>gMD4nHoAF165YHCMx=4DPl zkhJpye`qAhl|X$!KN#S(;#OmnYMUl(h-1k_z9(N30G{cxJo~XrI7{Yalsf^i?;fF* zg_c2V58dGV+JS=f9rQvw8p{y@FYyUcC&yW+hTXYNWyFT@AZg3)V@SQG>-?vMCo~N^rqW7TtOw z1tfNN$2L?821u)e8?tL}w?(+}%6OudswixIh+ISd`$_t3bZfSkmQZ`d#H(moWpXZz z*Ik8RnI9A@(-7$#i?vj7M(gd_i3>oP1@VXJ$+A3WcT5}RaWIBofgk5pu#>6Qnxe!$I% zSb|mgJjS^t0X!R_^>A^(_`6g-FAF9E7I@A{?K&e53#4WUH#ak(4WXRJyqV1UcZ;x+ zPtO#~s5@;@h1l@)&WvZR#;hT)VtcLoeoM{nSe@N)uwEO?rALkxgzpqx!K}g>yimeU zSHMm;aVntnsCA$NO&w1j4pl)F9 zpKi&Z`Q)E~n08RcC2A0&4B^MMoVZ5nAkHHGbq?|`e3JNth)BMIoVP5DkWpZ*nnhtE zx_#^Z)cUNwNRDArZ%el;&a+s;UM+L`Z-iiRdsLC@%wZWGVce19<~3<^{wf^@EUBCb z(hN*HY~`u1>j+0Ne7&^}vey=_$6H!P*jEccnFFr4S$)nkuU&nUdvcv zAChzt@rfh`s*I{Ij_@mgkH$nWVYG}YyVn|+#1@nX=jIvd?>(V2@?uwZ zynPm9f>Gw`0P`N))HqiCc3@&Zvh?&-q_@MmY!`k9V$+^Ae@pWPk>Y+{C(D!jqD{1W zCk^Fjg$+WFiGG#?+l^4_a))6)fz~=7Zzu;hhi6wzp3De;z}810Z^EGQge85VXwucc zlS*!^zh|>zw~A!u-TVM+hlDvqvz7RWa7tphd0_|g`uQ{$?L`;+TNvF2N3^FEx2pHP zFOqI6$}Q2L75^Tk0wqAvXY(QAr=ole^Qz9dz22t~$W^K)a4CieA#J*D!3f*FU0Nk2Z`IidmAu=W;K7t;Nk)ErkZCa2>n4G8Or0jWdlI1st-BEN5ld)!}tm@n-2dhPfWxG zkKJo>SEji@{7ADkZNnam+oihDuJO7+25M9aGNnxL;YO~p_nS#1Je0iN(_%{DetnTF z6oovuskOf6)st7V*LZ)v&;>j7FzcXoTLJwN%SrCTqXb2~32zz$5B?p($UOAg@UA*d z&ktSJzgYnp`ymk`@$>=2@IJp#oS!vF;i3-2@{kn!W4BK{1K7VvEb+7@K$Y&*=`}D` zm1^vO=^~YY87aRbFiSe`K-L@+HBf{zi9*g$66UTa@tS>ecp zWe{QeB7~9)0WCQMrc-c#lz`s}KLdzA01PsheS;!5L<=kpzCOu4fBocwS=t@=7}#yY z%scj#kytis1-+{m4j~GpvJXE1ez|PP0z-HIQuPc{tsrLtp&~mWY03ri(=2)M{*Kou zf}uV&__wbQGWccvLtBBU%C`qD?rvAU2aTAx`t~#er+(xqd&A>UW@|(8Wk*6K0t2w- zDPR$DS|YE&(+oj`4NS}`;HCv?$7^;#@hjRVUNur;K?Lf6km#wvj|hSy-rY}nR(C(B z{U$>GhFjes>oyNSYkL61KKVmH0R_XdFs#p2hk>MvkXx~&Z2}loqcJ}$XIh4d$+feH zwKZG@?W!a{VP2!kn%u)QQozMg@rmwG+EQ36_pi~sgkTLP86hY_UI)R8GrBvUx*y-I>F1qwm{_8;`q`a&<5>#X6|d6sEF+9XU_sBp~8A6 zkLb~G2m{(WHhR9b)Ug7PfgAojgq&TJ4Lj)b_6PQyEh%Ps<0L2+6@#jYX7?Y1_0CqJ zusgwzQx~~X1~}*+=sWdm4mE+C*9t=Bbe(!9MplO1=V1wzJgpLtI!lYN8 zj#ejkBTF;R3okAQALdh~Osb;f*>LVctaOveBFoVAE%kE0T>1|=%mNy^JnZ>55Imu% z^9t%qT9co%0aj-bKgcEx1K^l*m=wt(u7mdgj`I_^O8RbcAoF28$v&Jx&9UKZ;h*jci4}cTj^80!dDkMJ zJ8l_jOLQPl3HMjc@d<7k!Np1}?GNvTGl_imW3wG0J=UJ2gdH>C+~ap0#`c?fS`Jl11HxWTGV9-rZ9K+p!*2h|D=_Z^?tcYU z;QxW^K~g04_1JDnO%NA#@=k}_e@4sYvyjQEa=jeV`rM-JMUSJZr7aPvXC!qva^n!_+<6bL9cf0pHC{_O)9xL!Z%OAjHoD3o#Amnil{gTV$jt3&rn5$XC>0wF!k;w(<#5Q%seQjY~9w07xB9w0#du*mQ8`;KE}FTFhVx_hY=jBar)TM6%2uN>&h!|$OEE*& z{dM>BSHEUAkwV8rBPYR7q6dj;Fh&o%kCbx!RAZy6faF@Dil!~e+0d=pCd6|bJ%dSu z1NP8RezmX62;5U}E~b6yVsTiW!>w3O{5Nj`6pvpNreQXRZXh{X{0$Cl;|5Xh2EZB+ zF&L96ROzI`$l^wv-HV#V#F*xC9X!az9;|aN4Qo}G8ARP%8Nkxz(vYKv`{06t#-p#H zvvw5I4i~OgkkE~|c)LSo{o_8dsrN5WTv@7~(m%paD<1nW_8~07)b|h}RTz$5= zF%5t>CYxmB^Vl~H7;b2&X#vZ@8zq}7hi=HX`#Hf=u1+8IbJgkO@D38G7@iF+@>737 z{s#mj#l`3jRyoS{^p(P^`BQo5GD0eAsN)u}+7^~8IY@F0V;Q+1Vbj2YG!Goc5JxQ^ zWh#_ef^X;MnMgR1L#;Vwxxap9y7z5jzl8%sMmi?~AS^fMES}*1d#4DpF8OcRE>Y1J zFKEyPl=v?WG$`Ah;Vh9y7MuYoD7*HPJWLN*jC4C{GuSe5bCik(0Tcy9bN7UTmZB_{ zNSSm3b5 z+f4@JgT&Z*BLEGF4^n{2$IiG*o|98pr|z{~RrO%3%5@vv-q<5I^FT%;7)c6d0g52^ zrSrY>qwjrUCvGAS1nj_^1*BvtUXFdTgLLa>%{#tB_3rcN?TMS(sD~_F$NdKub0JIO zl;jSt@NzI!zvt$hTqW!%@e1Nx&Le=QI?EA>;I9RrBF!O9p3MT`_wVBJ?p}F>#Q~fb z{L4qAJMO%cED5;b3PM%|Jbzg}63Qzzxqzr>h2${y;8%XUUy^q%k2r$v-f@ zF@KM-ErioBH6wJ5j#E^8`e^3`PC$64egyuhd167V3XWBWg2Cv!@kLForfV?l(y5r* zbx`UXlm0zBK+U|DC&jvill5KYiHhhtWQ1%$pPH+ku|nmi3Er&?@4>UjeaSZqQ%AA# z!jLoC@^6rEP|Sr#Rq*sy-TC=|)5N?-6jMPBP%^ik#ooTQ#ucNpm#&Dc>qjy|DCYuQ z0MBo)t$VgkFwq&M%I%Zane@sNx9CPAEHJ1Ix0M;?Z@iq8aXkuSliI2}Z)^4+KLDld zcAjTLRwrrd6@d6)7xwZJ|aDF!J&6t@6)ojGQG)8vNYJw zbM8I)PB(c6{VyAiUfb_(&8S+a-~^fBdN~@3GE~J$-)33Df4qN)&8hzcm9TLB7W@4# z=KtTZ3Lp;Z|F5VpCS4HM`+q%FWw9KF&Vd#{AN>EV)~rk*k2=tBR1Sv$G#s7C+!GfV zaVirG!isH~!eg;~)8+i8&v!@7aA{+NAf%RhJrm>;z(6TPi$h6<-x9MlDSE{JMOe5q z{I2@q^r3f>wJKI}Hiin1@#3Snh&Op`Dr`5YE(6uoL&{g5M!c1Dbf@3x1O&d!PCSQI zD=@GK0Pt>I{`HtM#80rR`~;eQ{aIH5eXKTxP|k1OoC!0`+3RwM za5J>$v~rP|Zm&OGejFaugBwmc zYoA-gD?2Ac;JFRt6Tmf9rJ^AE%Ax+6#UrBkdj>Y5qf6(nTX$qN3l}EY6`;GJj1&Ip z2BWJE-=0O%h1ixQbKI`Soy?{4MKZG~{&DEt^SAQRnv%#)7tg;KX=5u_l8m6|y%bcR z|Iwte>2mx-g3QAVi?d1nGo{2ub1c{qn!m&?2OVf|2&p!R7 z${K$iou(Iv&K*D>==(3eE~737=*V3i4icXXbdJ;Vas-hqxrG=~m`(IvBiM`ZO97)S zxU1uB)hj;(KX4f~M(k+l*frrGqvB|G_mnB^ea$41${Le(mcc)=&#?7(8&B3Xc0L$S ze{x1|+R71;8K=;Ai_uOC}$qHIx8M?{IfNf-DOt!x!wgr3xFHXSW}V$|GEd^vb$x3%#b&~ z*v5Wfk+c|1z{gm~APWgyi!RU6hZ2|L1P;%ni`i|hyMFu*0X3)KyxCQlr5Q~xq0l)-j5bF z^pN0F2i3qT>aOoo&9c z6m5?H%hYa(OJC_GOukO6t^rSaI(xDb?Q}26wv*|IwjT-zwYV!WH@V1E_g}uzhkH6% zrFQOEP8VaxOJ14!qWB#e1T(64Hk%Oa#|N_Z4n9B!g#!I83c7m;2b!AU zUd9?-j_eo|F@J6=zl@G~-W-gxX-?-s7b>99bo~|&Z;uHWDFS@nj)N|4{{WaFas(8T z#(=#FYS(Q+9eohvKc_tV{D|IS3n`8a52!?DhRX?T4`WfqkuRqHP-0i85C=2u4BmO{ z4o!n3as7yuVQbPuz;%f(vN3X*iuJh=tnPC9d#0dEIJR6}hFyg*Rjx8>74_9vKgmJC$8fRQh1dQ#WZUA?_l zld%d}r5jGXt3NWw8|)1-DXBK_XPZbtXAEp&6ZP9k~>1{_gmJY9daRKFYri?gpmTL48M=@WEz%>7_WOia0W z1s=Dcjs2z>N$0ZD7XcwPiPupYEG-E3OA~N!Mki^CE|mlLhYK^KA95s}6=W`gVOg|^ zkavY-As_W%=08U6>M?5xeOsN;uREH&dxo}WudMC2+wiscP~i?fGNSR|rx@U@lLiBS zYVi@p3>*p(Zzb1F3(AyOGe{$>A(s|>UREkeRHKL}wWpXI3{hfOtvkZTfIX|yKhc^{ zj_l+F{gsAmd|r3py{oZ&l=ZZ&%bF2tgV%%=)R*~Ks|58-6i zbM92f?zXAA$euRUomGn7D(05 z@lRk91QoHc>?d_wuZkiChg2hDPjru$@GB;qm-y3~WqlE$^9udo75JPKp#96>7GX#LN2>eY@dR9oKCbI_W8g$EI{{y~J3IA1h@Nt5G$&ii6>f_ST!m0sj-$$$d( z7b=A{172VN4<>iQ<*tyk>E4a7UBl45V^ROh%nfhU!}A7jUg_(2h22Z^P)c77F818D zi!qdl0#i%^;l1J@U0EYNw4`)0NsesgsMZS|fyq)oA1v;+1Q%}vGWDhPT_BUBFw=&0 zDoJP~)k#N`>M5^IM3_P6c-fm%>#;_YqKk}mveD;C1>_CQ4(E3?OGe)@hmD$S8&2o@ zN2YI+^$YF?yCCa=`tKR*vS`3_-sOVV!3PSf(*pB`N$2G+OxCvBZVPEPi*occu7!ua zjdxxe`LqhaB)rRa?X+V7V(iK+#N&t1pP@%H`(+hqMfLAysiuY;ycIWzgkMldu@1v0 z`A8);gcyiy1(WXpbKRFM7e@|+|*RC(u z=4E`CWefeeHPhqB&G_(O{z!GOWPj4cW#|62ED88=sm*eJ_E6&?o8^u<_<6u{lI-YN zLJ83Jo|%)r8?U==^Ap4UZPKr4rCd}Ni0Cd7;;q3Ip7AbZ?H2j2yYS2x<9(eAOacvx zdgy{iHGuIUzkG&OVG>2aQf(sVR1GVEpY_)!7T0${KSaIPM94}ipmH%cvu9uE8f}HD z>xNXf(JYv-6Pv_tG=XSOEH2QjFeTVa^IPC#yqWzAtb_JRQBh;7@IwCSg>syj>4OPX zQj+(S?d%1{Z6I)VGqmvr;(#smB)K0gMovL{?#(`@jG&=4v*`2YMWvk;#Pdo&U8|g) z*6TorQ&SJi-EX**yxUDaQ~{|r$VcSa+2BL|oW^MEiqn^UnGPfyj)v2n#D^bJhzgU| zQ#H|0OYPk*8c)TGjc2Em4?g;vz@QUv`?D1AE$`k9*;B=10 z@7P5kw$sWRFmItVR-h8SXX`JD!{0FTA2slQNkgGimJ|KsqNE3E@c+dgWnlq{!8W$| zD2t0&e9$PT{)X?6>N90xK<@z=W&fiy1X-wZFoNQ-5qjz2z|H8qgCD$WbbpV@k;{#o ziUjS|g~Ecl43v?{PD&M zj^*W@v#sDG8k6p`G8m68cg7$UW6*XN@}NCaw)x`(KPkC|y3U7&Zvp5P_vYPq!I1VI z;^k_c?J%SAFdR>I@;$ZOTJAq9{2WwXW)A2l{tIXVv*qyNz>l{qK}>Hr)$D zQQ@$3E18a4lhh^CnsL>~&{3{KC$QD-+c>Q`#k0y#+J$U<®v8|^R2 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%0Ad$v77U3vL3Z6pNhndnL}SAy?j@HjDi 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