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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package net.runelite.client.plugins.microbot.shortestpath;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.runelite.api.TileObject;
import net.runelite.api.coords.WorldPoint;
import net.runelite.client.plugins.microbot.util.player.Rs2Player;
import net.runelite.client.plugins.microbot.util.widget.Rs2Widget;

import static net.runelite.client.plugins.microbot.util.Global.sleepUntil;

/**
* Handles the Magic Mushtree (Mycelium Transportation System) on Fossil Island.
* The mushtree network connects four locations:
* - House on the Hill
* - Verdant Valley
* - Sticky Swamp
* - Mushroom Meadow
*/
@Getter
@RequiredArgsConstructor
public enum MagicMushtree {
HOUSE_ON_THE_HILL("House on the Hill", new WorldPoint(3764, 3879, 1)),
VERDANT_VALLEY("Verdant Valley", new WorldPoint(3760, 3758, 0)),
STICKY_SWAMP("Sticky Swamp", new WorldPoint(3676, 3755, 0)),
MUSHROOM_MEADOW("Mushroom Meadow", new WorldPoint(3676, 3871, 0));

private final String destinationName;
private final WorldPoint destination;

// Object IDs for the Magic Mushtrees
public static final int MUSHTREE_HOUSE_ON_HILL = 30920;
public static final int MUSHTREE_OTHER = 30924;

private static final int OFFSET = 10;

/**
* Checks if the given object ID is a Magic Mushtree.
*/
public static boolean isMagicMushtree(int objectId) {
return objectId == MUSHTREE_HOUSE_ON_HILL || objectId == MUSHTREE_OTHER;
}

/**
* Checks if the given TileObject is a Magic Mushtree.
*/
public static boolean isMagicMushtree(TileObject tileObject) {
return tileObject != null && isMagicMushtree(tileObject.getId());
}

/**
* Handles the Magic Mushtree transport after the initial "Use" interaction.
* Waits for the menu to appear, then clicks the appropriate destination.
*
* @param transport The transport containing the destination
* @return true if the transport was handled successfully
*/
public static boolean handleTransport(Transport transport) {
WorldPoint dest = transport.getDestination();
MagicMushtree destination = getByDestination(dest);

if (destination == null) {
return false;
}

// Wait for the mushtree menu widget to appear
if (!sleepUntil(() -> Rs2Widget.hasWidget("Mycelium"), 5000)) {
return false;
}

// Click the destination option
if (!Rs2Widget.clickWidget(destination.getDestinationName())) {
return false;
}

// Wait until we arrive at destination
sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo(dest) < OFFSET, 10000);
return true;
Comment on lines +76 to +78
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Return value ignores whether arrival actually succeeded.

The sleepUntil on line 77 returns a boolean indicating if the player arrived at the destination, but the method returns true unconditionally on line 78. If the 10-second timeout expires without arriving, the method still reports success—inconsistent with the documented contract.

🔧 Proposed fix
         // Wait until we arrive at destination
-        sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo(dest) < OFFSET, 10000);
-        return true;
+        return sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo(dest) < OFFSET, 10000);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Wait until we arrive at destination
sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo(dest) < OFFSET, 10000);
return true;
// Wait until we arrive at destination
return sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo(dest) < OFFSET, 10000);
🤖 Prompt for AI Agents
In
`@runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/MagicMushtree.java`
around lines 76 - 78, The method in MagicMushtree currently ignores the boolean
result of sleepUntil and always returns true; capture the return value of
sleepUntil (the arrival success) when calling sleepUntil(() ->
Rs2Player.getWorldLocation().distanceTo(dest) < OFFSET, 10000) and return that
boolean instead of unconditionally returning true so the method accurately
reflects whether the player arrived.

}

