diff --git a/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/RatPen.java b/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/RatPen.java new file mode 100644 index 0000000000..ebaa147fde --- /dev/null +++ b/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/RatPen.java @@ -0,0 +1,29 @@ +package net.runelite.client.plugins.microbot.tutorialisland; + +import net.runelite.api.coords.WorldPoint; + +final class RatPen { + static final int GATE_ID = 9719; + static final WorldPoint GATE_OUTSIDE = new WorldPoint(3111, 9518, 0); + static final WorldPoint GATE_INSIDE = new WorldPoint(3110, 9518, 0); + + enum Step { + ATTACK, + OPEN_GATE, + WALK_TO_GATE + } + + private RatPen() { + } + + static Step next(WorldPoint playerLoc, boolean ratReachable) { + if (ratReachable) { + return Step.ATTACK; + } + if (playerLoc != null && playerLoc.getPlane() == GATE_OUTSIDE.getPlane() + && playerLoc.distanceTo2D(GATE_OUTSIDE) <= 1) { + return Step.OPEN_GATE; + } + return Step.WALK_TO_GATE; + } +} diff --git a/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandPlugin.java b/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandPlugin.java index d99aac9841..7fa7200298 100644 --- a/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandPlugin.java +++ b/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandPlugin.java @@ -25,7 +25,7 @@ isExternal = PluginConstants.IS_EXTERNAL ) public class TutorialIslandPlugin extends Plugin { - public static final String version = "1.3.16"; + public static final String version = "1.3.17"; private boolean toggleMusic; private boolean toggleRoofs; diff --git a/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandScript.java b/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandScript.java index a8e567a28d..a22b63e6ac 100644 --- a/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandScript.java +++ b/src/main/java/net/runelite/client/plugins/microbot/tutorialisland/TutorialIslandScript.java @@ -334,21 +334,26 @@ private boolean walkAndAct(Rs2NpcModel npc, int reach, String action, Runnable a } private boolean walkAndAttackRat() { - // The rat pit gate (id 9719) blocks both Rs2Walker and native pathfinder. - // Explicitly open it if we're standing adjacent; after passing through, attack directly. - WorldPoint playerLoc = Rs2Player.getWorldLocation(); - if (playerLoc != null && playerLoc.getX() == 3111 && playerLoc.getY() >= 9516 && playerLoc.getY() <= 9519) { - if (Microbot.getRs2TileObjectCache().query().withId(9719).interact("Open")) { - sleepUntil(() -> { - WorldPoint p = Rs2Player.getWorldLocation(); - return p != null && p.getY() < 9516; - }, 3000); + Rs2NpcModel rat = Microbot.getRs2NpcCache().query().withName("Giant rat").nearest(); + if (rat == null || rat.getWorldLocation() == null) return false; + switch (RatPen.next(Rs2Player.getWorldLocation(), Rs2Tile.isTileReachable(rat.getWorldLocation()))) { + case ATTACK: + return rat.click("Attack"); + case OPEN_GATE: + if (Microbot.getRs2TileObjectCache().query().withId(RatPen.GATE_ID).interact("Open")) { + sleepUntil(() -> Rs2Tile.isTileReachable(RatPen.GATE_INSIDE), 3000); + } + return false; + default: + Rs2Walker.walkTo(RatPen.GATE_OUTSIDE, 1); + Rs2Player.waitForWalking(); return false; - } } + } + + private boolean attackRatAtRange() { Rs2NpcModel rat = Microbot.getRs2NpcCache().query().withName("Giant rat").nearest(); - if (rat == null || rat.getWorldLocation() == null) return false; - if (!Rs2Walker.canReach(rat.getWorldLocation())) return false; + if (rat == null) return false; return rat.click("Attack"); } @@ -655,7 +660,7 @@ public void CombatGuide() { Rs2Inventory.wield("Bronze arrow"); Rs2Random.waitEx(600, 100); } - walkAndAttackRat(); + attackRatAtRange(); } else if (Microbot.getVarbitPlayerValue(281) == 470) { if (npc == null) return; walkAndTalk(npc); diff --git a/src/test/java/net/runelite/client/plugins/microbot/tutorialisland/RatPenTest.java b/src/test/java/net/runelite/client/plugins/microbot/tutorialisland/RatPenTest.java new file mode 100644 index 0000000000..b5e7b42909 --- /dev/null +++ b/src/test/java/net/runelite/client/plugins/microbot/tutorialisland/RatPenTest.java @@ -0,0 +1,40 @@ +package net.runelite.client.plugins.microbot.tutorialisland; + +import net.runelite.api.coords.WorldPoint; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public final class RatPenTest { + @Test + void attacksWhenRatIsReachable() { + assertEquals(RatPen.Step.ATTACK, RatPen.next(new WorldPoint(3111, 9526, 0), true)); + } + + @Test + void walksToGateWhenRatIsUnreachableFromLadder() { + assertEquals(RatPen.Step.WALK_TO_GATE, RatPen.next(new WorldPoint(3111, 9526, 0), false)); + } + + @Test + void walksToGateWhenRatIsUnreachableFromInstructor() { + assertEquals(RatPen.Step.WALK_TO_GATE, RatPen.next(new WorldPoint(3107, 9509, 0), false)); + } + + @Test + void opensGateWhenStandingAtEitherGateTile() { + assertEquals(RatPen.Step.OPEN_GATE, RatPen.next(new WorldPoint(3111, 9518, 0), false)); + assertEquals(RatPen.Step.OPEN_GATE, RatPen.next(new WorldPoint(3111, 9519, 0), false)); + assertEquals(RatPen.Step.OPEN_GATE, RatPen.next(new WorldPoint(3112, 9517, 0), false)); + } + + @Test + void walksToGateWhenPlayerLocationIsUnknown() { + assertEquals(RatPen.Step.WALK_TO_GATE, RatPen.next(null, false)); + } + + @Test + void doesNotOpenGateFromAnotherPlane() { + assertEquals(RatPen.Step.WALK_TO_GATE, RatPen.next(new WorldPoint(3111, 9518, 1), false)); + } +}