PDA

View Full Version : How to script for a RSPS -Intermediate level



rj
09-21-2013, 06:06 PM
Table of contents

>Making your own uptext function
> Map walking
>>Get Compass Angle
>>SPS
>>DTM
>Inventory functions




Making your own uptext function

Making your own uptext for your RSPS of choice is a pretty good idea if you want to find objects that may have the same colors as others. Uptext will help you always click on the correct object! Now this section is not on creating a font set, it's on creating your own uptext so we will be taking a shortcut: There are 1 of 2 font sets the RSPS will use, either 'P07Chars' (even if the server is from 2008-2011!) or the current upchars set! This means we can use the font set that is already on your computer. In order to get the uptext we will be using GetTextATPA, because it is IMO the most easy to use.

GetTextATPA(ATPA:T2DPointArray, maxvspacing:LongInt, font:String):string;

First, we are going to want to grab the colors of the text, you WILL need to get the best coloring using ACA(this is a intermediate tutorial I am going to assume you know how to grab good colors using ACA). You will have to keep relogging until ACA highlights all of the uptext. Re-log a few times to make sure it finds all of the uptext like this:

http://i.imgur.com/oFGZbxr.png

First make a function and define the variables needed for a TPA and ATPA:

function rsps_getUpText:string;
var
blueTPA: tpointarray;
blueATPA: t2dpointarray;

Next, you will want to find all of the text color of your choice:

FindColorsTolerance(blueTPA, color, X1, Y1, X2, Y2, tol);

Make sure the area it's searching is were the uptext is!

Next, if the length is > 1 then we want to continue:

if (length(blueTPA) > 1) then


After it continues, we want to split it into an ATPA:

blueATPA := splitTPAEx(blueTPA, 1, 10);


Next we want to sort the ATPAs from 0,0 so the text does not end up all jumbled up!

sortATPAFromFirstPointX(blueATPA, point(0, 0));

Now we return whatever GetTextATPA finds:

result:= getTextATPA(blueATPA, 5, 'UpChars07');

blueATPA is the found ATPA, 5 is the minimum vertical spacing(you may have to play around with this) and 'UpChars07' is the font set that is located in C:Simba/fonts

This should return 99% accurate uptext. If it does not then debug the TPA to make sure it's finding all of the text:

DebugTPA(blueTPA, 'bmp');
(bmp must be declared as a interger)

Reasons for incorrect uptext:

-Wrong or bad font set
-Bad colors
-Not searching in the whole uptext area


Map Walking

Get Compass Angle

In order to accurately walk, you are going to have to make a function that will correctly be able to either:

A) Make the Compass close to perfect north
B) Be able to accurately determine the compass angle

I am going to start with being able to determine the compass angle first, because it will make making the compass to perfect north more easy.

Getting the exact compass angle in (degrees) is fairly easy because there is already a function for that in SRL! Why re-invent the wheel?

Function rsps_GetCompassAngleRadians: Extended;
var
TPA: TPointArray;
T: TPoint;
B: TBox;
begin
B := IntToBox(519, 1, 564, 46);
with B do
FindColorsSpiralTolerance(T.x, T.y, TPA, 1911089, x1, y1, x2, y2, 0);
if Length(TPA) < 1 then
exit;
T := MiddleTPA(TPA);
Result := ArcTan2(-(T.Y - 24), T.X - 543) + Radians(90);
Result := fixRad(Result - Pi);
end;

Now all of this is confusing right? WRONG! There are only 2 lines that we need to edit:

this:

B := IntToBox(519, 1, 564, 46);
Change the numbers to the bounds of the compass (hopefully you know how to do this?) This box is were it's going to search for the color. Make it as EXACT as possible

and this:
Change COLOR to the color of the 'N' on the compass

FindColorsSpiralTolerance(T.x, T.y, TPA, COLOR, x1, y1, x2, y2, 0);

and then your done... getting the compass angle in radians. To get it in degrees just do:

function rsps_GetCompassAngleDegrees: Extended;
begin
Result := Degrees(rsps_GetCompassAngleRadians());
end;

SPS

This tutorial will not cover how to SPS walk, it will cover how to edit SPS to work on the RSPS of your choice. Editing SPS is fairly simple, open up SPS.simba (C:\Simba\Includes\SPS). Now paste the SPS source into a new simba script, and save that simba script to your include folder. Now, it is important that you do everything I say or else it won't work. Here is what my SPS.simba looks like so you can accurately follow along:

(*
SPS ~ SRL Positioning System
============================

Concept and original work done by marpis @ SRL-Forums. Work continued by Coh3n
and members of the SRL community.

*)

{$loadlib sps}

const
// Path where all the SPS files are
SPS_IMG_PATH = IncludePath + 'SPS\img\';
SPS_IMG_FMT = '.png';

// Surfaces
RUNESCAPE_SURFACE = 0;
RUNESCAPE_SURFACE_FOLDER = 'runescape_surface\';

RUNESCAPE_OTHER = 1;
RUNESCAPE_OTHER_FOLDER = 'runescape_other\';

// User defined SPS global variables
var
SPS_Debug: boolean;
SPS_MultiMouse: boolean; // simulates a human like "spam-click" when walking
SPS_AnyAngle: boolean; // true = work at any angle; false = only north
SPS_ClickNorth: boolean; // call ClickNorth instead of MakeCompass to set the compass to north

// SPS Global variables
var
SPS_Areas: TStringArray;
SPS_AreaMaps: T3DIntegerArray; // Grids of the combined SPS_Areas
SPS_Tolerance, SPS_MatchesPercent: extended;
SPS_Accuracy: integer; // Splits minimap/areas into squares of this side length; used for area recognition
SPS_IsSetup: boolean; // Used to make sure the user calls SPS_Setup

// Author: marpis & Coh3n
// Returns an image of the minimap in a TMufasaBitmap
function SPS_GatherMinimap: TMufasaBitmap;
var
c: TClient;
begin
try
Result := TMufasaBitmap.Create;
Result.SetSize(150, 150);

c := getTClient;
Result.CopyClientToBitmap(
c.IOManager, false, 0, 0, MMCX-75, MMCY-75, MMCX+75, MMCY+75
);

except
Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: Ollybest & J J
// gets the rotated RS minimap and rotates to face north
// needed for SPS to work at any compass angle
function SPS_RotateMinimap: TMufasaBitmap;
var
W, H, t: Integer;
mmBMP, rBMP: TMufasaBitmap;
MiddleBMP: TPoint;
begin
try
t := getSystemTime();

//gathering minimap
mmBMP := SPS_GatherMinimap;

//rotating minimap
rBMP := GetMufasaBitmap(RotateBitmap(mmBMP.index, 0-rs_GetCompassAngleRadians))

//getting the middle of the rotated bitmap
GetBitmapSize(rBMP.Index, W, H);
MiddleBMP := Point(W/2, H/2);

//creating the result by using a 74 radius around the centre
Result := rbmp.Copy(MiddleBMP.X-74, MiddleBMP.Y-74, MiddleBMP.X+74, MiddleBMP.Y+74);

mmBMP.free
rbmp.free

If SPS_Debug Then
Writeln('Rotating map took '+toStr(getSystemTime - t)+' ms.');