/**
* Gets the MagicMushtree enum by destination WorldPoint.
*/
public static MagicMushtree getByDestination(WorldPoint destination) {
if (destination == null) return null;

for (MagicMushtree mushtree : values()) {
WorldPoint dest = mushtree.getDestination();
if (dest.equals(destination)) {
return mushtree;
}
// Also match by X and Y only (ignore plane differences in destination matching)
if (dest.getX() == destination.getX() && dest.getY() == destination.getY()) {
return mushtree;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.runelite.api.gameval.VarbitID;
import net.runelite.client.plugins.microbot.Microbot;
import net.runelite.client.plugins.microbot.util.equipment.Rs2Equipment;
import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory;
import net.runelite.client.plugins.microbot.util.player.Rs2Player;

@Getter
Expand Down Expand Up @@ -128,7 +129,9 @@ public boolean hasRequirements() {
boolean isWearingCraftingGuild = (Rs2Equipment.isWearing("brown apron") || Rs2Equipment.isWearing("golden apron")) ||
(Rs2Equipment.isWearing("max cape") || Rs2Equipment.isWearing("max hood")) ||
(Rs2Equipment.isWearing("crafting cape") || Rs2Equipment.isWearing("crafting hood"));
return isWearingCraftingGuild && (hasMaxedCrafting || hasFaladorHardDiary);
// Also check if crafting cape is in inventory (can equip it to teleport and enter)
boolean hasCraftingCapeInInventory = Rs2Inventory.contains("crafting cape") || Rs2Inventory.contains("crafting cape(t)");
return (isWearingCraftingGuild || hasCraftingCapeInInventory) && (hasMaxedCrafting || hasFaladorHardDiary);
case LUMBRIDGE_BASEMENT:
return Rs2Player.getQuestState(Quest.RECIPE_FOR_DISASTER__ANOTHER_COOKS_QUEST) == QuestState.FINISHED;
case COOKS_GUILD:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public boolean execute() {
return false;
}
if (pendant.getId() == objectId) {
//The correct id for the object means it has the right left click option, so we can just use that.
// The correct id for the object means it has the right left click option, so we can just use that.
return Rs2GameObject.interact(pendant, destinationName);
}
Widget widget = getWidget();
Expand All @@ -49,6 +49,10 @@ public boolean execute() {
return Rs2Widget.clickWidget(destinationName);
}

private static Widget getWidget() {
return Rs2Widget.getWidget(InterfaceID.MENU, 3);
}

public static final Integer[] IDS = {ObjectID.POH_AMULET_DIGSITE, ObjectID.POH_AMULET_DIG_LITHKREN, ObjectID.POH_AMULET_DIG_FOSSIL, ObjectID.POH_AMULET_DIG_DIGSITE};

public static DecorativeObject getObject() {
Expand All @@ -63,10 +67,6 @@ public static boolean isMountedDigsite(DecorativeObject go) {
return false;
}

private static Widget getWidget() {
return Rs2Widget.getWidget(InterfaceID.MENU, 3);
}

@Override
public String displayInfo() {
return "MountedDigsite -> " + destinationName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1605,9 +1605,8 @@ private static boolean handleTransports(List<WorldPoint> path, int indexOfStartP
}

if (object != null) {
System.out.println("Object Type: " + Rs2GameObject.getObjectType(object));

if (!(object instanceof GroundObject)) {
// Skip reachability check for GroundObjects and Magic Mushtrees
if (!(object instanceof GroundObject) && !MagicMushtree.isMagicMushtree(transport.getObjectId())) {
if (!Rs2Tile.isTileReachable(transport.getOrigin())) {
break;
}
Expand Down Expand Up @@ -1811,6 +1810,11 @@ private static boolean handleObjectExceptions(Transport transport, TileObject ti
sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo2D(transport.getDestination()) < OFFSET, 10000);
return true;
}

// Handle Magic Mushtree (Fossil Island Mycelium Transportation System)
if (MagicMushtree.isMagicMushtree(tileObject)) {
return MagicMushtree.handleTransport(transport);
}
return false;
}

Expand Down Expand Up @@ -1925,6 +1929,18 @@ private static boolean handleInventoryTeleports(Transport transport, int itemId)

if (itemAction.equalsIgnoreCase("open") && itemId == ItemID.BOOKOFSCROLLS_CHARGED) {
return handleMasterScrollBook(destination);
} else if (isDialogueBasedTeleportItem(transport.getDisplayInfo())) {
// Multi-destination teleport items: wait for destination selection dialogue
Rs2Dialogue.sleepUntilSelectAnOption();
Rs2Dialogue.clickOption(destination);
log.info("Traveling to {} - ({})", transport.getDisplayInfo(), transport.getDestination());
return true;
} else if (transport.getDisplayInfo().toLowerCase().contains("burning amulet")) {
// Burning amulet in inventory: confirm wilderness teleport
Rs2Dialogue.sleepUntilInDialogue();
Rs2Dialogue.clickOption("Okay, teleport to level");
log.info("Traveling to {} - ({})", transport.getDisplayInfo(), transport.getDestination());
return true;
} else if (wildernessTransport) {
Rs2Dialogue.sleepUntilInDialogue();
return Rs2Dialogue.clickOption("Yes", "Okay");
Expand Down Expand Up @@ -1960,6 +1976,28 @@ private static boolean handleWearableTeleports(Transport transport, int itemId)
return false;
}

/**
* Checks if the teleport item requires dialogue-based destination selection.
* These are items that, when rubbed/activated, show a dialogue menu to choose destination.
*
* @param displayInfo the displayInfo from the transport
* @return true if the item requires dialogue handling
*/
private static boolean isDialogueBasedTeleportItem(String displayInfo) {
if (displayInfo == null) return false;
String lowerDisplayInfo = displayInfo.toLowerCase();
return lowerDisplayInfo.contains("slayer ring")
|| lowerDisplayInfo.contains("games necklace")
|| lowerDisplayInfo.contains("skills necklace")
|| lowerDisplayInfo.contains("ring of dueling")
|| lowerDisplayInfo.contains("ring of wealth")
|| lowerDisplayInfo.contains("amulet of glory")
|| lowerDisplayInfo.contains("combat bracelet")
|| lowerDisplayInfo.contains("digsite pendant")
|| lowerDisplayInfo.contains("necklace of passage")
|| lowerDisplayInfo.contains("giantsoul amulet");
}

/**
* Checks if the player's current location is within the specified area defined by the given world points.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,4 @@
1651 3010 0 9650=1 5 AJP
1359 2941 0 9650=1 5 CKQ
1429 3324 0 9650=1 5 AIS
2926 10455 0 5 DLP
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,24 @@
3666 3809 0 3685 3756 0 Jump on;Rubber cap mushroom;30606
3663 3808 0 3685 3756 0 Jump on;Rubber cap mushroom;30606
3664 3808 0 3685 3756 0 Jump on;Rubber cap mushroom;30606
3665 3808 0 3685 3756 0 Jump on;Rubber cap mushroom;30606
3665 3808 0 3685 3756 0 Jump on;Rubber cap mushroom;30606
# Magic Mushtree - Fossil Island Mycelium Transportation System
# House on the Hill mushtree (ID 30920)
3764 3880 1 3760 3758 0 Use;Magic Mushtree;30920
3764 3880 1 3676 3755 0 Use;Magic Mushtree;30920
3764 3880 1 3676 3871 0 Use;Magic Mushtree;30920
# Verdant Valley mushtree (ID 30924)
3758 3756 0 3764 3879 1 Use;Magic Mushtree;30924
3758 3756 0 3676 3755 0 Use;Magic Mushtree;30924
3758 3756 0 3676 3871 0 Use;Magic Mushtree;30924
# Sticky Swamp mushtree (ID 30924)
3677 3755 0 3764 3879 1 Use;Magic Mushtree;30924
3677 3755 0 3760 3758 0 Use;Magic Mushtree;30924
3677 3755 0 3676 3871 0 Use;Magic Mushtree;30924
# Mushroom Meadow mushtree (ID 30924)
3674 3871 0 3764 3879 1 Use;Magic Mushtree;30924
3674 3871 0 3760 3758 0 Use;Magic Mushtree;30924
3674 3871 0 3676 3755 0 Use;Magic Mushtree;30924
3768 3868 1 3768 3868 0 Climb-down;Trapdoor;30725
3768 3868 0 3768 3868 1 Climb-up;Ladder;30727
3767 3868 1 3768 3868 0 Climb-down;Trapdoor;30725
Expand Down Expand Up @@ -1544,27 +1561,63 @@
2775 3234 1 2776 3235 0 Climb-down;Ship's ladder;9745
2808 3162 0 2808 3162 1 Climb-up;Ladder;16683 3
2808 3162 1 2808 3162 0 Climb-down;Ladder;16679 3
2744 3153 0 2713 9564 0 Pay;Dungeon entrance;20877 875 Coins
2713 9564 0 2744 3153 0 Leave;Exit;20878
2691 9564 0 2689 9564 0 Chop-down;Vines;21731 1351;1349;1361;1353;1355;1357;1359
2689 9564 0 2691 9564 0 Chop-down;Vines;21731 1351;1349;1361;1353;1355;1357;1359
2683 9568 0 2683 9570 0 Chop-down;Vines;21732 1351;1349;1361;1353;1355;1357;1359
2683 9570 0 2683 9568 0 Chop-down;Vines;21732 1351;1349;1361;1353;1355;1357;1359
2649 9591 0 2643 9595 2 Walk-up;Stairs;21722
2650 9591 0 2643 9595 2 Walk-up;Stairs;21722
2643 9595 2 2649 9591 0 Walk-down;Stairs;21724
2647 9557 0 2649 9562 0 Jump-from;Stepping Stone;21739 3
2649 9562 0 2647 9557 0 Jump-from;Stepping Stone;21738 3
2636 9517 0 2636 9510 2 Walk-up;Stairs;21725
2637 9517 0 2636 9510 2 Walk-up;Stairs;21725
2636 9510 2 2636 9517 0 Walk-down;Stairs;21726
2682 9506 0 2687 9506 0 Walk-across;Log balance;20882 3
2687 9506 0 2682 9506 0 Walk-across;Log balance;20884 3
2698 9500 0 2698 9492 0 Squeeze-through;Pipe;21727
2698 9492 0 2698 9500 0 Squeeze-through;Pipe;21727
2697 9436 0 2684 9436 0 Enter;Crevice;30198
2684 9436 0 2697 9436 0 Enter;Crevice;30198

# Main Entrance - ID 20877
# With coin requirement (875 coins for entry)
2744 3154 0 2713 9564 0 Enter;Dungeon entrance;20877 875 Coins
2744 3153 0 2713 9564 0 Enter;Dungeon entrance;20877 875 Coins
2745 3154 0 2713 9564 0 Enter;Dungeon entrance;20877 875 Coins
2743 3154 0 2713 9564 0 Enter;Dungeon entrance;20877 875 Coins
# Permanent access (after paying 1.5m one-time fee)
2744 3154 0 2713 9564 0 Enter;Dungeon entrance;20877
2744 3153 0 2713 9564 0 Enter;Dungeon entrance;20877
2745 3154 0 2713 9564 0 Enter;Dungeon entrance;20877
2743 3154 0 2713 9564 0 Enter;Dungeon entrance;20877
# Exit from inside
2713 9564 0 2744 3153 0 Leave;Exit;20878
# Vines (axe IDs: bronze, iron, steel, black, mithril, adamant, rune, dragon, 3rd age, infernal, crystal)
2689 9564 0 2691 9564 0 Chop-down;Vines;21731 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2691 9564 0 2689 9564 0 Chop-down;Vines;21731 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2683 9568 0 2683 9570 0 Chop-down;Vines;21732 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2683 9570 0 2683 9568 0 Chop-down;Vines;21732 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2674 9499 0 2672 9499 0 Chop-down;Vines;21733 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2672 9499 0 2674 9499 0 Chop-down;Vines;21733 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2676 9479 0 2674 9479 0 Chop-down;Vines;21734 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2674 9479 0 2676 9479 0 Chop-down;Vines;21734 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2693 9482 0 2695 9482 0 Chop-down;Vines;21735 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
2695 9482 0 2693 9482 0 Chop-down;Vines;21735 1351;1349;1353;1361;1355;1357;1359;6739;20011;13241;23673;25066;28222
# 87 Agility Vine Shortcut
2673 9583 0 2670 9583 2 Climb;Vine;26880
2670 9583 2 2673 9583 0 Climb;Vine;26882
# Stairs
2649 9591 0 2643 9595 2 Walk-up;Stairs;21722
2643 9595 2 2649 9591 0 Walk-down;Stairs;21724
2636 9517 0 2636 9510 2 Walk-up;Stairs;21725
2636 9510 2 2636 9517 0 Walk-down;Stairs;21726
# Stepping Stones
2647 9557 0 2649 9562 0 Jump-from;Stepping stone;21739
2649 9562 0 2647 9557 0 Jump-from;Stepping stone;21738
2695 9533 0 2697 9525 0 Cross;Stepping stone;19040
2697 9525 0 2695 9533 0 Cross;Stepping stone;19040
2690 9547 0 2682 9548 0 Cross;Stepping stone;19040
2682 9548 0 2690 9547 0 Cross;Stepping stone;19040
# Log Balance
2682 9506 0 2687 9506 0 Walk-across;Log balance;20882
2687 9506 0 2682 9506 0 Walk-across;Log balance;20884
# Pipes
2698 9500 0 2698 9492 0 Squeeze-through;Pipe;21727
2698 9492 0 2698 9500 0 Squeeze-through;Pipe;21727
2655 9573 0 2655 9566 0 Squeeze-through;Pipe;21728
2655 9566 0 2655 9573 0 Squeeze-through;Pipe;21728
# Crevice
2684 9436 0 2697 9436 0 Enter;Crevice;30198
2697 9436 0 2684 9436 0 Enter;Crevice;30198
# Brimhaven Dungeon - CKR Fairy Ring Alternate Entrance
2761 3062 0 2734 9478 0 Climb;Rope;66
2761 3063 0 2734 9478 0 Climb;Rope;66
2760 3064 0 2734 9478 0 Climb;Rope;66
2760 3061 0 2734 9478 0 Climb;Rope;66
2734 9478 0 2760 3061 0 Use;Crevice;30201

# Karamja Volcano
2855 3169 0 2855 9569 0 Climb-down;Rocks;11441
2855 9569 0 2856 3167 0 Climb;Climbing rope;18969
Expand Down Expand Up @@ -3971,7 +4024,11 @@
2621 3690 0 2472 3994 0 Travel;Fremennik Boat;37432 2
2598 3608 0 2596 3608 0 Cross;Broken bridge;4616 2
2596 3608 0 2598 3608 0 Cross;Broken bridge;4615 2


# Waterbirth Island
2523 3740 0 2442 10146 0 Enter;Cave entrance;8929
2442 10146 0 2523 3740 0 Climb;Steps;8966

# Isle of Stone
2465 4010 0 2461 10417 0 Enter;Cave;37433
2461 10417 0 2465 4010 0 Exit;Steps;37411
Expand Down Expand Up @@ -5195,4 +5252,7 @@
2763 2952 1 2763 2951 0 Climb-down;Ladder;16679
# woodcutting guild
1574 3483 1 1575 3483 0 Climb-down;Rope ladder;28858
1575 3483 0 1574 3483 1 Climb-up;Rope ladder;28857
1575 3483 0 1574 3483 1 Climb-up;Rope ladder;28857
#Grimstone Dungeon
2902 10454 0 2902 10456 0 Climb;Uneven stone ledges;60120
2902 10456 0 2902 10454 0 Climb;Uneven stone ledges;60120