SRL Archive - Senior Scripts and Snippets

New Tilewalking Idea


Smartzkid

2008-08-21 20:05:09

Well, let me start off, this isn't at all my idea, I was just looking at Sum's pathmaker (gj, sum!), and it reminded me of a thread I saw at RSBot.

http://rsbot.com/smf/index.php?topic=9826.msg83227#msg83227

Basically, map out (by hand; it really isn't that bad, if you do it in small increments) all of RS with this web - a walkable mesh. Add 1 or 2 tolerance to every tile, and you can walk anywhere using a nearly infinite many paths.

EDIT: More code, for anyone interested. http://pastebin.ubuntu.com/39593/ :

import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import com.speljohan.rsbot.script.*;
import com.speljohan.rsbot.bot.*;
import com.speljohan.rsbot.script.wrappers.*;
import com.speljohan.rsbot.event.listeners.*;
import com.speljohan.rsbot.event.events.*;
import java.awt.event.KeyEvent;
import java.applet.Applet;
import com.speljohan.rsbot.plugin.NonPluginClass;

public class BotArmy extends Script {
RSTile[] path;
public String getName() {
return "Bot Army";
}
public double getVersion() {
return 2.1;
}
public String getAuthor() {
return "Mike";
}
public String getScriptCategory() {
return "Mike's Scripts";
}
public String getScriptDescription() {
return "<html>\n" +
"<head></head>\n" +
"<body>\n" +
"<center>" +
"<h2>" + getName() + "</h2>" +
"</center>\n" +
"<b>Author:</b> " + getAuthor() + "<br/>\n" +
"<b>Version:</b> " + getVersion() + "<br/>\n" +
"<br/>\n" +
"<b>Starting Location:</b> Tutorial island/Lumbridge<br/>" +
"<b>Function:</b> Will do 'Learning The Ropes' then train your stats to the desired levels." +
"<br/>" +
"<b>Version Notes:</b> " +
"<ul>" +
"<li>" +
"<li>" +
"<b>0.*:</b> Beta Versions" +
"</li>" +

"</ul>" +
"</body>\n" +
"</html>";
}
public boolean onStart(String[] args) {
nodes = new ArrayList<MapNode>();
links = new ArrayList<MapLink>();
loadMap();
path = generateProperPath(3253, 3401);
return true;
}
public int loop() {
try {
if(getMyPlayer().isMoving())
return random(300,500);
if(walkPathMM(randomizePath(path,2,2),17))
return -1;
} catch(Exception e) {
}
return random(300,500);
}

static List nodes, links;
int nodeCount = 0;
int[][] pathFound = null;
int[][] mapPath = null;

public RSTile[] generateProperPath(int x, int y) {
try {
ArrayList<RSTile> list = new ArrayList<RSTile>();
int[][] test = findPath(getLocation().getX(), getLocation().getY(), x,y);
for(int i=0; i<test.length; i++)
list.add(new RSTile(test[i][0], test[i][1]));
return list.toArray(new RSTile[list.size()]);
} catch(Exception e){
e.printStackTrace();
}
return null;
}
private void loadMap() {
try {
FileReader fileReader = new FileReader("Scripts\\nodes.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while((line = bufferedReader.readLine()) != null) {
String[] thisLine = line.split("\t");
addNode(Integer.parseInt(thisLine[0]), Integer.parseInt(thisLine[1]), Integer.parseInt(thisLine[2]));
}
bufferedReader.close();

} catch (Exception e) {
System.out.println("error loading nodes");
}
try {
FileReader fileReader = new FileReader("Scripts\\links.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while((line = bufferedReader.readLine()) != null) {
String[] thisLine = line.split("\t");
addLinkIndex(Integer.parseInt(thisLine[0]), Integer.parseInt(thisLine[1]));
}
bufferedReader.close();

} catch (Exception e) {
System.out.println("error loading links");
}
}


private void addNode(int x, int y) throws Exception {
try {
nodes.add(new MapNode(x, y, nodeCount++));
} catch(Exception e){
e.printStackTrace();
}
}
private void addNode(int x, int y, int index) {
try {
nodes.add(new MapNode(x, y, index));
nodeCount = index + 1;
} catch(Exception e){
e.printStackTrace();
}
}

private void addLink(int start, int end) {
try {
start = getIndex(start);
end = getIndex(end);
for(int i = 0; i < links.size(); i++) {
MapLink link = (MapLink)links.get(i);
if(link.startNode == start && link.endNode == end)
return;
if(link.startNode == end && link.endNode == start)
return;
}
links.add(new MapLink(start, end));
} catch(Exception e){
e.printStackTrace();
}
}

private void addLinkIndex(int start, int end) {
try {
for(int i = 0; i < links.size(); i++) {
MapLink link = (MapLink)links.get(i);
if(link.startNode == start && link.endNode == end)
return;
if(link.startNode == end && link.endNode == start)
return;
}
links.add(new MapLink(start, end));
} catch(Exception e){
e.printStackTrace();
}
}


private static int coordinateX(int x) {
return (int)((x / 3) + 2032);

}

private static int coordinateY(int y) {
return (int)(4129 - (y / 3));
}

private int getIndex(int index) {
try {
MapNode node = (MapNode)nodes.get(index);
return node.index;
} catch(Exception e){
e.printStackTrace();
}
return 0;
}

private int findIndex(int index) {
for(int i = 0; i < nodes.size(); i++) {
MapNode node = (MapNode)nodes.get(i);
if(node.index == index)
return i;
}
return -1;
}

private MapNode getNode(int index) {
for(int i = 0; i < nodes.size(); i++) {
MapNode node = (MapNode)nodes.get(i);
if(node.index == index)
return node;
}
System.out.println("notfound=" + index);
return null;
}

private int distance(int x1, int x2, int y1, int y2) {
int dx = x1 - x2;
int dy = y1 - y2;
return (int)Math.sqrt(dx*dx + dy*dy);
}




private int coordinateToMapX(int x) {
return 3 * (x - 2032);
}

private int coordinateToMapY(int y) {
return -3 * (y - 4129);
}

private int[][] findPath(int startX, int startY, int endX, int endY) {
try {
pathFound = null;
mapPath = null;
int start, end, shortestIdx = -1, shortest = 99999;
for(int i = 0; i < nodes.size(); i++) {
MapNode node = (MapNode)nodes.get(i);
if(distance(coordinateToMapX(startX), node.x, coordinateToMapY(startY), node.y) < shortest || shortestIdx == -1) {
shortestIdx = i;
shortest = distance(coordinateToMapX(startX), node.x, coordinateToMapY(startY), node.y);
}
}
start = shortestIdx;
shortestIdx = -1;
shortest = 99999;
for(int i = 0; i < nodes.size(); i++) {
MapNode node = (MapNode)nodes.get(i);
if(distance(coordinateToMapX(endX), node.x, coordinateToMapY(endY), node.y) < shortest || shortestIdx == -1) {
shortestIdx = i;
shortest = distance(coordinateToMapX(endX), node.x, coordinateToMapY(endY), node.y);
}
}
end = shortestIdx;
long t = System.currentTimeMillis();
List activeNodes = new ArrayList();
MapNode node = (MapNode)nodes.get(start);
activeNodes.add(new int[] { node.x, node.y, 0, -1, activeNodes.size(), node.index });
node = (MapNode)nodes.get(end);
int endIndex = node.index;
activeNodes.add(new int[] { node.x, node.y, 999999, -1, activeNodes.size(), node.index });
for(int i = 0; i < nodes.size(); i++) {
if(i != start && i != end) {
node = (MapNode)nodes.get(i);
activeNodes.add(new int[] { node.x, node.y, 999999, -1, activeNodes.size(), node.index });
}
}
List allNodes = new ArrayList();
for(int i = 0; i < activeNodes.size(); i++)
allNodes.add(activeNodes.get(i));
while(activeNodes.isEmpty() == false) {
int j = 0;
int[] tNearestNode = (int[])activeNodes.get(0);
int[] tNode = new int[1];
for(int i = 0; i < activeNodes.size(); i++){
tNode = (int[])activeNodes.get(i);
if(tNode[2] < tNearestNode[2]) {
tNearestNode = tNode;
j = i;
}
}
activeNodes.remove(j);
if(tNearestNode[5] == endIndex) {
activeNodes.clear();
} else {
for(int i = 0; i < activeNodes.size(); i++){
tNode = (int[])activeNodes.get(i);
for(int k = 0; k < links.size(); k++) {
MapLink link = (MapLink)links.get(k);
if((link.startNode == tNode[5] && link.endNode == tNearestNode[5]) || (link.startNode == tNearestNode[5] && link.endNode == tNode[5])){
int dx = Math.abs(tNearestNode[0] - tNode[0]);
int dy = Math.abs(tNearestNode[1] - tNode[1]);
int new_dist = dx*dx + dy*dy;
int alt = tNearestNode[2] + new_dist;
if(alt < tNode[2]) {
tNode[2] = alt;
tNode[3] = tNearestNode[4];
}
}
}
}
}
}
List path = new ArrayList();
boolean doContinue = true;
int i = 1;
int j = 1;
while(doContinue) {
int[] tNode = (int[])allNodes.get(i);
path.add(new int[] {tNode[0], tNode[1], tNode[5]});
if(tNode[3] == -1)
doContinue = false;
i = tNode[3];
}
i = 0;
pathFound = new int[path.size()][2];
mapPath = new int[path.size()][2];
for(int k = path.size() - 1; k >= 0; k--) {
int[] tNode = (int[])path.get(k);
pathFound[i] = new int[] { tNode[0], tNode[1], tNode[2] };
mapPath[i++] = new int[] { coordinateX(tNode[0]), coordinateY(tNode[1]) };
}
if(path.size() == 1) {
System.out.println("no valid path found");
pathFound = null;
mapPath = null;
} else {
System.out.println("path found, time=" + (System.currentTimeMillis() - t) + "ms, " + path.size() + " nodes");
}
return mapPath;
} catch(Exception e){
e.printStackTrace();
}
return new int[0][0];
}
}
class MapLink implements NonPluginClass {
int startNode, endNode;

public MapLink(int startNode, int endNode) {
this.startNode = startNode;
this.endNode = endNode;
}
}
class MapNode implements NonPluginClass {
int x, y, index;

public MapNode(int x, int y, int index) {
this.x = x;
this.y = y;
this.index = index;
}
}

n3ss3s

2008-08-22 07:18:05

I would make a walker that can go anywhere, but I failed to understand Ben's helping words - "curx and cury might have to be switched." with isWalkable :(

Smartzkid

2008-08-22 22:22:41

He got CurrentX & CurrentY switched?

n3ss3s

2008-08-23 05:33:06

No, the RSBot code, method getRealDistanceTo uses the getBlocks int[][] array to get an 'isWalkable', and uses some curx and cury vars, Ben said they might have to be switched, but my code didn't even have any curx and cury or anything like them, which divided my brains by zero :(

Bobarkinator

2008-08-23 13:13:31

From: n3ss3s
which divided my brains by zero :(


Roflcakes. I vote just force people to make their own paths :p

And the whole reflection include would be easier if Freddy would add classes to scar.

Wizzup?

2008-08-25 10:35:58

From: Smartzkid
Well, let me start off, this isn't at all my idea, I was just looking at Sum's pathmaker (gj, sum!), and it reminded me of a thread I saw at RSBot.


The idea was actually by Boreas.

Smartzkid

2008-08-25 15:20:59

Somewhat different, but yeah, I guess one could say that..

Wizzup?

2008-08-25 15:28:06

From: Smartzkid
Somewhat different, but yeah, I guess one could say that..


NOTE: I meant that iBot & RSBot got their idea from Boreas… Not necessarily your idea.

Markus

2008-08-26 05:52:03

Only thing is that Boreas never made it, and they did.

Wizzup?

2008-08-26 13:06:50

From: Markus
Only thing is that Boreas never made it, and they did.


The reason was that Boreas had no Reflection for SCAR.

Boreas

2008-08-30 00:36:54

Or attention span :p. Impsoft also attempted it (screwing it up), after saying I was crazy, and then changing their mind.

The basic idea is about 2 years old, but there is a lot that can be added from more recent pathing techniques. For example having the points be connected by 2D rectangles of walkable area, rather than 1D lines.

Mutant Squirrle

2008-08-30 09:24:58

look there are alot of ways to do mapwalking, i remember when i made my private essence miner i literally found every walkable space and thats how i made it tell where your character was located by counting trees and rocks and moveable space hahaha it was kind of retarded after the fact but i got so interested in the mapwalking i got distracted from what i was actually doing XD.

but not many people even know i did that one lol, i used canvas's which i found out are a bitch anymore idk why

Smartzkid

2009-02-20 16:48:21

http://www.cprogramming.com/tutorial/computersciencetheory/dijkstra.html

Sorry for the bump everyone, posting this for future reference..

Markus

2009-02-20 17:03:02

From: Smartzkid
http://www.cprogramming.com/tutorial/computersciencetheory/dijkstra.html

Sorry for the bump everyone, posting this for future reference..

http://www.villavu.com/forum/showthread.php?t=36548?t=39365

Smartzkid

2009-02-20 17:31:54

Ooh, thanks!

n3ss3s

2009-02-21 02:27:02

Want my code for getting all the walkable tiles in a box, Smartzy?

Smartzkid

2009-02-21 14:07:11

Ooh, sure!

n3ss3s

2009-02-21 14:46:12


Const
getBlocks = 't';
getGroundDataArray = 'ua.c';


Function IsWalkable(X, Y: Integer): Boolean;

Var
GroundData, BX, BY, Blocks, blx, bly: Integer;
Begin
Bx := SmartGetFieldInt(0, BaseX);
By := SmartGetFieldInt(0, BaseY);
GroundData := SmartGetFieldArrayObject(0, getGroundDataArray, SmartGetFieldInt(0, BaseLayer));
If (SmartGetFieldArray2DInt(GroundData, getBlocks, X - Bx, Y - By) And $1280108) = 0 Then
Result := True;
SmartFreeObject(GroundData);
End;


Function GetTileArea(X1, Y1, X2, Y2: Integer): TPointArray;

Begin
Result := TPAFromBox(IntToBox(X1, Y1, X2, Y2));
End;


Function FilterWalkable(TPA: TPointArray): TPointArray;

Var
C, I: Integer;
Begin
SetArrayLength(Result, GetArrayLength(TPA));
For I := 0 To High(TPA) Do
If IsWalkable(TPA[i].x, TPA[i].y) Then
Begin
Result[c] := TPA[i];
C := C + 1;
End;
SetArrayLength(Result, C);
End;


//* So, you use FilterWalkable(GetTileArea(The area between you and destionation))
//* to get all the walkable tiles in between.

Comes with outdated groundData hooks :)

So, you can use the single function Ray made to make a path from all those walkable tiles, but the problem is that my code doesn't know whether the walkable tiles are behind closed doors or something so it's safe to be used only at wide areas, like from eastern rock crabs to south for re-aggression…

mastaraymond

2009-02-22 07:14:32

Still don't get why you want to make dynamic paths, n3ss3s :-(. Just manually pick a set of walkable tiles within a certain distance, and you have got yourself a Runescape TomTom!

n3ss3s

2009-02-22 08:30:34

Example scenario:

You've somehow managed to get yourself in a shitty place e.g Isafdar, and you can just be like "Walk me to Varrock, son, while I take a crap".


Well it wouldn't make it through the traps and shit in Isafdar but anyway. Dynamic paths are leetalot.

Still don't get why you want to make dynamic paths, n3ss3s :-(. Just manually pick a set of walkable tiles within a certain distance, and you have got yourself a Runescape TomTom!


TomTom is from RSCA :( (If it has some gay web of tiles)

Method

2009-02-22 10:26:10

Comes with updated groundData hooks. :)

Const
getBlocks = 'f';
getGroundDataArray = 'gb.j';

Boreas

2009-02-22 12:21:11

When I started my global walking system I was under the impression there is no clean reliable way to tell whether a tile is walkable. Are you saying that we can use those hooks for that? So it would return false for a wall or tree etc? What about in the space behind a bank booth?

n3ss3s

2009-02-22 14:12:05

Here is the code hun -


Function IsWalkable(X, Y: Integer): Boolean;

Var
GroundData, BX, BY, Blocks, blx, bly: Integer;
Begin
Bx := SmartGetFieldInt(0, BaseX);
By := SmartGetFieldInt(0, BaseY);
GroundData := SmartGetFieldArrayObject(0, getGroundDataArray, SmartGetFieldInt(0, BaseLayer));
If (SmartGetFieldArray2DInt(GroundData, getBlocks, X - Bx, Y - By) And $1280108) = 0 Then
Result := True;
SmartFreeObject(GroundData);
End;


(Your post just gave the impression you didn't see it since you talked about the hooks only)


Space behind a bank is walkable, but blank tiles that either aren't full tiles or are a part of a hill etc it returns non-walkable :)


Warning: Returns always true when hooks are outdated.

Boreas

2009-02-22 15:36:09

K thanks.