except
Writeln('SPS_RotateMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: marpis & Coh3n
// Gets the starting area coordinates depending on the area image
procedure SPS_GetAreaCoords(Area: string; var x, y: integer);
var
p: integer;
begin
// if it's a specific dungeon map (i.e. name isn't 0_0, 10_2, etc.)
if (length(getNumbers(Area)) < 2) then
begin
x := 0;
y := 0;
Exit;
end;

p := pos('_', Area);

x := StrToIntDef(copy(Area, 1, p - 1), -1);
y := StrToIntDef(copy(Area, p + 1, Length(Area) - p), -1);

//writeln('SPS_GetAreaCoords: '+toStr(point(x, y)));
end;

// Author: marpis
// Converts a point from a map piece to a point on the entire map
function SPS_LocalToGlobal(Area: string; x, y: integer): TPoint;
var
cx, cy: integer;
begin
SPS_GetAreaCoords(Area, cx, cy);
Result.x := (cx * 400) + x;
Result.y := (cy * 400) + y;
end;

// Author: marpis
// Converts a point from the entire map to a point on the main screen
function SPS_GlobalToLocal(x, y: integer): TPoint;
var
cx, cy: integer;
begin
cx := Floor(x / 400);
cy := Floor(y / 400);

Result.x := x - (cx * 400);
Result.y := y - (cy * 400);
end;

// Author: marpis
// Returns the coordinates (x, y) in the form of a string
function SPS_AreaCoordsToString(x, y: integer): string;
begin
Result := IntToStr(x)+'_'+IntToStr(y);
end;

// Author: Coh3n
// Returns a TPA of the areas' values
function SPS_TPAFromAreas(areas: TStringArray): TPointArray;
var
i: integer;
begin
setLength(result, length(areas));

for i := 0 to high(areas) do
SPS_GetAreaCoords(areas[i], result[i].x, result[i].y);
end;

// Author: Coh3n
// Sorts the areas by columns, and sorts each column by rows
// Example: ['1_5', '1_3', '0_5'] results ['0_5', '1_3', '1_5']
function SPS_SortAreas(areas: TStringArray): TStringArray;
var
i, j: integer;
tpa: TPointArray;
begin
setLength(tpa, length(areas));

tpa := SPS_TPAFromAreas(areas);
clearDoubleTPA(tpa);

sortTPAByX(tpa, true); // first sort by column number

// then sort the Y values for each column number
for i := 0 to high(tpa) do
for j := i to high(tpa) do
if (tpa[i].x = tpa[j].x) then
if (tpa[i].y > tpa[j].y) then
tSwap(tpa[i], tpa[j]);

setLength(result, length(tpa));

for i := 0 to high(tpa) do
result[i] := SPS_AreaCoordsToString(tpa[i].x, tpa[i].y);

//writeln('SPS_SortAreas: '+toStr(result));
end;

// Author: Coh3n
// Loads the "Area" image
function SPS_GetArea(Area: string; surface: integer): TMufasaBitmap;
var
x, y: integer;
S: string;
begin
SPS_GetAreaCoords(Area, x, y);

case surface of
RUNESCAPE_SURFACE: s := RUNESCAPE_SURFACE_FOLDER;
RUNESCAPE_OTHER: s := RUNESCAPE_OTHER_FOLDER;
end;

try
Result := TMufasaBitmap.Create;
Result.LoadFromFile(SPS_IMG_PATH + s + Area + SPS_IMG_FMT);
except
Writeln('SPS_GetArea ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: Coh3n
// Merges the SPS 'areas' into one bitmap (makes more more accurate GetMyPos)
function SPS_MergeAreas(areas: TStringArray): TMufasaBitmap;
var
t, i, l, x, y, diffX, diffY, newWidth, newHeight: integer;
startPoint: TPoint;
newAreas: TStringArray;
xVals, yVals: TIntegerArray;
bmpTemp: TMufasaBitmap;
tmpTPA: TPointArray;
begin
if (length(areas) <= 0) then
exit;

t := getSystemTime();

// sort the areas from by columns/rows; remove duplicates
newAreas := SPS_SortAreas(areas);
l := length(newAreas);

// if there's only one area in the array
if (l = 1) then
begin
result := SPS_GetArea(areas[0], RUNESCAPE_SURFACE);
exit;
end;

// get the x and y values for each area
setLength(xVals, l);
setLength(yVals, l);

for i := 0 to high(newAreas) do
SPS_GetAreaCoords(newAreas[i], xVals[i], yVals[i]);

// get the lowest Y value so we can calculate the starting point to draw the first image
tmpTPA := SPS_TPAFromAreas(newAreas);
sortTPAByY(tmpTPA, true);

try
result := TMufasaBitmap.create();

// calculate the starting point
// x is always 0 because of how the areas are sorted
// y is relative to the lowest y value in the areas
SPS_GetAreaCoords(newAreas[0], x, y);
startPoint.x := 0;
startPoint.y := ((y - tmpTPA[0].y) * 400);

// draw the first area to the starting point on the bitmap
bmpTemp := SPS_GetArea(newAreas[0], RUNESCAPE_SURFACE);
result.SetSize(bmpTemp.width, bmpTemp.height + startPoint.y);
bmpTemp.fastDrawTransparent(startPoint.x, startPoint.y, result);
bmpTemp.free();

// loop through each area, drawing them to the result bitmap
// coordinates are calculated relative to the first area drawn (areas[0])
for i := 0 to (l - 2) do
begin
diffX := (xVals[i + 1] - xVals[0]);
diffY := (yVals[i + 1] - yVals[0]);

newWidth := 500 + (round(abs(diffX)) * 400);
newHeight := 500 + (round(abs(diffY)) * 400);

// only set the size if the width or height is increasing
if (newWidth > result.width) then
result.setSize(newWidth, result.height);

if (newHeight > result.height) then
result.setSize(result.width, newHeight);

// copy the area image to the resulting bitmap
bmpTemp := SPS_GetArea(newAreas[i + 1], RUNESCAPE_SURFACE);
bmpTemp.fastDrawTransparent(startPoint.x + (diffX * 400 + 1),
startPoint.y + (diffY * 400 + 1), result);
bmpTemp.free();
end;

//result.saveToFile('C:/Simba/test.bmp');
except
Writeln('SPS_MergeAreas ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;

if (SPS_Debug) then
writeln('SPS_MergeAreas: Merged areas in '+toStr(getSystemTime - t)+' ms.');
end;

// Author: Coh3n
// Returns an SPS area of lowest x and y value. Used for calculating the
// player's correct position
function SPS_GetTopLeftCoords(areas: TStringArray): string;
var
tpa: TPointArray;
begin
tpa := SPS_TPAFromAreas(areas);

if (length(tpa) <= 0) then
begin
result := '0_0';
exit;
end;

sortTPAByX(tpa, true);
result := toStr(tpa[0].x);

sortTPAByY(tpa, true);
result := result + '_'+toStr(tpa[0].y);

//writeln('SPS_GetTopLeftCoords: '+result);
end;

// Author: marpis & SRL Community
function SPS_GetMyPos(): TPoint;
var
Minimap: TMufasaBitmap;
SmallMap: T3DIntegerArray;
a, t, FoundMatches: integer;
P: TPoint;
Searches: extended;
begin
Result := Point(-1, -1);

if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;

if (not LoggedIn) then
Exit;

if (SPS_Tolerance < 1.0) then
SPS_Tolerance := 600.0;

if (SPS_MatchesPercent = 0.0) then
SPS_MatchesPercent := 0.35;

a := round(rs_GetCompassAngleDegrees);

if (SPS_AnyAngle) and (inRange(a, 10, 350)) then
Minimap := SPS_RotateMinimap()
else begin
if (inRange(a, 10, 350)) then
if (SPS_ClickNorth) then
ClickNorth(SRL_ANGLE_HIGH)
else
MakeCompass('N');

Minimap := SPS_GatherMinimap();
end;

t := getSystemTime();
SPS_FilterMinimap(Minimap);
//DrawBitmapDebugImg(Minimap.Index);
//DisplayDebugImgWindow(150, 150);

{$IFDEF SIMBAMAJOR990}
SetLength(SmallMap, 0); // Using this instead of SmallMap := [];
SPS_BitmapToMap(Minimap, SPS_Accuracy, SmallMap);
{$ELSE}
SmallMap := [];
SmallMap := SPS_BitmapToMap(Minimap, SPS_Accuracy);
{$ENDIF}

FoundMatches := SPS_FindMapInMap(P.x, P.y, SPS_AreaMaps, SmallMap, SPS_Tolerance);
Searches := ((Minimap.Width / SPS_Accuracy) * (Minimap.Height / SPS_Accuracy));
{
writeln('fx: '+toStr(p.x)+' ~ on area: '+toStr(P.X * SPS_Accuracy + (Minimap.Width / 2)));
writeln('fy: '+toStr(p.y)+' ~ on area: '+toStr(P.Y * SPS_Accuracy + (Minimap.Width / 2)));
writeln('matches: '+toStr(foundMatches));
writeln('searches: '+toStr(searches));
writeln('percent: '+toStr(FoundMatches / Searches));
}
if ((FoundMatches / Searches) > SPS_MatchesPercent) then
Result := SPS_LocalToGlobal(SPS_GetTopLeftCoords(SPS_Areas), // the top left of the total area
P.x * SPS_Accuracy + (Minimap.Width / 2),
P.y * SPS_Accuracy + (Minimap.Width / 2));

Minimap.Free;

t := (GetSystemTime - t);
if (SPS_Debug) then
Writeln('SPS_GetMyPos: Finished in '+ToStr(t)+' ms. Result = '+ToStr(Result));
end;

// Author: marpis
// Finds position P in minimap by checking your own location
function SPS_PosToMM(P: TPoint): TPoint;
var
MyPos: TPoint;
begin
if not LoggedIn then
Exit;

Result := Point(-1, -1);
MyPos := SPS_GetMyPos;

if (Distance(MyPos.X, MyPos.Y, P.X, P.Y) < 75) then
Result := RotatePoint(Point(MMCX + P.X - MyPos.X, MMCY + P.Y - MyPos.Y), 0-rs_GetCompassAngleRadians, MMCX, MMCY);
end;

// Author: marpis
// Walks to position, P.
function SPS_WalkToPos(P: TPoint): boolean;
var
MM: TPoint;
begin
if not LoggedIn then
Exit;

MM := SPS_PosToMM(P);

if (MM.X > 0) then
begin
if (SPS_MultiMouse) then
MultiMouse(MM.X, MM.Y, 25, 3, false)
else
Mouse(MM.X, MM.Y, 0, 0, mouse_Left);

if WaitFunc(@IsMoving, 1, 3000 + random(500)) then
while IsMoving do
Flag;

Result := True;
end;
end;

// Author: marpis
// Returns true if the point "Pt" is on the minimap
function SPS_PosOnMM(Pt: TPoint): Boolean;
var
p: TPoint;
begin
p := SPS_PosToMM(Pt);
Result := rs_OnMinimap(p.x, p.y);
end;

// Author: marpis & Coh3n
// Walks the path "Path"; always walks to the furthest point possible
function SPS_WalkPath(Path: TPointArray): boolean;
var
I, H, T, D, Fails: integer;
P, MM, MMF: TPoint;
begin
if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;

H := High(Path);
T := GetSystemTime + 20000 + Random(5000);
Fails := 0;

while (not Result) and (GetSystemTime < T) and (Fails < 5) do
begin
if (not LoggedIn()) then
Exit;

RunEnergy(20);
P := SPS_GetMyPos();

for I := H downto 0 do
begin
MM := RotatePoint(Point(MMCX + Path[I].X - P.X, MMCY + Path[I].Y - P.Y),
0-rs_GetCompassAngleRadians, MMCX, MMCY);

if MM = MMF then
Inc(Fails);

D := Distance(MM.X, MM.Y, MMCX, MMCY);

if (D < 10) then
break
else
if (D < 70) then
begin
if (SPS_MultiMouse) then
MultiMouse(MM.X, MM.Y, 25, 3, false)
else
Mouse(MM.X, MM.Y, 5, 5, mouse_Left);

MMF := MM;
FFlag(5 + (Integer(I <> H) * 15));

T := getSystemTime + 20000 + Random(1000);
Break;
end;
end;

Result := (I = H);
end;
end;

// Walks blindly from the player's current position to the point T
function SPS_BlindWalk(P: TPoint): Boolean;
var
Tries: Integer;
M: TPoint;
ctrlPoints: TPointArray;
begin
if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;

repeat
if (not LoggedIn()) then
Exit;

M := SPS_GetMyPos();

if (M.X = -1) then
Continue;

if (Length(ctrlPoints) = 0) then
ctrlPoints := TPABetweenPoints(Point(M.X, M.Y), Point(P.X, P.Y), 20 + Random(15), 10);

Inc(Tries);
if (Tries > 20) then
Exit;

Result := SPS_WalkPath(ctrlPoints);
until(Result);
end;

// Author: Coh3n
// Sets up SPS; needs to be called if you want to switch RS surfaces
function SPS_Setup(surface: integer; areas: TStringArray): boolean;
var
t: integer;
tmp: TMufasaBitmap;
begin
t := getSystemTime;

setLength(SPS_AreaMaps, 0);
setLength(SPS_Areas, 0);

SPS_MultiMouse := true;
SPS_Accuracy := 4;

if (length(areas) > 0) then
begin
if (surface = RUNESCAPE_SURFACE) then
tmp := SPS_MergeAreas(areas) // combine the SPS areas into 1; makes for a more accurate read
else
if (surface = RUNESCAPE_OTHER) then
if (length(areas) = 1) then
tmp := SPS_GetArea(areas[0], surface)
else begin
writeln('SPS_Setup(): Invalid dungeon areas. You can only select one!');
exit;
end;

SPS_IsSetup := true;
result := true;

{$IFDEF SIMBAMAJOR990}
SPS_BitmapToMap(tmp, SPS_Accuracy, SPS_AreaMaps);
{$ELSE}
SPS_AreaMaps := SPS_BitmapToMap(tmp, SPS_Accuracy);
{$ENDIF}

if (surface = RUNESCAPE_SURFACE) then
SPS_Areas := SPS_SortAreas(areas)
else
if (surface = RUNESCAPE_OTHER) then
SPS_Areas := areas;

tmp.free();

end else
writeln('SPS_Setup(): ERROR: SPS areas are not set!');

t := (getSystemTime - t);

if (SPS_Debug) and (result) then
writeln('[SPS] SPS_Setup() took '+toStr(t)+' ms. Areas: '+toStr(SPS_Areas));
end;


Step 1)
Go to line 51. Were it says:

c.IOManager, false, 0, 0, MMCX-75, MMCY-75, MMCX+75, MMCY+75

Change MMCX and MMCY to the center of the minimap of your RSPS of choice. Change 75 to the distance from the center of the minimap to the very edge of the minimap (probably still 75, but you can change it if you want it to be exact)

step 2)

Go to line 340. Were it says
if (not LoggedIn) then
Exit;

There are 1 of 2 things you can do:

1) make your own logged in function and change it to that

