Skip to content

Commit f2e5386

Browse files
committed
Merge remote-tracking branch 'origin/development' into development
2 parents 61c1a7c + f24ac9e commit f2e5386

File tree

6 files changed

+253
-34
lines changed

6 files changed

+253
-34
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package net.runelite.client.plugins.microbot.shortestpath;
2+
3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
import net.runelite.api.TileObject;
6+
import net.runelite.api.coords.WorldPoint;
7+
import net.runelite.client.plugins.microbot.util.player.Rs2Player;
8+
import net.runelite.client.plugins.microbot.util.widget.Rs2Widget;
9+
10+
import static net.runelite.client.plugins.microbot.util.Global.sleepUntil;
11+
12+
/**
13+
* Handles the Magic Mushtree (Mycelium Transportation System) on Fossil Island.
14+
* The mushtree network connects four locations:
15+
* - House on the Hill
16+
* - Verdant Valley
17+
* - Sticky Swamp
18+
* - Mushroom Meadow
19+
*/
20+
@Getter
21+
@RequiredArgsConstructor
22+
public enum MagicMushtree {
23+
HOUSE_ON_THE_HILL("House on the Hill", new WorldPoint(3764, 3879, 1)),
24+
VERDANT_VALLEY("Verdant Valley", new WorldPoint(3760, 3758, 0)),
25+
STICKY_SWAMP("Sticky Swamp", new WorldPoint(3676, 3755, 0)),
26+
MUSHROOM_MEADOW("Mushroom Meadow", new WorldPoint(3676, 3871, 0));
27+
28+
private final String destinationName;
29+
private final WorldPoint destination;
30+
31+
// Object IDs for the Magic Mushtrees
32+
public static final int MUSHTREE_HOUSE_ON_HILL = 30920;
33+
public static final int MUSHTREE_OTHER = 30924;
34+
35+
private static final int OFFSET = 10;
36+
37+
/**
38+
* Checks if the given object ID is a Magic Mushtree.
39+
*/
40+
public static boolean isMagicMushtree(int objectId) {
41+
return objectId == MUSHTREE_HOUSE_ON_HILL || objectId == MUSHTREE_OTHER;
42+
}
43+
44+
/**
45+
* Checks if the given TileObject is a Magic Mushtree.
46+
*/
47+
public static boolean isMagicMushtree(TileObject tileObject) {
48+
return tileObject != null && isMagicMushtree(tileObject.getId());
49+
}
50+
51+
/**
52+
* Handles the Magic Mushtree transport after the initial "Use" interaction.
53+
* Waits for the menu to appear, then clicks the appropriate destination.
54+
*
55+
* @param transport The transport containing the destination
56+
* @return true if the transport was handled successfully
57+
*/
58+
public static boolean handleTransport(Transport transport) {
59+
WorldPoint dest = transport.getDestination();
60+
MagicMushtree destination = getByDestination(dest);
61+
62+
if (destination == null) {
63+
return false;
64+
}
65+
66+
// Wait for the mushtree menu widget to appear
67+
if (!sleepUntil(() -> Rs2Widget.hasWidget("Mycelium"), 5000)) {
68+
return false;
69+
}
70+
71+
// Click the destination option
72+
if (!Rs2Widget.clickWidget(destination.getDestinationName())) {
73+
return false;
74+
}
75+
76+
// Wait until we arrive at destination
77+
sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo(dest) < OFFSET, 10000);
78+
return true;
79+
}
80+
81+
/**
82+
* Gets the MagicMushtree enum by destination WorldPoint.
83+
*/
84+
public static MagicMushtree getByDestination(WorldPoint destination) {
85+
if (destination == null) return null;
86+
87+
for (MagicMushtree mushtree : values()) {
88+
WorldPoint dest = mushtree.getDestination();
89+
if (dest.equals(destination)) {
90+
return mushtree;
91+
}
92+
// Also match by X and Y only (ignore plane differences in destination matching)
93+
if (dest.getX() == destination.getX() && dest.getY() == destination.getY()) {
94+
return mushtree;
95+
}
96+
}
97+
return null;
98+
}
99+
}

runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/bank/enums/BankLocation.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import net.runelite.api.gameval.VarbitID;
1212
import net.runelite.client.plugins.microbot.Microbot;
1313
import net.runelite.client.plugins.microbot.util.equipment.Rs2Equipment;
14+
import net.runelite.client.plugins.microbot.util.inventory.Rs2Inventory;
1415
import net.runelite.client.plugins.microbot.util.player.Rs2Player;
1516

