Skip to content

Commit 6d0ccd0

Browse files
authored
Merge pull request #1763 from chsami/development
fix(build): bump project version to 1.12.26.2
2 parents af640e3 + 98e1cfe commit 6d0ccd0

4 files changed

Lines changed: 235 additions & 87 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ project.build.group=net.runelite
3131
project.build.version=1.12.26.2
3232

3333
glslang.path=
34-
microbot.version=2.5.5
34+
microbot.version=2.5.6
3535
microbot.commit.sha=nogit
3636
microbot.repo.url=http://138.201.81.246:8081/repository/microbot-snapshot/
3737
microbot.repo.username=

runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/mouse/VirtualMouse.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,18 @@ private void handleClick(Point point, boolean rightClick) {
112112
clicked(point, rightClick ? MouseEvent.BUTTON3 : MouseEvent.BUTTON1);
113113
setLastClick(point);
114114
}
115+
116+
private boolean shouldMoveNaturally(Point point) {
117+
return point.getX() > 1
118+
&& point.getY() > 1
119+
&& Microbot.naturalMouse != null;
120+
}
121+
115122
public Mouse click(Point point, boolean rightClick) {
116123
if (point == null) return this;
117124

118125
Runnable clickAction = () -> {
119-
if (point.getX() > 1 && point.getY() > 1 && Microbot.naturalMouse != null) {
126+
if (shouldMoveNaturally(point)) {
120127
Microbot.naturalMouse.moveTo(point.getX(), point.getY());
121128
}
122129
handleClick(point, rightClick);
@@ -137,7 +144,7 @@ public Mouse click(Point point, boolean rightClick, NewMenuEntry entry) {
137144

138145
Runnable clickAction = () -> {
139146
Point newPoint = point;
140-
if (point.getX() > 1 && point.getY() > 1 && Microbot.naturalMouse != null) {
147+
if (shouldMoveNaturally(point)) {
141148
Microbot.naturalMouse.moveTo(point.getX(), point.getY());
142149

143150
if (Rs2UiHelper.hasActor(entry)) {
@@ -287,14 +294,14 @@ public void shutdown() {
287294
public Mouse drag(Point startPoint, Point endPoint) {
288295
if (startPoint == null || endPoint == null) return this;
289296

290-
if (startPoint.getX() > 1 && startPoint.getY() > 1 && Microbot.naturalMouse != null)
297+
if (shouldMoveNaturally(startPoint))
291298
Microbot.naturalMouse.moveTo(startPoint.getX(), startPoint.getY());
292299
else
293300
move(startPoint);
294301
sleep(Rs2Random.logNormalBounded(50, 80));
295302
pressed(startPoint, MouseEvent.BUTTON1);
296303
sleep(Rs2Random.logNormalBounded(80, 120));
297-
if (endPoint.getX() > 1 && endPoint.getY() > 1 && Microbot.naturalMouse != null)
304+
if (shouldMoveNaturally(endPoint))
298305
Microbot.naturalMouse.moveTo(endPoint.getX(), endPoint.getY());
299306
else
300307
move(endPoint);

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

Lines changed: 195 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,62 +1491,162 @@ private static boolean handleDoors(List<WorldPoint> path, int index) {
14911491
TileObject object = (wall != null)
14921492
? wall
14931493
: Rs2GameObject.getGameObject(o -> o.getWorldLocation().equals(probe), probe, 3);
1494-
if (object == null) continue;
1494+
if (tryHandleDoorObject(object, probe, fromWp, toWp, doorActions, false)) {
1495+
return true;
1496+
}
1497+
}
1498+
}
14951499

1496-
ObjectComposition comp = Rs2GameObject.convertToObjectComposition(object);
1497-
// Ignore imposter objects
1498-
if (comp == null || comp.getImpostorIds() != null || comp.getName().equals("null")) continue;
1500+
TileObject nearbyDoor = findDoorNearSegment(fromWp, toWp, doorActions);
1501+
if (nearbyDoor != null && tryHandleDoorObject(nearbyDoor, nearbyDoor.getWorldLocation(), fromWp, toWp, doorActions, true)) {
1502+
return true;
1503+
}
14991504

1500-
String action = Arrays.stream(comp.getActions())
1501-
.filter(Objects::nonNull)
1502-
.filter(act -> doorActions.stream().anyMatch(dact -> act.toLowerCase().startsWith(dact.toLowerCase())))
1503-
.min(Comparator.comparing(act -> doorActions.indexOf(doorActions.stream().filter(dact -> act.toLowerCase().startsWith(dact)).findFirst().orElse(""))))
1504-
.orElse(null);
1505+
return false;
1506+
}
15051507

1506-
if (action == null) continue;
1508+
private static TileObject findDoorNearSegment(WorldPoint fromWp, WorldPoint toWp, List<String> doorActions) {
1509+
WorldPoint playerLoc = Rs2Player.getWorldLocation();
1510+
if (playerLoc == null || fromWp == null || toWp == null || fromWp.getPlane() != toWp.getPlane()) {
1511+
return null;
1512+
}
15071513

1508-
boolean found = false;
1514+
final int searchDistance = 10;
1515+
return Rs2GameObject.getAll(o -> {
1516+
if (o == null || o.getWorldLocation() == null) return false;
1517+
WorldPoint loc = o.getWorldLocation();
1518+
if (loc.getPlane() != playerLoc.getPlane()) return false;
1519+
if (loc.distanceTo2D(playerLoc) > searchDistance) return false;
1520+
if (sessionBlacklistedDoors.contains(loc)) return false;
1521+
if (!(o instanceof WallObject) && !(o instanceof GameObject)) return false;
1522+
ObjectComposition comp = Rs2GameObject.convertToObjectComposition(o);
1523+
if (!isDoorComposition(comp, doorActions)) return false;
1524+
return isDoorOnSegment(o, fromWp, toWp);
1525+
}, playerLoc, searchDistance).stream()
1526+
.min(Comparator.comparingInt(o -> o.getWorldLocation().distanceTo2D(playerLoc)))
1527+
.orElse(null);
1528+
}
15091529

1510-
final String name = comp.getName();
1530+
private static boolean tryHandleDoorObject(TileObject object, WorldPoint probe, WorldPoint fromWp, WorldPoint toWp,
1531+
List<String> doorActions, boolean allowSegmentProbe) {
1532+
if (object == null || probe == null) return false;
15111533

1512-
if (object instanceof WallObject) {
1513-
int orientation = ((WallObject) object).getOrientationA();
1534+
ObjectComposition comp = Rs2GameObject.convertToObjectComposition(object);
1535+
if (!isDoorComposition(comp, doorActions)) return false;
15141536

1515-
if (searchNeighborPoint(orientation, probe, fromWp) || searchNeighborPoint(orientation, probe, toWp)) {
1516-
log.info("Found WallObject door - name {} with action {} at {} - from {} to {}", name, action, probe, fromWp, toWp);
1517-
found = true;
1518-
}
1519-
} else {
1520-
if (name != null && name.toLowerCase().contains("door")) {
1521-
log.info("Found GameObject door - name {} with action {} at {} - from {} to {}", name, action, probe, fromWp, toWp);
1522-
found = true;
1523-
}
1524-
}
1537+
String action = getDoorAction(comp, doorActions);
1538+
if (action == null) return false;
15251539

1526-
if (found) {
1527-
if (!handleDoorException(object, action)) {
1528-
WorldPoint posBefore = Rs2Player.getWorldLocation();
1529-
Rs2GameObject.interact(object, action);
1530-
Rs2Player.waitForWalking();
1531-
WorldPoint posAfter = Rs2Player.getWorldLocation();
1532-
boolean moved = posBefore != null && posAfter != null && !posBefore.equals(posAfter);
1533-
if (!moved && isQuestLockedDoorDialogue()) {
1534-
String dialogue = Rs2Dialogue.getDialogueText();
1535-
log.warn("[Walker] Door at {} ({} action={}) appears quest/stat-locked — dialogue=\"{}\" — blacklisting tile, refreshing restrictions, recalculating",
1536-
probe, name, action, dialogue);
1537-
sessionBlacklistedDoors.add(probe);
1538-
Rs2Dialogue.clickContinue();
1539-
if (ShortestPathPlugin.pathfinderConfig != null) {
1540-
ShortestPathPlugin.pathfinderConfig.refresh();
1541-
}
1542-
recalculatePath();
1543-
}
1544-
}
1545-
return true;
1540+
boolean found = false;
1541+
final String name = comp.getName();
1542+
1543+
if (object instanceof WallObject) {
1544+
int orientation = ((WallObject) object).getOrientationA();
1545+
1546+
if (searchNeighborPoint(orientation, probe, fromWp)
1547+
|| searchNeighborPoint(orientation, probe, toWp)
1548+
|| (allowSegmentProbe && wallDoorTouchesSegment((WallObject) object, fromWp, toWp))) {
1549+
log.info("Found WallObject door - name {} with action {} at {} - from {} to {}", name, action, probe, fromWp, toWp);
1550+
found = true;
1551+
}
1552+
} else if (name != null && name.toLowerCase().contains("door")) {
1553+
log.info("Found GameObject door - name {} with action {} at {} - from {} to {}", name, action, probe, fromWp, toWp);
1554+
found = true;
1555+
}
1556+
1557+
if (!found) return false;
1558+
1559+
if (!handleDoorException(object, action)) {
1560+
WorldPoint posBefore = Rs2Player.getWorldLocation();
1561+
Rs2GameObject.interact(object, action);
1562+
Rs2Player.waitForWalking();
1563+
WorldPoint posAfter = Rs2Player.getWorldLocation();
1564+
boolean moved = posBefore != null && posAfter != null && !posBefore.equals(posAfter);
1565+
if (!moved && isQuestLockedDoorDialogue()) {
1566+
String dialogue = Rs2Dialogue.getDialogueText();
1567+
log.warn("[Walker] Door at {} ({} action={}) appears quest/stat-locked — dialogue=\"{}\" — blacklisting tile, refreshing restrictions, recalculating",
1568+
probe, name, action, dialogue);
1569+
sessionBlacklistedDoors.add(probe);
1570+
Rs2Dialogue.clickContinue();
1571+
if (ShortestPathPlugin.pathfinderConfig != null) {
1572+
ShortestPathPlugin.pathfinderConfig.refresh();
15461573
}
1574+
recalculatePath();
1575+
}
1576+
}
1577+
return true;
1578+
}
1579+
1580+
private static boolean isDoorComposition(ObjectComposition comp, List<String> doorActions) {
1581+
if (comp == null || comp.getImpostorIds() != null || comp.getName().equals("null") || comp.getActions() == null) {
1582+
return false;
1583+
}
1584+
return getDoorAction(comp, doorActions) != null;
1585+
}
1586+
1587+
private static String getDoorAction(ObjectComposition comp, List<String> doorActions) {
1588+
if (comp == null || comp.getActions() == null) {
1589+
return null;
1590+
}
1591+
return Arrays.stream(comp.getActions())
1592+
.filter(Objects::nonNull)
1593+
.filter(act -> doorActions.stream().anyMatch(dact -> act.toLowerCase().startsWith(dact.toLowerCase())))
1594+
.min(Comparator.comparing(act -> doorActions.indexOf(doorActions.stream()
1595+
.filter(dact -> act.toLowerCase().startsWith(dact))
1596+
.findFirst()
1597+
.orElse(""))))
1598+
.orElse(null);
1599+
}
1600+
1601+
private static boolean isDoorOnSegment(TileObject object, WorldPoint fromWp, WorldPoint toWp) {
1602+
if (object == null || object.getWorldLocation() == null) return false;
1603+
if (object instanceof WallObject) {
1604+
return wallDoorTouchesSegment((WallObject) object, fromWp, toWp)
1605+
|| isPointNearSegment(object.getWorldLocation(), fromWp, toWp, 1);
1606+
}
1607+
return isPointNearSegment(object.getWorldLocation(), fromWp, toWp, 1);
1608+
}
1609+
1610+
private static boolean wallDoorTouchesSegment(WallObject wall, WorldPoint fromWp, WorldPoint toWp) {
1611+
if (wall == null || wall.getWorldLocation() == null || fromWp == null || toWp == null) return false;
1612+
if (wall.getWorldLocation().getPlane() != fromWp.getPlane() || fromWp.getPlane() != toWp.getPlane()) return false;
1613+
1614+
int orientation = wall.getOrientationA();
1615+
int x = fromWp.getX();
1616+
int y = fromWp.getY();
1617+
int steps = 0;
1618+
while (steps++ <= 64) {
1619+
WorldPoint point = new WorldPoint(x, y, fromWp.getPlane());
1620+
if (searchNeighborPoint(orientation, wall.getWorldLocation(), point)) {
1621+
return true;
1622+
}
1623+
if (x == toWp.getX() && y == toWp.getY()) {
1624+
return false;
15471625
}
1626+
x += Integer.signum(toWp.getX() - x);
1627+
y += Integer.signum(toWp.getY() - y);
15481628
}
1629+
return false;
1630+
}
15491631

1632+
private static boolean isPointNearSegment(WorldPoint point, WorldPoint fromWp, WorldPoint toWp, int distance) {
1633+
if (point == null || fromWp == null || toWp == null || point.getPlane() != fromWp.getPlane() || fromWp.getPlane() != toWp.getPlane()) {
1634+
return false;
1635+
}
1636+
1637+
int x = fromWp.getX();
1638+
int y = fromWp.getY();
1639+
int steps = 0;
1640+
while (steps++ <= 64) {
1641+
if (point.distanceTo2D(new WorldPoint(x, y, fromWp.getPlane())) <= distance) {
1642+
return true;
1643+
}
1644+
if (x == toWp.getX() && y == toWp.getY()) {
1645+
return false;
1646+
}
1647+
x += Integer.signum(toWp.getX() - x);
1648+
y += Integer.signum(toWp.getY() - y);
1649+
}
15501650
return false;
15511651
}
15521652

@@ -2091,20 +2191,29 @@ private static boolean handleTransports(List<WorldPoint> path, int indexOfStartP
20912191
List<TileObject> objects = Rs2GameObject.getAll(o -> {
20922192
if (o.getId() == transportObjectId) return true;
20932193
Integer legacyClosed = OPEN_TO_CLOSED_MAPPINGS.get(transportObjectId);
2094-
if (legacyClosed != null && o.getId() == legacyClosed) return true;
2095-
if (!allowClosedVariant) return false;
2096-
ObjectComposition comp = Rs2GameObject.convertToObjectComposition(o);
2097-
if (comp == null || comp.getActions() == null) return false;
2098-
String nm = comp.getName() == null ? "" : comp.getName().toLowerCase();
2099-
boolean nameMatches = nm.contains("trapdoor") || nm.contains("manhole")
2100-
|| nm.contains("grate") || nm.contains("hatch");
2101-
if (!nameMatches) return false;
2102-
return Arrays.stream(comp.getActions()).filter(Objects::nonNull)
2103-
.anyMatch(a -> a.equalsIgnoreCase("Open"));
2194+
return legacyClosed != null && o.getId() == legacyClosed;
21042195
}, transport.getOrigin(), 10).stream()
21052196
.sorted(Comparator.comparingInt(o -> o.getWorldLocation().distanceTo(transport.getOrigin())))
21062197
.collect(Collectors.toList());
21072198

2199+
if (objects.isEmpty() && allowClosedVariant) {
2200+
// The closed-variant fallback needs object composition lookups for name/action
2201+
// matching. Keep it off the common exact-id path; doing this for every
2202+
// climb-down object was the Varrock staircase delay.
2203+
objects = Rs2GameObject.getAll(o -> {
2204+
ObjectComposition comp = Rs2GameObject.convertToObjectComposition(o);
2205+
if (comp == null || comp.getActions() == null) return false;
2206+
String nm = comp.getName() == null ? "" : comp.getName().toLowerCase();
2207+
boolean nameMatches = nm.contains("trapdoor") || nm.contains("manhole")
2208+
|| nm.contains("grate") || nm.contains("hatch");
2209+
if (!nameMatches) return false;
2210+
return Arrays.stream(comp.getActions()).filter(Objects::nonNull)
2211+
.anyMatch(a -> a.equalsIgnoreCase("Open"));
2212+
}, transport.getOrigin(), 10).stream()
2213+
.sorted(Comparator.comparingInt(o -> o.getWorldLocation().distanceTo(transport.getOrigin())))
2214+
.collect(Collectors.toList());
2215+
}
2216+
21082217
TileObject object = objects.stream().findFirst().orElse(null);
21092218
if (object instanceof GroundObject) {
21102219
object = objects.stream()
@@ -2150,7 +2259,10 @@ private static boolean handleTransports(List<WorldPoint> path, int indexOfStartP
21502259
}
21512260
}
21522261

2153-
handleObject(transport, object);
2262+
prepareTransportObjectForInteraction(object);
2263+
if (!handleObject(transport, object)) {
2264+
return false;
2265+
}
21542266
sleepUntil(() -> !Rs2Player.isAnimating());
21552267
return sleepUntilTrue(() -> Rs2Player.getWorldLocation().distanceTo(transport.getDestination()) < OFFSET);
21562268
}
@@ -2174,9 +2286,19 @@ private static boolean handlePohTransport(Transport transport) {
21742286
return ((PohTransport)transport).execute();
21752287
}
21762288

2177-
private static void handleObject(Transport transport, TileObject tileObject) {
2289+
private static void prepareTransportObjectForInteraction(TileObject tileObject) {
2290+
if (tileObject == null || tileObject.getLocalLocation() == null) {
2291+
return;
2292+
}
2293+
if (!Rs2Camera.isTileOnScreen(tileObject)) {
2294+
Rs2Camera.turnTo(tileObject);
2295+
sleepUntil(() -> Rs2Camera.isTileOnScreen(tileObject), 1200);
2296+
}
2297+
}
2298+
2299+
private static boolean handleObject(Transport transport, TileObject tileObject) {
21782300
Rs2GameObject.interact(tileObject, transport.getAction());
2179-
if (handleObjectExceptions(transport, tileObject)) return;
2301+
if (handleObjectExceptions(transport, tileObject)) return true;
21802302
if (transport.getDestination().getPlane() == Rs2Player.getWorldLocation().getPlane()) {
21812303
if (transport.getType() == TransportType.AGILITY_SHORTCUT) {
21822304
Rs2Player.waitForAnimation();
@@ -2194,10 +2316,23 @@ private static void handleObject(Transport transport, TileObject tileObject) {
21942316
Rs2Player.waitForWalking();
21952317
Rs2Dialogue.clickOption("Yes please"); //shillo village cart
21962318
}
2319+
return true;
21972320
} else {
21982321
int z = Rs2Player.getWorldLocation().getPlane();
2199-
sleepUntil(() -> Rs2Player.getWorldLocation().getPlane() != z);
2200-
sleep((int) Rs2Random.gaussRand(1000.0, 300.0));
2322+
boolean started = sleepUntil(() -> Rs2Player.getWorldLocation().getPlane() != z
2323+
|| Rs2Player.isMoving()
2324+
|| Rs2Player.isAnimating(), 1800);
2325+
if (!started) {
2326+
log.debug("[Walker] {} transport click on {} produced no movement/animation; retrying",
2327+
transport.getAction(), tileObject.getId());
2328+
return false;
2329+
}
2330+
boolean planeChanged = Rs2Player.getWorldLocation().getPlane() != z
2331+
|| sleepUntil(() -> Rs2Player.getWorldLocation().getPlane() != z, 5000);
2332+
if (planeChanged) {
2333+
sleep((int) Rs2Random.gaussRand(300.0, 120.0));
2334+
}
2335+
return planeChanged;
22012336
}
22022337
}
22032338

@@ -2608,7 +2743,7 @@ public static boolean isNearPath() {
26082743
final WorldPoint loc = Rs2Player.getWorldLocation();
26092744
if (loc == null) return true;
26102745

2611-
if (config.recalculateDistance() < 0 || lastPosition.equals(lastPosition = loc)) {
2746+
if (config.recalculateDistance() < 0) {
26122747
return true;
26132748
}
26142749

@@ -4463,4 +4598,3 @@ public static boolean closeWorldMap() {
44634598
return sleepUntil(() -> !Rs2Widget.isWidgetVisible(InterfaceID.Worldmap.CLOSE), 3000);
44644599
}
44654600
}
4466-

0 commit comments

Comments
 (0)