2) Erase those 2 lines


Step 3) go to line 403. Repeat step 2, and then go to line 410 were it says:

Result := RotatePoint(Point(MMCX + P.X - MyPos.X, MMCY + P.Y - MyPos.Y), 0-rs_GetCompassAngleRadians, MMCX, MMCY);

Change all MMCX and MMCY to the center of your minimap, and change rs_GetCompassAngleRadians to your compass function that you created in the compass section(MAKE SURE IT'S THE RADIANS ONE)

Step 4) Go to line 419. Repeat step 2. Go to line 432, were it says

while IsMoving do
Flag;

Create a procedure that will look for the flag DTM on your minimap and wait until it's gone. Replace 'Flag' with this procedures name. Here is what mine looks like:

function rsps_FFlag:Boolean;
var
x, y:Integer;
begin
result := FindDTM(Flag_DTM, x, y, rsps_MMX1, rsps_MMY1, rsps_MMX2, rsps_MMY2);
end;
procedure rsps_Flag;
begin
waitFunc(@rsps_FFlag, 100, 6000);
end;

Replace rsps_MMX1, rsps_MMY1, rsps_MMX2, and rsps_MMY2 with the bounds of the minimap.

Step 5) Go to line 468. Repeat step 2 again and then go to line 476 were it says:

MM := RotatePoint(Point(MMCX + Path[I].X - P.X, MMCY + Path[I].Y - P.Y),
0-rs_GetCompassAngleRadians, MMCX, MMCY);

Change all MMCY and MMCX to the center of your minimap, and rs_GetCompassAngleRadians to your compass functions to get the compass angle(MAKE SURE IT'S THE RADIANS ONE)


Step 6) Go to line 520, and repeat step 2 yet again(you catching what I'm doing yet?) and your done!


In order for SPS to work for your RSPS of your choice you will have to use custom maps, guide on how to use custom maps: http://villavu.com/forum/showthread.php?t=84360

DTM

DTM walking is a good way to walk if your too lazy to edit SPS or if the compass angle is > 15 degrees off the actual minimap. In order for a DTM to be found accurately we must use FindDTMRotated. This will look for the DTM as different angles! But before we do that, you should learn how to create a good DTM on the minimap. First, open up Simba's DTM editor. Next, find the point you want to walk and click there, and then make the tolerance '255'. Example:

http://img196.imageshack.us/img196/9506/xtga.png

Next, create points with a tolerance of around 35-40 on areas were NPCs/Players can't walk:

http://img89.imageshack.us/img89/158/9s46.png

Now click show matching DTM's and make sure the point you want to walk at is the only red point:

http://i.imgur.com/52vb5nZ.png

Next, use the FindDTMRotated function to click on it:

FindDTMRotated(DTM, x, y, rsps_MMX1, rsps_MMY1, rsps_MMX2, rsps_MMY2, startD, endD, step, FA)

startD is the start angle it will look for the DTM, I always put 0, endD is the ending angle that it will look for the DTM at I always put 360, and step is the amount (in degrees) that it will look each time. So if you put 10.00 as step, it will start at startD degrees, go to 10.00, go to 20.00 and so on until it reaches the endD degrees. The lower the number you put, the longer it will take. I advise (if) you are just going to look for 1 7.00-10.00.

Now just looking for 1 DTM for 1 point may not be accurate, so I created this function that allows you have have multple DTMs each point. If the first DTM isn't found for the point, it moves onto the second, then third etc etc.
function:

function walk_dtmPath(Points:T2DIntegerArray):Boolean;
var
i, l, x, y:Integer;
FA:Extended;
begin
for i := 0 to high(Points) do
begin
for l := 0 to high(Points[i]) do
begin
if FindDTMRotated(Points[i][l], x, y, rsps_MMX1, rsps_MMY1, rsps_MMX2, rsps_MMY2, 0, 360, 14.00, FA) then
begin
if (distance(x, y, 648, 83) > 15) then
begin
Mouse(x, y, 0, 0, Mouse_left);
wait(1200);
if (rsps_FFlag) then
begin
rsps_Flag;
break;
end;
end;
end;
end;
end;
end;

Of course you will have to make your own rsps_FFlag and rsps_Flag functions.

Here is how I use it. First I declare a path as a record:

type Path = record
dtmpoint:T2DIntegerArray;
end;

Next, I create a variable and make it refer to that record like so:

var
toBank:Path;

And then I declare DTMs for each point:

toBank.dtmPoint[0][0] := DTMFromString('m1gAAAHic42JgYOhiYmCoBeJZQNwLxCVAvB qIC4G4DSo+H4gdgGoNgdgEiA2A2AmI/YDYEsq3A2JXIH77loHhzZMXePG7d+8Y/gPV6hKBGYnECAAAvt4k7w==');

To add another DTM for that point just increase the second 0 by 1:

toBank.dtmPoint[0][1] := DTMFromString('mrAAAAHic42BgYJjHxMCwFIjXAPFGIN4CxJ uAeD4QdwJxKlBNKRBnM0DYMUAcDsRlQFwIxGfOMDC8efICBb97 9w7O1gWqwYcZCWAYAAAybh6t');

Then to add Points increase the first 0 by 1. Example of a path with 4 points:

toBank.dtmPoint[0][0] := DTMFromString('m1gAAAHic42JgYOhiYmCoBeJZQNwLxCVAvB qIC4G4DSo+H4gdgGoNgdgEiA2A2AmI/YDYEsq3A2JXIH77loHhzZMXePG7d+8Y/gPV6hKBGYnECAAAvt4k7w==');
toBank.dtmPoint[0][1] := DTMFromString('mrAAAAHic42BgYJjHxMCwFIjXAPFGIN4CxJ uAeD4QdwJxKlBNKRBnM0DYMUAcDsRlQFwIxGfOMDC8efICBb97 9w7O1gWqwYcZCWAYAAAybh6t');
toBank.dtmPoint[1][0] := DTMFromString('blahblahhhfdjfk');
toBank.dtmPoint[1][1] := DTMFromString('dfgsdfgdfsd');
toBank.dtmPoint[1][2] := DTMFromString('dsfgfdsgdfdg');
toBank.dtmPoint[2][0] := DTMFromString('blahblahhhfdjfk');
toBank.dtmPoint[2][1] := DTMFromString('dfgsdfgdfsd');
toBank.dtmPoint[3][0] := DTMFromString('blahblahhhfdjfk');
toBank.dtmPoint[3][1] := DTMFromString('dfgsdfgdfsd');
toBank.dtmPoint[3][2] := DTMFromString('dsfgfdsgdfdg');

And then to walk the path I just do

walk_dtmPath(ToBank.dtmPoint);



Inventory functions

Inventory functions are hella useful. I will be using Janilabo's Explode box function here! Ok first let's say you want to get the amount of items in your inventory. First declare a TBoxArray variable:


var
Inventory:TBoxArray;


Next use this function to make the variable Inventory Represent every one of the inventory slots:

function ExplodeBox(bx: TBox; rows, columns: integer): TBoxArray;
var
r, c, w, h, ew, eh, ow, oh, i, x, y: integer;
begin
if ((rows > 0) and (columns > 0) and (bx.X1 <= bx.X2) and (bx.Y1 <= bx.Y2)) then
begin
w := ((bx.X2 - bx.X1) + 1);
h := ((bx.Y2 - bx.Y1) + 1);
if (rows < 1) then
rows := 1
else
if (rows > h) then
rows := h;
if (columns < 1) then
columns := 1
else
if (columns > w) then
columns := w;
w := (w div columns);
h := (h div rows);
ew := (((bx.X2 - bx.X1) + 1) - (w * columns));
eh := (((bx.Y2 - bx.Y1) + 1) - (h * rows));
SetLength(Result, (rows * columns));
y := bx.Y1;
for r := 0 to (rows - 1) do
begin
x := bx.X1;
if ((eh > 0) and (r < eh)) then
oh := 1
else
oh := 0;
for c := 0 to (columns - 1) do
begin
if ((ew > 0) and (c < ew)) then
ow := 1
else
ow := 0;
i := ((r * columns) + c);
Result[i].X1 := x;
Result[i].X2 := (x + (w - 1) + ow);
Result[i].Y1 := y;
Result[i].Y2 := (y + (h - 1) + oh);
x := (Result[i].X2 + 1);
end;
y := (Result[i].Y2 + 1);
end;
end else
SetLength(Result, 0);
end;

You use it by getting the exact bounds of the inventory:

http://img716.imageshack.us/img716/3192/xas0.png

The most easy way to do this is to put a large item in the first slot, and another large item in the last slot.

Inventory := ExplodeBox(IntToBox(X1, Y1, X2, Y2), 7, 4);

7 is the number of rows, 4 is the number of colums.

Replaces X1, Y1, X2, and Y2 with the bounds of the inventory.

Now, EVERY SINGLE item in the whole entire game of Runescape that has ever been released has a black outline. There is no such thing as an item without a black outline, we you will have to find out what color that is by finding.... the black outline on a item like this:

http://i.imgur.com/v8Fu7hP.png

The color will usually 65536 but it's different for some servers. I advise you use ACA so you can make sure the color you chose is infact the black outline. As you can see here, 65536 is infact the black outline:
http://img801.imageshack.us/img801/2774/nhc6.png

Now first, we want to see if a selected slot is full:

function rsps_slotFull(slot:Integer):Boolean;
var
x, y:Integer;
begin
if FindColor(x, y, 65536, Inventory[slot].x1, Inventory[slot].y1, Inventory[slot].x2, Inventory[slot].y2) then
result := true;
end;

This will look at the index that you have chosen, so if you do rsps_slotFull(0) it will check the first slot.

Now to get the inventory count, all you have to do is call the rsps_slotFull function inside of another function like so:

function rsps_Invcount:Integer;
var
i:Integer;
begin
for i := 0 to high(Inventory) do
begin
if rsps_slotFull(i) then
result := result + 1;
end;
end;

TADA!

Infull:

function rsps_invFull:Boolean;
begin
result := (rsps_invcount = 28);
end;

Count Item(DTM):

function rsps_CountInventoryDTM(DTMSearch:Integer):Integer;
var
i, x, y:Integer;
begin
for i := 0 to high(Inventory) do
begin
if FindDTM(DTMSearch, x, y, Inventory[i].x1, Inventory[i].y1, Inventory[i].x2, Inventory[i].y2) then
result := result + 1;
end;
end;



Hope this guide help! If you see any grammar mistakes or need help just post below

Twinki
09-23-2013, 12:15 AM
Wow thank you! Going to try SPS soon :)