1617
@Getter
@@ -38,6 +39,9 @@ public enum BankLocation {
3839
CRAFTING_GUILD(new WorldPoint(2936, 3281, 0), true),
3940
DARKFROST(new WorldPoint(1527, 3292, 0), true),
4041
DARKMEYER(new WorldPoint(3604, 3366, 0), true),
42+
DEEPFIN_POINT(new WorldPoint(1935, 2755,0), true),
43+
DEEPFIN_MINE_MID(new WorldPoint(2011, 9186,0), true),
44+
DEEPFIN_MINE_EAST(new WorldPoint(2094, 9197,0), true),
4145
DORGESH_KAAN_BANK(new WorldPoint(2702, 5350, 0), true),
4246
DRAYNOR_VILLAGE(new WorldPoint(3093, 3245, 0), false),
4347
DUEL_ARENA(new WorldPoint(3381, 3268, 0), true),
@@ -98,7 +102,8 @@ public enum BankLocation {
98102
SHILO_VILLAGE(new WorldPoint(2852, 2954, 0), true),
99103
SOPHANEM(new WorldPoint(2799, 5169, 0), true),
100104
SULPHUR_MINE(new WorldPoint(1453, 3858, 0), true),
101-
TAL_TEKLAN(new WorldPoint(1243, 3121, 0), true),
105+
SUNBLEAK_ISLAND(new WorldPoint(2195, 2314, 0), true),
106+
TAL_TEKLAN(new WorldPoint(1243, 3121, 0), true),
102107
TREE_GNOME_STRONGHOLD_NIEVE(new WorldPoint(2445, 3424, 1), true),
103108
TZHAAR(new WorldPoint(2446, 5178, 0), true),
104109
VARLAMORE_EAST(new WorldPoint(1780, 3094, 0), true),
@@ -128,7 +133,9 @@ public boolean hasRequirements() {
128133
boolean isWearingCraftingGuild = (Rs2Equipment.isWearing("brown apron") || Rs2Equipment.isWearing("golden apron")) ||
129134
(Rs2Equipment.isWearing("max cape") || Rs2Equipment.isWearing("max hood")) ||
130135
(Rs2Equipment.isWearing("crafting cape") || Rs2Equipment.isWearing("crafting hood"));
131-
return isWearingCraftingGuild && (hasMaxedCrafting || hasFaladorHardDiary);
136+
// Also check if crafting cape is in inventory (can equip it to teleport and enter)
137+
boolean hasCraftingCapeInInventory = Rs2Inventory.contains("crafting cape") || Rs2Inventory.contains("crafting cape(t)");
138+
return (isWearingCraftingGuild || hasCraftingCapeInInventory) && (hasMaxedCrafting || hasFaladorHardDiary);
132139
case LUMBRIDGE_BASEMENT:
133140
return Rs2Player.getQuestState(Quest.RECIPE_FOR_DISASTER__ANOTHER_COOKS_QUEST) == QuestState.FINISHED;
134141
case COOKS_GUILD:
@@ -259,6 +266,18 @@ public boolean hasRequirements() {
259266
case PRIFDDINAS_SOUTH:
260267
// Requires Song of the elves to be completed
261268
return Rs2Player.getQuestState(Quest.SONG_OF_THE_ELVES) == QuestState.FINISHED;
269+
case SUNBLEAK_ISLAND:
270+
// Requires sailing level 72
271+
return Rs2Player.getSkillRequirement(Skill.SAILING, 72, false);
272+
case DEEPFIN_POINT:
273+
// Requires sailing level 67
274+
return Rs2Player.getSkillRequirement(Skill.SAILING, 67, false);
275+
case DEEPFIN_MINE_MID:
276+
// Requires sailing level 67 + Bank to be made
277+
return Rs2Player.getSkillRequirement(Skill.SAILING, 67, false);
278+
case DEEPFIN_MINE_EAST:
279+
// Requires sailing level 67 + Bank to be made
280+
return Rs2Player.getSkillRequirement(Skill.SAILING, 67, false);
262281
default:
263282
return true;
264283
}

runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/poh/data/MountedDigsite.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public boolean execute() {
3535
return false;
3636
}
3737
if (pendant.getId() == objectId) {
38-
//The correct id for the object means it has the right left click option, so we can just use that.
38+
// The correct id for the object means it has the right left click option, so we can just use that.
3939
return Rs2GameObject.interact(pendant, destinationName);
4040
}
4141
Widget widget = getWidget();
@@ -49,6 +49,10 @@ public boolean execute() {
4949
return Rs2Widget.clickWidget(destinationName);
5050
}
5151

52+
private static Widget getWidget() {
53+
return Rs2Widget.getWidget(InterfaceID.MENU, 3);
54+
}
55+
5256
public static final Integer[] IDS = {ObjectID.POH_AMULET_DIGSITE, ObjectID.POH_AMULET_DIG_LITHKREN, ObjectID.POH_AMULET_DIG_FOSSIL, ObjectID.POH_AMULET_DIG_DIGSITE};
5357

5458
public static DecorativeObject getObject() {
@@ -63,10 +67,6 @@ public static boolean isMountedDigsite(DecorativeObject go) {
6367
return false;
6468
}
6569

66-
private static Widget getWidget() {
67-
return Rs2Widget.getWidget(InterfaceID.MENU, 3);
68-
}
69-
7070
@Override
7171
public String displayInfo() {
7272
return "MountedDigsite -> " + destinationName;

runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,9 +1605,8 @@ private static boolean handleTransports(List<WorldPoint> path, int indexOfStartP
16051605
}
16061606

16071607
if (object != null) {
1608-
System.out.println("Object Type: " + Rs2GameObject.getObjectType(object));
1609-
1610-
if (!(object instanceof GroundObject)) {
1608+
// Skip reachability check for GroundObjects and Magic Mushtrees
1609+
if (!(object instanceof GroundObject) && !MagicMushtree.isMagicMushtree(transport.getObjectId())) {
16111610
if (!Rs2Tile.isTileReachable(transport.getOrigin())) {
16121611
break;
16131612
}
@@ -1811,6 +1810,11 @@ private static boolean handleObjectExceptions(Transport transport, TileObject ti
18111810
sleepUntil(() -> Rs2Player.getWorldLocation().distanceTo2D(transport.getDestination()) < OFFSET, 10000);
18121811
return true;
18131812
}
1813+
1814+
// Handle Magic Mushtree (Fossil Island Mycelium Transportation System)
1815+
if (MagicMushtree.isMagicMushtree(tileObject)) {
1816+
return MagicMushtree.handleTransport(transport);
1817+
}
18141818
return false;
18151819
}
18161820

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

19261930
if (itemAction.equalsIgnoreCase("open") && itemId == ItemID.BOOKOFSCROLLS_CHARGED) {
19271931
return handleMasterScrollBook(destination);
1932+
} else if (isDialogueBasedTeleportItem(transport.getDisplayInfo())) {
1933+
// Multi-destination teleport items: wait for destination selection dialogue
1934+
Rs2Dialogue.sleepUntilSelectAnOption();
1935+
Rs2Dialogue.clickOption(destination);
1936+
log.info("Traveling to {} - ({})", transport.getDisplayInfo(), transport.getDestination());
1937+
return true;
1938+
} else if (transport.getDisplayInfo().toLowerCase().contains("burning amulet")) {
1939+
// Burning amulet in inventory: confirm wilderness teleport
1940+
Rs2Dialogue.sleepUntilInDialogue();
1941+
Rs2Dialogue.clickOption("Okay, teleport to level");
1942+
log.info("Traveling to {} - ({})", transport.getDisplayInfo(), transport.getDestination());
1943+
return true;
19281944
} else if (wildernessTransport) {
19291945
Rs2Dialogue.sleepUntilInDialogue();
19301946
return Rs2Dialogue.clickOption("Yes", "Okay");
@@ -1960,6 +1976,28 @@ private static boolean handleWearableTeleports(Transport transport, int itemId)
19601976
return false;
19611977
}
19621978

1979+
/**
1980+
* Checks if the teleport item requires dialogue-based destination selection.
1981+
* These are items that, when rubbed/activated, show a dialogue menu to choose destination.
1982+
*
1983+
* @param displayInfo the displayInfo from the transport
1984+
* @return true if the item requires dialogue handling
1985+
*/
1986+
private static boolean isDialogueBasedTeleportItem(String displayInfo) {
1987+
if (displayInfo == null) return false;
1988+
String lowerDisplayInfo = displayInfo.toLowerCase();
1989+
return lowerDisplayInfo.contains("slayer ring")
1990+
|| lowerDisplayInfo.contains("games necklace")
1991+
|| lowerDisplayInfo.contains("skills necklace")
1992+
|| lowerDisplayInfo.contains("ring of dueling")
1993+
|| lowerDisplayInfo.contains("ring of wealth")
1994+
|| lowerDisplayInfo.contains("amulet of glory")
1995+
|| lowerDisplayInfo.contains("combat bracelet")
1996+
|| lowerDisplayInfo.contains("digsite pendant")
1997+
|| lowerDisplayInfo.contains("necklace of passage")
1998+
|| lowerDisplayInfo.contains("giantsoul amulet");
1999+
}
2000+
19632001
/**
19642002
* Checks if the player's current location is within the specified area defined by the given world points.
19652003
*

runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/fairy_rings.tsv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
1651 3010 0 9650=1 5
5555
1359 2941 0 9650=1 5
5656
1429 3324 0 9650=1 5
57+
3178 2447 0 Troubled Tortugans 5
5758
2996 3114 0 5 AIQ
5859
2700 3247 0 5 AIR
5960
2328 4426 0 5 AIR DLR DJQ AJS
@@ -104,6 +105,8 @@
104105
3423 3016 0 5 DLQ
105106
2213 3099 0 5 DLR
106107
3447 9824 0 In Search of the Myreque 5 DLS
108+
3178 2447 0 Troubled Tortugans 5 CJQ
107109
1651 3010 0 9650=1 5 AJP
108110
1359 2941 0 9650=1 5 CKQ
109111
1429 3324 0 9650=1 5 AIS
112+
2926 10455 0 5 DLP

0 commit comments

Comments
 (0)