Skip to content
Open
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
29 changes: 28 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
.gradle
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

.idea
.gradle
out
.DS_Store
bin
build
.vscode
22 changes: 13 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,27 @@ repositories {
mavenCentral()
}

def runeLiteVersion = '1.7.5'
def runeLiteVersion = '1.8.18.4'
def joglVersion = '2.4.0-rc-20220318'

dependencies {
compileOnly group: 'net.runelite', name:'client', version: runeLiteVersion
compileOnly group: 'net.runelite.jogl', name:'jogl-gldesktop-dbg', version: joglVersion

compileOnly 'org.projectlombok:lombok:1.18.4'
annotationProcessor 'org.projectlombok:lombok:1.18.4'
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'

testImplementation 'junit:junit:4.12'
testImplementation 'org.slf4j:slf4j-simple:1.7.12'
testImplementation group: 'net.runelite', name:'client', version: runeLiteVersion, {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
testImplementation 'junit:junit:4.12'
testImplementation group: 'net.runelite', name:'client', version: runeLiteVersion
testImplementation group: 'net.runelite', name:'jshell', version: runeLiteVersion
testImplementation group: 'net.runelite.jogl', name:'jogl-gldesktop-dbg', version: joglVersion

testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
}

group = 'shortestpath'
version = '1.2'
version = '1.9'
sourceCompatibility = '1.8'

tasks.withType(JavaCompile) {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#Thu Oct 08 20:51:56 EDT 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
Expand Down
Empty file modified gradlew
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions src/main/java/shortestpath/PathMapOverlay.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public Dimension render(Graphics2D graphics) {
continue;
}

for (WorldPoint b : plugin.transports.get(a)) {
Point mapB = worldMapOverlay.mapWorldPointToGraphicsPoint(b);
for (Transport b : plugin.transports.get(a)) {
Point mapB = worldMapOverlay.mapWorldPointToGraphicsPoint(b.getOrigin());
if (mapB == null) {
continue;
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/shortestpath/PathTileOverlay.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ public Dimension render(Graphics2D graphics) {
continue;
}

for (WorldPoint b : plugin.transports.get(a)) {
Point cb = tileCenter(b);
for (Transport b : plugin.transports.get(a)) {
Point cb = tileCenter(b.getOrigin());

if (cb != null) {
graphics.drawLine(ca.x, ca.y, cb.x, cb.y);
}
}

StringBuilder s = new StringBuilder();
for (WorldPoint b : plugin.transports.get(a)) {
if (b.getPlane() > a.getPlane()) {
for (Transport b : plugin.transports.get(a)) {
if (b.getOrigin().getPlane() > a.getPlane()) {
s.append("+");
} else if (b.getPlane() < a.getPlane()) {
} else if (b.getOrigin().getPlane() < a.getPlane()) {
s.append("-");
} else {
s.append("=");
Expand Down
30 changes: 18 additions & 12 deletions src/main/java/shortestpath/ShortestPathPlugin.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package shortestpath;

import com.google.inject.Provides;

import net.runelite.api.Point;
import net.runelite.api.*;
import net.runelite.api.coords.WorldArea;
Expand Down Expand Up @@ -65,7 +66,7 @@ public class ShortestPathPlugin extends Plugin {
public WorldMapPoint marker;
private static final BufferedImage MARKER_IMAGE = ImageUtil.getResourceStreamFromClass(ShortestPathPlugin.class, "/marker.png");
public boolean pathUpdateScheduled = false;
public final Map<WorldPoint, List<WorldPoint>> transports = new HashMap<>();
public final Map<WorldPoint, List<Transport>> transports = new HashMap<>();
public Pathfinder pathfinder;
private WorldPoint transportStart;
private MenuOptionClicked lastClick;
Expand Down Expand Up @@ -93,18 +94,21 @@ protected void startUp() {
try {
String s = new String(Util.readAllBytes(ShortestPathPlugin.class.getResourceAsStream("/transports.txt")), StandardCharsets.UTF_8);
Scanner scanner = new Scanner(s);

while (scanner.hasNextLine()) {
String line = scanner.nextLine();

if (line.startsWith("#") || line.isEmpty()) {
continue;
}

String[] l = line.split(" ");
WorldPoint a = new WorldPoint(Integer.parseInt(l[0]), Integer.parseInt(l[1]), Integer.parseInt(l[2]));
WorldPoint b = new WorldPoint(Integer.parseInt(l[3]), Integer.parseInt(l[4]), Integer.parseInt(l[5]));
transports.computeIfAbsent(a, k -> new ArrayList<>()).add(b);
Transport transport = new Transport(line);
WorldPoint origin = transport.getOrigin();

transports.computeIfAbsent(origin, k-> new ArrayList<>()).add(transport);
}

scanner.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand All @@ -117,7 +121,8 @@ protected void startUp() {
if (target == null) {
path = null;
} else {
pathfinder = new Pathfinder(map, transports, client.getLocalPlayer().getWorldLocation(), target, config.avoidWilderness() && !isInWilderness(target));
int agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY);
pathfinder = new Pathfinder(map, transports, client.getLocalPlayer().getWorldLocation(), target, config.avoidWilderness() && !isInWilderness(target), agilityLevel);
path = pathfinder.find();
pathUpdateScheduled = false;
}
Expand Down Expand Up @@ -206,11 +211,14 @@ public void onMenuOptionClicked(MenuOptionClicked event) {

if (event.getMenuOption().equals("End")) {
WorldPoint transportEnd = client.getLocalPlayer().getWorldLocation();

System.out.println(transportStart.getX() + " " + transportStart.getY() + " " + transportStart.getPlane() + " " +
transportEnd.getX() + " " + transportEnd.getY() + " " + transportEnd.getPlane() + " " +
lastClick.getMenuOption() + " " + Text.removeTags(lastClick.getMenuTarget()) + " " + lastClick.getId()
);
transports.computeIfAbsent(transportStart, k -> new ArrayList<>()).add(transportEnd);

Transport transport = new Transport(transportStart, transportEnd);
transports.computeIfAbsent(transportStart, k -> new ArrayList<>()).add(transport);
}

if (event.getMenuOption().equals("Copy Position")) {
Expand Down Expand Up @@ -242,6 +250,7 @@ private void setTarget(WorldPoint target) {
marker = new WorldMapPoint(target, MARKER_IMAGE);
marker.setTarget(marker.getWorldPoint());
marker.setJumpOnClick(true);
marker.setName("Shortest Path");
worldMapPointManager.add(marker);
}
}
Expand Down Expand Up @@ -270,12 +279,9 @@ private void addMenuEntry(MenuEntryAdded event, String option) {
return;
}

MenuEntry entry = new MenuEntry();
MenuEntry entry = client.createMenuEntry(0);
entry.setOption(option);
entry.setTarget(event.getTarget());
entry.setType(MenuAction.RUNELITE.getId());
entries.add(0, entry);

client.setMenuEntries(entries.toArray(new MenuEntry[0]));
entry.setType(MenuAction.RUNELITE);
}
}
65 changes: 65 additions & 0 deletions src/main/java/shortestpath/Transport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package shortestpath;
import net.runelite.api.coords.WorldPoint;


/**
* This class represents a travel point between two WorldPoints.
*/
public class Transport {
/** The starting point of this transport */
private final WorldPoint origin;
/** The ending point of this transport */
private final WorldPoint destination;
/** The agility level required to use transport */
private final int agilityLevelRequired;

Transport(final String line) {
String[] spaceSplit = line.split(" ");

origin = new WorldPoint(Integer.parseInt(spaceSplit[0]), Integer.parseInt(spaceSplit[1]), Integer.parseInt(spaceSplit[2]));
destination = new WorldPoint(Integer.parseInt(spaceSplit[3]), Integer.parseInt(spaceSplit[4]), Integer.parseInt(spaceSplit[5]));

int agilityLevel = 1;

if (line.contains("Agility")) {
// Agility comments are in this for "NN Agility, <etc>" where NN is the level required
String[] quoteSplit = line.split("\"");

assert(quoteSplit.length == 2);

// There is only one comment per line, always at the end
String[] splitComment = quoteSplit[1].replace("\"", "").split(" ");
String level = splitComment[0];

try {
agilityLevel = Integer.parseInt(level);
} catch (Exception e) {
System.out.println("e: " + e.getMessage());
}
}

agilityLevelRequired = agilityLevel;
}

Transport(final WorldPoint origin, final WorldPoint destination, int agilityLevelRequired) {
this.origin = origin;
this.destination = destination;
this.agilityLevelRequired = agilityLevelRequired;
}

Transport(final WorldPoint origin, final WorldPoint destination) {
this(origin, destination, 0);
}

public WorldPoint getOrigin() {
return origin;
}

public WorldPoint getDestination() {
return destination;
}

public int getAgilityLevelRequired() {
return agilityLevelRequired;
}
}
40 changes: 27 additions & 13 deletions src/main/java/shortestpath/pathfinder/Pathfinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.runelite.api.coords.WorldPoint;
import shortestpath.ShortestPathPlugin;
import shortestpath.Transport;

import java.util.*;

Expand All @@ -11,17 +12,19 @@ public class Pathfinder {
private final WorldPoint target;
private final List<Node> boundary = new LinkedList<>();
private final Set<WorldPoint> visited = new HashSet<>();
private final Map<WorldPoint, List<WorldPoint>> transports;
private final Map<WorldPoint, List<Transport>> transports;
private final boolean avoidWilderness;
private Node nearest;
private final int agilityLevel;

public Pathfinder(CollisionMap map, Map<WorldPoint, List<WorldPoint>> transports, WorldPoint start, WorldPoint target, boolean avoidWilderness) {
public Pathfinder(CollisionMap map, Map<WorldPoint, List<Transport>> transports, WorldPoint start, WorldPoint target, boolean avoidWilderness, int agilityLevel) {
this.map = map;
this.transports = transports;
this.target = target;
this.start = new Node(start, null);
this.avoidWilderness = avoidWilderness;
nearest = null;
this.agilityLevel = agilityLevel;
}

public List<WorldPoint> find() {
Expand All @@ -32,24 +35,34 @@ public List<WorldPoint> find() {
while (!boundary.isEmpty()) {
Node node = boundary.remove(0);

// if we are on the target block, return a path to this block
if (node.position.equals(target)) {
return node.path();
}

int distance = Math.max(Math.abs(node.position.getX() - target.getX()), Math.abs(node.position.getY() - target.getY()));
// add all the neighbouring blocks to this node to the graph
addNeighbors(node);

int distance = node.position.distanceTo2D(target);

if (nearest == null || distance < bestDistance) {
nearest = node;
bestDistance = distance;
}

addNeighbors(node);
}

if (nearest != null) {
return nearest.path();
// Check this node for valid transports
for (Transport transport : transports.getOrDefault(node.position, new ArrayList<>())) {
if (canPlayerUseTransport(transport)) {
addNeighbor(node, transport.getOrigin());
addNeighbor(node, transport.getDestination());
} else if (bestDistance == distance) {
// Player cannot use this tile, push out the bestDistance to allow selection of a new node
bestDistance += 1;
}
}
}

return null;
return currentBest();
}

private void addNeighbors(Node node) {
Expand Down Expand Up @@ -84,14 +97,15 @@ private void addNeighbors(Node node) {
if (map.ne(node.position.getX(), node.position.getY(), node.position.getPlane())) {
addNeighbor(node, new WorldPoint(node.position.getX() + 1, node.position.getY() + 1, node.position.getPlane()));
}
}

for (WorldPoint transport : transports.getOrDefault(node.position, new ArrayList<>())) {
addNeighbor(node, transport);
}
private boolean canPlayerUseTransport(Transport transport) {
// Currently, only supports agility level check
return agilityLevel >= transport.getAgilityLevelRequired();
}

public List<WorldPoint> currentBest() {
return nearest==null ? null : nearest.path();
return nearest == null ? null : nearest.path();
}

private void addNeighbor(Node node, WorldPoint neighbor) {
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/transports.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3884,3 +3884,6 @@
# Karamja
2910 3049 0 2906 3049 0 Cross A wooden log 23644
2906 3049 0 2910 3049 0 Cross A wooden log 23644

# Feldip Hills
2546 2873 0 2546 2871 0 Climb Rocks 31757 "10 Agility"