Also, you should totally make a guide on killing monsters and looting them... ;)

rj
09-23-2013, 12:21 AM
Wow thank you! Going to try SPS soon :)

Also, you should totally make a guide on killing monsters and looting them... ;)
I feel like killing monsters and looting would be under the TPA/ATPA category since it is the same as you would for RS

Twinki
09-23-2013, 11:01 PM
I feel like killing monsters and looting would be under the TPA/ATPA category since it is the same as you would for RS
What about just killing the monsters or detecting if you're in combat? I know it's very different on RSPS's.

Also do you plan on making an advanced guide?

rj
09-23-2013, 11:09 PM
What about just killing the monsters or detecting if you're in combat? I know it's very different on RSPS's.

Also do you plan on making an advanced guide?

I think I'll write a more advanced guide when I learn more advanced stuff (such as loading smart(which only works with a small portion if any servers))

Twinki
09-23-2013, 11:38 PM
I think I'll write a more advanced guide when I learn more advanced stuff (such as loading smart(which only works with a small portion if any servers))

I feel like a noob for asking this.. but how do you find the bounds for the compass angle? Is that just another name for finding like a cord at the top left and a cord at the bottom right? (Making a box basically)

rj
09-23-2013, 11:39 PM
I feel like a noob for asking this.. but how do you find the bounds for the compass angle? Is that just another name for finding like a cord at the top left and a cord at the bottom right? (Making a box basically)

Yea find the very top left and the very bottom right

Twinki
09-25-2013, 11:16 PM
Yea find the very top left and the very bottom right
So far all the inventory functions are working great, but I have one question.

For the Count Item, do we replace the DTMsearch with the DTM to count?

rj
09-25-2013, 11:31 PM
So far all the inventory functions are working great, but I have one question.

For the Count Item, do we replace the DTMsearch with the DTM to count?

DTMSearch is a parameter for the function. Example:

var
IronOre:Integer;

IronOre := DTMFromString('jkdffffffffffffffffffffffffffffffff ffffffffffffff');

rsps_CountInventoryDTM(IronOre);



DTM's are integer's

Twinki
09-25-2013, 11:39 PM
DTMSearch is a parameter for the function. Example:

var
IronOre:Integer;

IronOre := DTMFromString('jkdffffffffffffffffffffffffffffffff ffffffffffffff');

rsps_CountInventoryDTM(IronOre);



DTM's are integer's
Yeah that's what I was trying to say :P Thanks again.

Twinki
09-26-2013, 01:49 AM
Well um... I can't get SPS to work... I'm not getting errors, I start the script and it doesn't do anything... lol


Program TestPath;
{$i srl/srl.Simba}
{$I RL_SPS.Simba}

var

testpath: tpointarray;


begin
testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
SPS_WalkPath(testpath);
end.

rj
09-26-2013, 10:10 AM
Well um... I can't get SPS to work... I'm not getting errors, I start the script and it doesn't do anything... lol


Program TestPath;
{$i srl/srl.Simba}
{$I RL_SPS.Simba}

var

testpath: tpointarray;


begin
testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
SPS_WalkPath(testpath);
end.

You gotta call SetupSPS; I think

Can I see a copy of your SPS file?

Twinki
09-26-2013, 04:49 PM
You gotta call SetupSPS; I think

Can I see a copy of your SPS file?

Yup,

(*
SPS ~ SRL Positioning System
============================

Concept and original work done by marpis @ SRL-Forums. Work continued by Coh3n
and members of the SRL community.

*)
{$include_once RLTools.simba}
{$loadlib sps}

const
// Path where all the SPS files are
SPS_IMG_PATH = IncludePath + 'SPS\img\';
SPS_IMG_FMT = '.png';

// Surfaces
RUNESCAPE_SURFACE = 0;
RUNESCAPE_SURFACE_FOLDER = 'runescape_surface\';

RUNESCAPE_OTHER = 1;
RUNESCAPE_OTHER_FOLDER = 'runescape_other\';

// User defined SPS global variables
var
SPS_Debug: boolean;
SPS_MultiMouse: boolean; // simulates a human like "spam-click" when walking
SPS_AnyAngle: boolean; // true = work at any angle; false = only north
SPS_ClickNorth: boolean; // call ClickNorth instead of MakeCompass to set the compass to north

// SPS Global variables
var
SPS_Areas: TStringArray;
SPS_AreaMaps: T3DIntegerArray; // Grids of the combined SPS_Areas
SPS_Tolerance, SPS_MatchesPercent: extended;
SPS_Accuracy: integer; // Splits minimap/areas into squares of this side length; used for area recognition
SPS_IsSetup: boolean; // Used to make sure the user calls SPS_Setup

// Author: marpis & Coh3n
// Returns an image of the minimap in a TMufasaBitmap
function SPS_GatherMinimap: TMufasaBitmap;
var
c: TClient;
begin
try
Result := TMufasaBitmap.Create;
Result.SetSize(150, 150);

c := getTClient;
Result.CopyClientToBitmap(
c.IOManager, false, 0, 0, 628-75, 86-75, 628+75, 86+75
);

except
Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: Ollybest & J J
// gets the rotated RS minimap and rotates to face north
// needed for SPS to work at any compass angle
function SPS_RotateMinimap: TMufasaBitmap;
var
W, H, t: Integer;
mmBMP, rBMP: TMufasaBitmap;
MiddleBMP: TPoint;
begin
try
t := getSystemTime();

//gathering minimap
mmBMP := SPS_GatherMinimap;

//rotating minimap
rBMP := GetMufasaBitmap(RotateBitmap(mmBMP.index, 0-rs_GetCompassAngleRadians))

//getting the middle of the rotated bitmap
GetBitmapSize(rBMP.Index, W, H);
MiddleBMP := Point(W/2, H/2);

//creating the result by using a 74 radius around the centre
Result := rbmp.Copy(MiddleBMP.X-74, MiddleBMP.Y-74, MiddleBMP.X+74, MiddleBMP.Y+74);

mmBMP.free
rbmp.free

If SPS_Debug Then
Writeln('Rotating map took '+toStr(getSystemTime - t)+' ms.');

except
Writeln('SPS_RotateMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: marpis & Coh3n
// Gets the starting area coordinates depending on the area image
procedure SPS_GetAreaCoords(Area: string; var x, y: integer);
var
p: integer;
begin
// if it's a specific dungeon map (i.e. name isn't 0_0, 10_2, etc.)
if (length(getNumbers(Area)) < 2) then
begin
x := 0;
y := 0;
Exit;
end;

p := pos('_', Area);

x := StrToIntDef(copy(Area, 1, p - 1), -1);
y := StrToIntDef(copy(Area, p + 1, Length(Area) - p), -1);

//writeln('SPS_GetAreaCoords: '+toStr(point(x, y)));
end;

// Author: marpis
// Converts a point from a map piece to a point on the entire map
function SPS_LocalToGlobal(Area: string; x, y: integer): TPoint;
var
cx, cy: integer;
begin
SPS_GetAreaCoords(Area, cx, cy);
Result.x := (cx * 400) + x;
Result.y := (cy * 400) + y;
end;

// Author: marpis
// Converts a point from the entire map to a point on the main screen
function SPS_GlobalToLocal(x, y: integer): TPoint;
var
cx, cy: integer;
begin
cx := Floor(x / 400);
cy := Floor(y / 400);

Result.x := x - (cx * 400);
Result.y := y - (cy * 400);
end;

// Author: marpis
// Returns the coordinates (x, y) in the form of a string
function SPS_AreaCoordsToString(x, y: integer): string;
begin
Result := IntToStr(x)+'_'+IntToStr(y);
end;

// Author: Coh3n
// Returns a TPA of the areas' values
function SPS_TPAFromAreas(areas: TStringArray): TPointArray;
var
i: integer;
begin
setLength(result, length(areas));

for i := 0 to high(areas) do
SPS_GetAreaCoords(areas[i], result[i].x, result[i].y);
end;

// Author: Coh3n
// Sorts the areas by columns, and sorts each column by rows
// Example: ['1_5', '1_3', '0_5'] results ['0_5', '1_3', '1_5']
function SPS_SortAreas(areas: TStringArray): TStringArray;
var
i, j: integer;
tpa: TPointArray;
begin
setLength(tpa, length(areas));

tpa := SPS_TPAFromAreas(areas);
clearDoubleTPA(tpa);

sortTPAByX(tpa, true); // first sort by column number

// then sort the Y values for each column number
for i := 0 to high(tpa) do
for j := i to high(tpa) do
if (tpa[i].x = tpa[j].x) then
if (tpa[i].y > tpa[j].y) then
tSwap(tpa[i], tpa[j]);

setLength(result, length(tpa));

for i := 0 to high(tpa) do
result[i] := SPS_AreaCoordsToString(tpa[i].x, tpa[i].y);

//writeln('SPS_SortAreas: '+toStr(result));
end;

// Author: Coh3n
// Loads the "Area" image
function SPS_GetArea(Area: string; surface: integer): TMufasaBitmap;
var
x, y: integer;
S: string;
begin
SPS_GetAreaCoords(Area, x, y);

case surface of
RUNESCAPE_SURFACE: s := RUNESCAPE_SURFACE_FOLDER;
RUNESCAPE_OTHER: s := RUNESCAPE_OTHER_FOLDER;
end;

try
Result := TMufasaBitmap.Create;
Result.LoadFromFile(SPS_IMG_PATH + s + Area + SPS_IMG_FMT);
except
Writeln('SPS_GetArea ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: Coh3n
// Merges the SPS 'areas' into one bitmap (makes more more accurate GetMyPos)
function SPS_MergeAreas(areas: TStringArray): TMufasaBitmap;
var
t, i, l, x, y, diffX, diffY, newWidth, newHeight: integer;
startPoint: TPoint;
newAreas: TStringArray;
xVals, yVals: TIntegerArray;
bmpTemp: TMufasaBitmap;
tmpTPA: TPointArray;
begin
if (length(areas) <= 0) then
exit;

t := getSystemTime();

// sort the areas from by columns/rows; remove duplicates
newAreas := SPS_SortAreas(areas);
l := length(newAreas);

// if there's only one area in the array
if (l = 1) then
begin
result := SPS_GetArea(areas[0], RUNESCAPE_SURFACE);
exit;
end;

// get the x and y values for each area
setLength(xVals, l);
setLength(yVals, l);

for i := 0 to high(newAreas) do
SPS_GetAreaCoords(newAreas[i], xVals[i], yVals[i]);

// get the lowest Y value so we can calculate the starting point to draw the first image
tmpTPA := SPS_TPAFromAreas(newAreas);
sortTPAByY(tmpTPA, true);

try
result := TMufasaBitmap.create();

// calculate the starting point
// x is always 0 because of how the areas are sorted
// y is relative to the lowest y value in the areas
SPS_GetAreaCoords(newAreas[0], x, y);
startPoint.x := 0;
startPoint.y := ((y - tmpTPA[0].y) * 400);

// draw the first area to the starting point on the bitmap
bmpTemp := SPS_GetArea(newAreas[0], RUNESCAPE_SURFACE);
result.SetSize(bmpTemp.width, bmpTemp.height + startPoint.y);
bmpTemp.fastDrawTransparent(startPoint.x, startPoint.y, result);
bmpTemp.free();

// loop through each area, drawing them to the result bitmap
// coordinates are calculated relative to the first area drawn (areas[0])
for i := 0 to (l - 2) do
begin
diffX := (xVals[i + 1] - xVals[0]);
diffY := (yVals[i + 1] - yVals[0]);

newWidth := 500 + (round(abs(diffX)) * 400);
newHeight := 500 + (round(abs(diffY)) * 400);

// only set the size if the width or height is increasing
if (newWidth > result.width) then
result.setSize(newWidth, result.height);

if (newHeight > result.height) then
result.setSize(result.width, newHeight);

// copy the area image to the resulting bitmap
bmpTemp := SPS_GetArea(newAreas[i + 1], RUNESCAPE_SURFACE);
bmpTemp.fastDrawTransparent(startPoint.x + (diffX * 400 + 1),
startPoint.y + (diffY * 400 + 1), result);
bmpTemp.free();
end;

//result.saveToFile('C:/Simba/test.bmp');
except
Writeln('SPS_MergeAreas ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;

if (SPS_Debug) then
writeln('SPS_MergeAreas: Merged areas in '+toStr(getSystemTime - t)+' ms.');
end;

// Author: Coh3n
// Returns an SPS area of lowest x and y value. Used for calculating the
// player's correct position
function SPS_GetTopLeftCoords(areas: TStringArray): string;
var
tpa: TPointArray;
begin
tpa := SPS_TPAFromAreas(areas);

if (length(tpa) <= 0) then
begin
result := '0_0';
exit;
end;

sortTPAByX(tpa, true);
result := toStr(tpa[0].x);

sortTPAByY(tpa, true);
result := result + '_'+toStr(tpa[0].y);

//writeln('SPS_GetTopLeftCoords: '+result);
end;

// Author: marpis & SRL Community
function SPS_GetMyPos(): TPoint;
var
Minimap: TMufasaBitmap;
SmallMap: T3DIntegerArray;
a, t, FoundMatches: integer;
P: TPoint;
Searches: extended;
begin
Result := Point(-1, -1);

if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;


if (SPS_Tolerance < 1.0) then
SPS_Tolerance := 600.0;

if (SPS_MatchesPercent = 0.0) then
SPS_MatchesPercent := 0.35;

a := round(rs_GetCompassAngleDegrees);

if (SPS_AnyAngle) and (inRange(a, 10, 350)) then
Minimap := SPS_RotateMinimap()
else begin
if (inRange(a, 10, 350)) then
if (SPS_ClickNorth) then
ClickNorth(SRL_ANGLE_HIGH)
else
MakeCompass('N');

Minimap := SPS_GatherMinimap();
end;

t := getSystemTime();
SPS_FilterMinimap(Minimap);
//DrawBitmapDebugImg(Minimap.Index);
//DisplayDebugImgWindow(150, 150);

{$IFDEF SIMBAMAJOR990}
SetLength(SmallMap, 0); // Using this instead of SmallMap := [];
SPS_BitmapToMap(Minimap, SPS_Accuracy, SmallMap);
{$ELSE}
SmallMap := [];
SmallMap := SPS_BitmapToMap(Minimap, SPS_Accuracy);
{$ENDIF}

FoundMatches := SPS_FindMapInMap(P.x, P.y, SPS_AreaMaps, SmallMap, SPS_Tolerance);
Searches := ((Minimap.Width / SPS_Accuracy) * (Minimap.Height / SPS_Accuracy));
{
writeln('fx: '+toStr(p.x)+' ~ on area: '+toStr(P.X * SPS_Accuracy + (Minimap.Width / 2)));
writeln('fy: '+toStr(p.y)+' ~ on area: '+toStr(P.Y * SPS_Accuracy + (Minimap.Width / 2)));
writeln('matches: '+toStr(foundMatches));
writeln('searches: '+toStr(searches));
writeln('percent: '+toStr(FoundMatches / Searches));
}
if ((FoundMatches / Searches) > SPS_MatchesPercent) then
Result := SPS_LocalToGlobal(SPS_GetTopLeftCoords(SPS_Areas), // the top left of the total area
P.x * SPS_Accuracy + (Minimap.Width / 2),
P.y * SPS_Accuracy + (Minimap.Width / 2));

Minimap.Free;

t := (GetSystemTime - t);
if (SPS_Debug) then
Writeln('SPS_GetMyPos: Finished in '+ToStr(t)+' ms. Result = '+ToStr(Result));
end;

// Author: marpis
// Finds position P in minimap by checking your own location
function SPS_PosToMM(P: TPoint): TPoint;
var
MyPos: TPoint;
begin

Result := Point(-1, -1);
MyPos := SPS_GetMyPos;

if (Distance(MyPos.X, MyPos.Y, P.X, P.Y) < 75) then
Result := RotatePoint(Point(964 + P.X - MyPos.X, 104 + P.Y - MyPos.Y), 0-RL_GetCompassAngleRadians, 964, 104);
end;

// Author: marpis
// Walks to position, P.
function SPS_WalkToPos(P: TPoint): boolean;
var
MM: TPoint;
begin

MM := SPS_PosToMM(P);

if (MM.X > 0) then
begin
if (SPS_MultiMouse) then
MultiMouse(MM.X, MM.Y, 25, 3, false)
else
Mouse(MM.X, MM.Y, 0, 0, mouse_Left);

if WaitFunc(@IsMoving, 1, 3000 + random(500)) then
while IsMoving do
Flag;

Result := True;
end;
end;

// Author: marpis
// Returns true if the point "Pt" is on the minimap
function SPS_PosOnMM(Pt: TPoint): Boolean;
var
p: TPoint;
begin
p := SPS_PosToMM(Pt);
Result := rs_OnMinimap(p.x, p.y);
end;

// Author: marpis & Coh3n
// Walks the path "Path"; always walks to the furthest point possible
function SPS_WalkPath(Path: TPointArray): boolean;
var
I, H, T, D, Fails: integer;
P, MM, MMF: TPoint;
begin
if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;

H := High(Path);
T := GetSystemTime + 20000 + Random(5000);
Fails := 0;

while (not Result) and (GetSystemTime < T) and (Fails < 5) do
begin

RunEnergy(20);
P := SPS_GetMyPos();

for I := H downto 0 do
begin
MM := RotatePoint(Point(964 + Path[I].X - P.X, 104 + Path[I].Y - P.Y),
0-RL_GetCompassAngleRadians, 964, 104);

if MM = MMF then
Inc(Fails);

D := Distance(MM.X, MM.Y, MMCX, MMCY);

if (D < 10) then
break
else
if (D < 70) then
begin
if (SPS_MultiMouse) then
MultiMouse(MM.X, MM.Y, 25, 3, false)
else
Mouse(MM.X, MM.Y, 5, 5, mouse_Left);

MMF := MM;
FFlag(5 + (Integer(I <> H) * 15));

T := getSystemTime + 20000 + Random(1000);
Break;
end;
end;

Result := (I = H);
end;
end;

// Walks blindly from the player's current position to the point T
function SPS_BlindWalk(P: TPoint): Boolean;
var
Tries: Integer;
M: TPoint;
ctrlPoints: TPointArray;
begin
if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;

repeat

M := SPS_GetMyPos();

if (M.X = -1) then
Continue;

if (Length(ctrlPoints) = 0) then
ctrlPoints := TPABetweenPoints(Point(M.X, M.Y), Point(P.X, P.Y), 20 + Random(15), 10);

Inc(Tries);
if (Tries > 20) then
Exit;

Result := SPS_WalkPath(ctrlPoints);
until(Result);
end;

// Author: Coh3n
// Sets up SPS; needs to be called if you want to switch RS surfaces
function SPS_Setup(surface: integer; areas: TStringArray): boolean;
var
t: integer;
tmp: TMufasaBitmap;
begin
t := getSystemTime;

setLength(SPS_AreaMaps, 0);
setLength(SPS_Areas, 0);

SPS_MultiMouse := true;
SPS_Accuracy := 4;

if (length(areas) > 0) then
begin
if (surface = RUNESCAPE_SURFACE) then
tmp := SPS_MergeAreas(areas) // combine the SPS areas into 1; makes for a more accurate read
else
if (surface = RUNESCAPE_OTHER) then
if (length(areas) = 1) then
tmp := SPS_GetArea(areas[0], surface)
else begin
writeln('SPS_Setup(): Invalid dungeon areas. You can only select one!');
exit;
end;

SPS_IsSetup := true;
result := true;

{$IFDEF SIMBAMAJOR990}
SPS_BitmapToMap(tmp, SPS_Accuracy, SPS_AreaMaps);
{$ELSE}
SPS_AreaMaps := SPS_BitmapToMap(tmp, SPS_Accuracy);
{$ENDIF}

if (surface = RUNESCAPE_SURFACE) then
SPS_Areas := SPS_SortAreas(areas)
else
if (surface = RUNESCAPE_OTHER) then
SPS_Areas := areas;

tmp.free();

end else
writeln('SPS_Setup(): ERROR: SPS areas are not set!');

t := (getSystemTime - t);

if (SPS_Debug) and (result) then
writeln('[SPS] SPS_Setup() took '+toStr(t)+' ms. Areas: '+toStr(SPS_Areas));
end;

I am new
09-26-2013, 08:42 PM
Hi this tutorial something I wish there was like 2 years a go while I was playing few p servers where I was making pretty basic scripts with just help of color finding boosted with ACA.

Where I am struggling now is the uptext part where you have to put in TPA and ATPA values. I read the guide about TPAs but didn't really find a way to apply it on this. Maybe if you could add one of your working functions I could try and study it to make mine work as well.

Thanks in advance.

rj
09-26-2013, 09:43 PM
Hi this tutorial something I wish there was like 2 years a go while I was playing few p servers where I was making pretty basic scripts with just help of color finding boosted with ACA.

Where I am struggling now is the uptext part where you have to put in TPA and ATPA values. I read the guide about TPAs but didn't really find a way to apply it on this. Maybe if you could add one of your working functions I could try and study it to make mine work as well.

Thanks in advance.

function rsps_uptext:string;
var
TPA: tpointarray;
ATPA: t2dpointarray;
begin
FindColorsTolerance(TPA, 65535, 438, 14, 469, 23, 0);
if (length(TPA) > 1) then
begin
ATPA := splitTPAEx(TPA, 1, 10);
filterTPAsbetween(ATPA, 1, 10);
sortATPAFromFirstPointX(ATPA, point(0, 0));
result.x := StrToInt(getTextATPA(ATPA, 5, 'fontname'));
end;
end;

Twinki
09-26-2013, 10:13 PM
You gotta call SetupSPS; I think

Can I see a copy of your SPS file?

Also SetupSPS; doesn't exist lol

rj
09-26-2013, 10:18 PM
Also SetupSPS; doesn't exist lol

Lol haven't used SPS in a while :D

Twinki
09-26-2013, 10:20 PM
Lol haven't used SPS in a while :D
It still doesn't seem to want to do anything...
Here's the full SPS file again:

(*
SPS ~ SRL Positioning System
============================

Concept and original work done by marpis @ SRL-Forums. Work continued by Coh3n
and members of the SRL community.

*)
{$include_once RLTools.simba}
{$loadlib sps}

const
// Path where all the SPS files are
SPS_IMG_PATH = IncludePath + 'SPS\img\';
SPS_IMG_FMT = '.png';

// Surfaces
RUNESCAPE_SURFACE = 0;
RUNESCAPE_SURFACE_FOLDER = 'runescape_surface\';

RUNESCAPE_OTHER = 1;
RUNESCAPE_OTHER_FOLDER = 'runescape_other\';

// User defined SPS global variables
var
SPS_Debug: boolean;
SPS_MultiMouse: boolean; // simulates a human like "spam-click" when walking
SPS_AnyAngle: boolean; // true = work at any angle; false = only north
SPS_ClickNorth: boolean; // call ClickNorth instead of MakeCompass to set the compass to north

// SPS Global variables
var
SPS_Areas: TStringArray;
SPS_AreaMaps: T3DIntegerArray; // Grids of the combined SPS_Areas
SPS_Tolerance, SPS_MatchesPercent: extended;
SPS_Accuracy: integer; // Splits minimap/areas into squares of this side length; used for area recognition
SPS_IsSetup: boolean; // Used to make sure the user calls SPS_Setup

// Author: marpis & Coh3n
// Returns an image of the minimap in a TMufasaBitmap
function SPS_GatherMinimap: TMufasaBitmap;
var
c: TClient;
begin
try
Result := TMufasaBitmap.Create;
Result.SetSize(150, 150);

c := getTClient;
Result.CopyClientToBitmap(
c.IOManager, false, 0, 0, 628-75, 86-75, 628+75, 86+75
);

except
Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: Ollybest & J J
// gets the rotated RS minimap and rotates to face north
// needed for SPS to work at any compass angle
function SPS_RotateMinimap: TMufasaBitmap;
var
W, H, t: Integer;
mmBMP, rBMP: TMufasaBitmap;
MiddleBMP: TPoint;
begin
try
t := getSystemTime();

//gathering minimap
mmBMP := SPS_GatherMinimap;

//rotating minimap
rBMP := GetMufasaBitmap(RotateBitmap(mmBMP.index, 0-rs_GetCompassAngleRadians))

//getting the middle of the rotated bitmap
GetBitmapSize(rBMP.Index, W, H);
MiddleBMP := Point(W/2, H/2);

//creating the result by using a 74 radius around the centre
Result := rbmp.Copy(MiddleBMP.X-74, MiddleBMP.Y-74, MiddleBMP.X+74, MiddleBMP.Y+74);

mmBMP.free
rbmp.free

If SPS_Debug Then
Writeln('Rotating map took '+toStr(getSystemTime - t)+' ms.');

except
Writeln('SPS_RotateMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: marpis & Coh3n
// Gets the starting area coordinates depending on the area image
procedure SPS_GetAreaCoords(Area: string; var x, y: integer);
var
p: integer;
begin
// if it's a specific dungeon map (i.e. name isn't 0_0, 10_2, etc.)
if (length(getNumbers(Area)) < 2) then
begin
x := 0;
y := 0;
Exit;
end;

p := pos('_', Area);

x := StrToIntDef(copy(Area, 1, p - 1), -1);
y := StrToIntDef(copy(Area, p + 1, Length(Area) - p), -1);

//writeln('SPS_GetAreaCoords: '+toStr(point(x, y)));
end;

// Author: marpis
// Converts a point from a map piece to a point on the entire map
function SPS_LocalToGlobal(Area: string; x, y: integer): TPoint;
var
cx, cy: integer;
begin
SPS_GetAreaCoords(Area, cx, cy);
Result.x := (cx * 400) + x;
Result.y := (cy * 400) + y;
end;

// Author: marpis
// Converts a point from the entire map to a point on the main screen
function SPS_GlobalToLocal(x, y: integer): TPoint;
var
cx, cy: integer;
begin
cx := Floor(x / 400);
cy := Floor(y / 400);

Result.x := x - (cx * 400);
Result.y := y - (cy * 400);
end;

// Author: marpis
// Returns the coordinates (x, y) in the form of a string
function SPS_AreaCoordsToString(x, y: integer): string;
begin
Result := IntToStr(x)+'_'+IntToStr(y);
end;

// Author: Coh3n
// Returns a TPA of the areas' values
function SPS_TPAFromAreas(areas: TStringArray): TPointArray;
var
i: integer;
begin
setLength(result, length(areas));

for i := 0 to high(areas) do
SPS_GetAreaCoords(areas[i], result[i].x, result[i].y);
end;

// Author: Coh3n
// Sorts the areas by columns, and sorts each column by rows
// Example: ['1_5', '1_3', '0_5'] results ['0_5', '1_3', '1_5']
function SPS_SortAreas(areas: TStringArray): TStringArray;
var
i, j: integer;
tpa: TPointArray;
begin
setLength(tpa, length(areas));

tpa := SPS_TPAFromAreas(areas);
clearDoubleTPA(tpa);

sortTPAByX(tpa, true); // first sort by column number

// then sort the Y values for each column number
for i := 0 to high(tpa) do
for j := i to high(tpa) do
if (tpa[i].x = tpa[j].x) then
if (tpa[i].y > tpa[j].y) then
tSwap(tpa[i], tpa[j]);

setLength(result, length(tpa));

for i := 0 to high(tpa) do
result[i] := SPS_AreaCoordsToString(tpa[i].x, tpa[i].y);

//writeln('SPS_SortAreas: '+toStr(result));
end;

// Author: Coh3n
// Loads the "Area" image
function SPS_GetArea(Area: string; surface: integer): TMufasaBitmap;
var
x, y: integer;
S: string;
begin
SPS_GetAreaCoords(Area, x, y);

case surface of
RUNESCAPE_SURFACE: s := RUNESCAPE_SURFACE_FOLDER;
RUNESCAPE_OTHER: s := RUNESCAPE_OTHER_FOLDER;
end;

try
Result := TMufasaBitmap.Create;
Result.LoadFromFile(SPS_IMG_PATH + s + Area + SPS_IMG_FMT);
except
Writeln('SPS_GetArea ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

// Author: Coh3n
// Merges the SPS 'areas' into one bitmap (makes more more accurate GetMyPos)
function SPS_MergeAreas(areas: TStringArray): TMufasaBitmap;
var
t, i, l, x, y, diffX, diffY, newWidth, newHeight: integer;
startPoint: TPoint;
newAreas: TStringArray;
xVals, yVals: TIntegerArray;
bmpTemp: TMufasaBitmap;
tmpTPA: TPointArray;
begin
if (length(areas) <= 0) then
exit;

t := getSystemTime();

// sort the areas from by columns/rows; remove duplicates
newAreas := SPS_SortAreas(areas);
l := length(newAreas);

// if there's only one area in the array
if (l = 1) then
begin
result := SPS_GetArea(areas[0], RUNESCAPE_SURFACE);
exit;
end;

// get the x and y values for each area
setLength(xVals, l);
setLength(yVals, l);

for i := 0 to high(newAreas) do
SPS_GetAreaCoords(newAreas[i], xVals[i], yVals[i]);

// get the lowest Y value so we can calculate the starting point to draw the first image
tmpTPA := SPS_TPAFromAreas(newAreas);
sortTPAByY(tmpTPA, true);

try
result := TMufasaBitmap.create();

// calculate the starting point
// x is always 0 because of how the areas are sorted
// y is relative to the lowest y value in the areas
SPS_GetAreaCoords(newAreas[0], x, y);
startPoint.x := 0;
startPoint.y := ((y - tmpTPA[0].y) * 400);

// draw the first area to the starting point on the bitmap
bmpTemp := SPS_GetArea(newAreas[0], RUNESCAPE_SURFACE);
result.SetSize(bmpTemp.width, bmpTemp.height + startPoint.y);
bmpTemp.fastDrawTransparent(startPoint.x, startPoint.y, result);
bmpTemp.free();

// loop through each area, drawing them to the result bitmap
// coordinates are calculated relative to the first area drawn (areas[0])
for i := 0 to (l - 2) do
begin
diffX := (xVals[i + 1] - xVals[0]);
diffY := (yVals[i + 1] - yVals[0]);

newWidth := 500 + (round(abs(diffX)) * 400);
newHeight := 500 + (round(abs(diffY)) * 400);

// only set the size if the width or height is increasing
if (newWidth > result.width) then
result.setSize(newWidth, result.height);

if (newHeight > result.height) then
result.setSize(result.width, newHeight);

// copy the area image to the resulting bitmap
bmpTemp := SPS_GetArea(newAreas[i + 1], RUNESCAPE_SURFACE);
bmpTemp.fastDrawTransparent(startPoint.x + (diffX * 400 + 1),
startPoint.y + (diffY * 400 + 1), result);
bmpTemp.free();
end;

//result.saveToFile('C:/Simba/test.bmp');
except
Writeln('SPS_MergeAreas ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;

if (SPS_Debug) then
writeln('SPS_MergeAreas: Merged areas in '+toStr(getSystemTime - t)+' ms.');
end;

// Author: Coh3n
// Returns an SPS area of lowest x and y value. Used for calculating the
// player's correct position
function SPS_GetTopLeftCoords(areas: TStringArray): string;
var
tpa: TPointArray;
begin
tpa := SPS_TPAFromAreas(areas);

if (length(tpa) <= 0) then
begin
result := '0_0';
exit;
end;

sortTPAByX(tpa, true);
result := toStr(tpa[0].x);

sortTPAByY(tpa, true);
result := result + '_'+toStr(tpa[0].y);

//writeln('SPS_GetTopLeftCoords: '+result);
end;

// Author: marpis & SRL Community
function SPS_GetMyPos(): TPoint;
var
Minimap: TMufasaBitmap;
SmallMap: T3DIntegerArray;
a, t, FoundMatches: integer;
P: TPoint;
Searches: extended;
begin
Result := Point(-1, -1);

if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;


if (SPS_Tolerance < 1.0) then
SPS_Tolerance := 600.0;

if (SPS_MatchesPercent = 0.0) then
SPS_MatchesPercent := 0.35;

a := round(rs_GetCompassAngleDegrees);

if (SPS_AnyAngle) and (inRange(a, 10, 350)) then
Minimap := SPS_RotateMinimap()
else begin
if (inRange(a, 10, 350)) then
if (SPS_ClickNorth) then
ClickNorth(SRL_ANGLE_HIGH)
else
MakeCompass('N');

Minimap := SPS_GatherMinimap();
end;

t := getSystemTime();
SPS_FilterMinimap(Minimap);
//DrawBitmapDebugImg(Minimap.Index);
//DisplayDebugImgWindow(150, 150);

{$IFDEF SIMBAMAJOR990}
SetLength(SmallMap, 0); // Using this instead of SmallMap := [];
SPS_BitmapToMap(Minimap, SPS_Accuracy, SmallMap);
{$ELSE}
SmallMap := [];
SmallMap := SPS_BitmapToMap(Minimap, SPS_Accuracy);
{$ENDIF}

FoundMatches := SPS_FindMapInMap(P.x, P.y, SPS_AreaMaps, SmallMap, SPS_Tolerance);
Searches := ((Minimap.Width / SPS_Accuracy) * (Minimap.Height / SPS_Accuracy));
{
writeln('fx: '+toStr(p.x)+' ~ on area: '+toStr(P.X * SPS_Accuracy + (Minimap.Width / 2)));
writeln('fy: '+toStr(p.y)+' ~ on area: '+toStr(P.Y * SPS_Accuracy + (Minimap.Width / 2)));
writeln('matches: '+toStr(foundMatches));
writeln('searches: '+toStr(searches));
writeln('percent: '+toStr(FoundMatches / Searches));
}
if ((FoundMatches / Searches) > SPS_MatchesPercent) then
Result := SPS_LocalToGlobal(SPS_GetTopLeftCoords(SPS_Areas), // the top left of the total area
P.x * SPS_Accuracy + (Minimap.Width / 2),
P.y * SPS_Accuracy + (Minimap.Width / 2));

Minimap.Free;

t := (GetSystemTime - t);
if (SPS_Debug) then
Writeln('SPS_GetMyPos: Finished in '+ToStr(t)+' ms. Result = '+ToStr(Result));
end;

// Author: marpis
// Finds position P in minimap by checking your own location
function SPS_PosToMM(P: TPoint): TPoint;
var
MyPos: TPoint;
begin

Result := Point(-1, -1);
MyPos := SPS_GetMyPos;

if (Distance(MyPos.X, MyPos.Y, P.X, P.Y) < 75) then
Result := RotatePoint(Point(964 + P.X - MyPos.X, 104 + P.Y - MyPos.Y), 0-RL_GetCompassAngleRadians, 964, 104);
end;

// Author: marpis
// Walks to position, P.
function SPS_WalkToPos(P: TPoint): boolean;
var
MM: TPoint;
begin

MM := SPS_PosToMM(P);

if (MM.X > 0) then
begin
if (SPS_MultiMouse) then
MultiMouse(MM.X, MM.Y, 25, 3, false)
else
Mouse(MM.X, MM.Y, 0, 0, mouse_Left);

if WaitFunc(@IsMoving, 1, 3000 + random(500)) then
while IsMoving do
Flag;

Result := True;
end;
end;

// Author: marpis
// Returns true if the point "Pt" is on the minimap
function SPS_PosOnMM(Pt: TPoint): Boolean;
var
p: TPoint;
begin
p := SPS_PosToMM(Pt);
Result := rs_OnMinimap(p.x, p.y);
end;

// Author: marpis & Coh3n
// Walks the path "Path"; always walks to the furthest point possible
function SPS_WalkPath(Path: TPointArray): boolean;
var
I, H, T, D, Fails: integer;
P, MM, MMF: TPoint;
begin
if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;

H := High(Path);
T := GetSystemTime + 20000 + Random(5000);
Fails := 0;

while (not Result) and (GetSystemTime < T) and (Fails < 5) do
begin

RunEnergy(20);
P := SPS_GetMyPos();

for I := H downto 0 do
begin
MM := RotatePoint(Point(964 + Path[I].X - P.X, 104 + Path[I].Y - P.Y),
0-RL_GetCompassAngleRadians, 964, 104);

if MM = MMF then
Inc(Fails);

D := Distance(MM.X, MM.Y, MMCX, MMCY);

if (D < 10) then
break
else
if (D < 70) then
begin
if (SPS_MultiMouse) then
MultiMouse(MM.X, MM.Y, 25, 3, false)
else
Mouse(MM.X, MM.Y, 5, 5, mouse_Left);

MMF := MM;
FFlag(5 + (Integer(I <> H) * 15));

T := getSystemTime + 20000 + Random(1000);
Break;
end;
end;

Result := (I = H);
end;
end;

// Walks blindly from the player's current position to the point T
function SPS_BlindWalk(P: TPoint): Boolean;
var
Tries: Integer;
M: TPoint;
ctrlPoints: TPointArray;
begin
if (not SPS_IsSetup) then
begin
writeln('SPS ERROR: SPS_Setup was never called');
exit;
end;

repeat

M := SPS_GetMyPos();

if (M.X = -1) then
Continue;

if (Length(ctrlPoints) = 0) then
ctrlPoints := TPABetweenPoints(Point(M.X, M.Y), Point(P.X, P.Y), 20 + Random(15), 10);

Inc(Tries);
if (Tries > 20) then
Exit;

Result := SPS_WalkPath(ctrlPoints);
until(Result);
end;

// Author: Coh3n
// Sets up SPS; needs to be called if you want to switch RS surfaces
function SPS_Setup(surface: integer; areas: TStringArray): boolean;
var
t: integer;
tmp: TMufasaBitmap;
begin
t := getSystemTime;

setLength(SPS_AreaMaps, 0);
setLength(SPS_Areas, 0);

SPS_MultiMouse := true;
SPS_Accuracy := 4;

if (length(areas) > 0) then
begin
if (surface = RUNESCAPE_SURFACE) then
tmp := SPS_MergeAreas(areas) // combine the SPS areas into 1; makes for a more accurate read
else
if (surface = RUNESCAPE_OTHER) then
if (length(areas) = 1) then
tmp := SPS_GetArea(areas[0], surface)
else begin
writeln('SPS_Setup(): Invalid dungeon areas. You can only select one!');
exit;
end;

SPS_IsSetup := true;
result := true;

{$IFDEF SIMBAMAJOR990}
SPS_BitmapToMap(tmp, SPS_Accuracy, SPS_AreaMaps);
{$ELSE}
SPS_AreaMaps := SPS_BitmapToMap(tmp, SPS_Accuracy);
{$ENDIF}

if (surface = RUNESCAPE_SURFACE) then
SPS_Areas := SPS_SortAreas(areas)
else
if (surface = RUNESCAPE_OTHER) then
SPS_Areas := areas;

tmp.free();

end else
writeln('SPS_Setup(): ERROR: SPS areas are not set!');

t := (getSystemTime - t);

if (SPS_Debug) and (result) then
writeln('[SPS] SPS_Setup() took '+toStr(t)+' ms. Areas: '+toStr(SPS_Areas));
end;

rj
09-26-2013, 10:28 PM
...

Can you show me the script your trying to run?

Twinki
09-26-2013, 10:29 PM
Can you show me the script your trying to run?

This was just for testing the path, to see if it worked

Program TestPath;
{$i srl/srl.Simba}
{$I RL_SPS.Simba}

var

testpath: tpointarray;


begin
testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
SPS_WalkPath(testpath);
end.

rj
09-26-2013, 10:39 PM
This was just for testing the path, to see if it worked

Program TestPath;
{$i srl/srl.Simba}
{$I RL_SPS.Simba}

var

testpath: tpointarray;


begin
testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
SPS_WalkPath(testpath);
end.

Try

SPS_MatchesPercent := 0.45;
SPS_Tolerance := 500.000;

Twinki
09-26-2013, 10:47 PM
Try

SPS_MatchesPercent := 0.45;
SPS_Tolerance := 500.000;

Nope :(

I am new
09-26-2013, 10:56 PM
FilterTPAsbetween unknown identifier. I feel so clueless... tried to google filterin them but no luck


function rsps_uptext:string;
var
TPA: tpointarray;
ATPA: t2dpointarray;
begin
FindColorsTolerance(TPA, 13883407, 43, 14, 69, 23, 7);
if (length(TPA) > 1) then
begin
ATPA := splitTPAEx(TPA, 1, 10);
FilterTPAsbetween(ATPA, 1, 10);
sortATPAFromFirstPointX(ATPA, point(0, 0));
result:= StrToInt(getTextATPA(ATPA, 5, 'UpChars07'));
end;
end;
Ah I guess I don't have the version with that function. trying it with this
https://github.com/MerlijnWajer/Simba

rj
09-26-2013, 11:20 PM
FilterTPAsbetween unknown identifier. I feel so clueless... tried to google filterin them but no luck


function rsps_uptext:string;
var
TPA: tpointarray;
ATPA: t2dpointarray;
begin
FindColorsTolerance(TPA, 13883407, 43, 14, 69, 23, 7);
if (length(TPA) > 1) then
begin
ATPA := splitTPAEx(TPA, 1, 10);
FilterTPAsbetween(ATPA, 1, 10);
sortATPAFromFirstPointX(ATPA, point(0, 0));
result:= StrToInt(getTextATPA(ATPA, 5, 'UpChars07'));
end;
end;
Ah I guess I don't have the version with that function. trying it with this
https://github.com/MerlijnWajer/Simba

woops remove that part

Twinki
09-26-2013, 11:32 PM
Try

SPS_MatchesPercent := 0.45;
SPS_Tolerance := 500.000;
Didn't fix it... :(
Wow nothing seems to work... Tried SPS_RotateMinimap and it doesn't work either

rj
09-26-2013, 11:39 PM
Didn't fix it... :(
Wow nothing seems to work... Tried SPS_RotateMinimap and it doesn't work either

Are you sure you are getting the correct compass angle?

I am new
09-26-2013, 11:40 PM
can't delete post this was irrelevant :Z

Twinki
09-26-2013, 11:42 PM
Are you sure you are getting the correct compass angle?
Pretty positive, do you want to TeamView and check?

I am new
09-26-2013, 11:47 PM
Got it working thanks alot.

rj
09-26-2013, 11:52 PM
Pretty positive, do you want to TeamView and check?

Post your SPS image and I'll get back to you in a few

Twinki
09-26-2013, 11:56 PM
Post your SPS image and I'll get back to you in a few

22247

rj
09-27-2013, 12:06 AM
22247

woah did you make that image at perfect north?

Twinki
09-27-2013, 12:07 AM
woah did you make that image at perfect north?
Oh.... Sec leme do it again :duh:

Twinki
09-27-2013, 12:46 AM
woah did you make that image at perfect north?

22248

Still doesn't work :(

rj
09-27-2013, 01:05 AM
22248

Still doesn't work :(

Grr don't have time tonight gotta study I may have a little time tomorrow make a thread in the help section and see if you have luck there because I won't be able to get on until briefly tomorrow at 3:00 eastern and then at 11:00 PM

Twinki
09-27-2013, 01:07 AM
Grr don't have time tonight gotta study I may have a little time tomorrow make a thread in the help section and see if you have luck there because I won't be able to get on until briefly tomorrow at 3:00 eastern and then at 11:00 PM

Whenever you have time just PM me, I'm not doing anything but this for like a week lol.