Simba Code:
{$loadlib sps}
{$include_once srl-6/lib/interfaces/minimap.simba}
{$include_once srl-6/lib/core/debug.simba}
{$include_once srl-6/lib/core/players.simba}
{$include_once srl-6/lib/utilities/drawing.simba}
type
TSPSArea = record
__mapPath: string;
__areaMap: T3DIntegerArray;
_accuracy: integer;
_tolerance, _minMatchPercent: extended;
isSetup: boolean;
end;
const
SPS_IMG_PATH = IncludePath + 'SPS\img\';
SPS_IMG_FMT = '.png';
const
RUNESCAPE_SURFACE = 'runescape_surface\';
RUNESCAPE_OTHER = 'runescape_other\';
const
__DEFAULT_ACCURACY: integer = 4;
__DEFAULT_TOLERANCE: extended = 600.0;
__DEFAULT_MIN_MATCH_PERCENT: extended = 0.40;
var
spsAnyAngle: boolean = false;
spsMultiMouse: boolean = true;
var
sps: TSPSArea;
(*
Returns the name of the TSPSArea variable.
Example:
writeln(sps.getName());
*)
function TSPSArea.getName(): string;
begin
result := GetGlobalName(@Self);
end;
(*
Loads and setups the TSPSArea.
Example:
sps.setup('my_map_name', RUNESCAPE_SURFACE, 4, 600.0, 0.40);
Example using default params:
sps.setup('my_map_name', RUNESCAPE_SURFACE);
*)
procedure TSPSArea.setup(imgName, imgFolder: string; accuracy: integer = __DEFAULT_ACCURACY; tolerance: extended = __DEFAULT_TOLERANCE; minMatchPercent: extended = __DEFAULT_MIN_MATCH_PERCENT);
var
bmp: TMufasaBitmap;
t: integer;
m: extended;
begin
print(self.getName()+'.init()', TDebug.HEADER);
t := getSystemTime();
if (fileExists(SPS_IMG_PATH + imgFolder + imgName + SPS_IMG_FMT)) then
begin
print('Path exists ('+SPS_IMG_PATH + imgFolder + imgName + SPS_IMG_FMT+')');
self._accuracy := accuracy;
self._tolerance := tolerance;
self._minMatchPercent := minMatchPercent;
self.__mapPath := SPS_IMG_PATH + imgFolder + imgName + SPS_IMG_FMT;
SetLength(self.__areaMap, 0);
if (spsAnyAngle) then
self._minMatchPercent := 0.10;
try
bmp.init(client.getMBitmaps());
bmp.loadFromFile(self.__mapPath);
SPS_BitmapToMap(bmp, self._accuracy, self.__areaMap);
except
print(self.getName()+'.setup(): Unable to load map or bitmap to map failed', TDebug.FATAL);
finally
bmp.free();
end;
self.isSetup := true;
end else
print(self.getName()+'.setup(): Unable to find map, searched path '+ SPS_IMG_PATH + imgFolder + imgName + SPS_IMG_FMT, TDebug.FATAL);
print('Setup area "' + imgName + '" in ' + intToStr(getSystemTime() - t) + 'ms');
print(self.getName()+'.init()', TDebug.FOOTER);
end;
(*
Gathers a 140x140 bitmap of the minimap.
Example:
bmp := SPS_GatherMinimap(true, 50.0);
*)
function SPS_GatherMinimap(const rotated: boolean; const deg: extended): TMufasaBitmap;
var
temp: TMufasaBitmap;
begin
result.init();
if (rotated) and (inRange(deg, 10.0, 350.0)) then
begin
temp.init();
try
temp.copyClientToBitmap(client.getIOManager(), true, minimap.cx - 70, minimap.cy - 70, minimap.cx + 70, minimap.cy + 70);
temp.rotateBitmap(radians(deg), result);
finally
temp.free();
end;
end else
result.copyClientToBitmap(client.getIOManager(), true, minimap.cx - 70, minimap.cy - 70, minimap.cx + 70, minimap.cy + 70);
Result.ReplaceColor(0, 1);
end;
(*
Debugs your players postion on the loaded map.
Example:
sps.debugPlayerPos();
*)
procedure TSPSArea.debugPlayerPos();
var
b: TBox;
bmp, w, h, t, timeTook: integer;
mid, pos: TPoint;
mbp : TMufasaBitmap;
begin
t := getSystemTime();
pos := self.getPlayerPos();
timeTook := (getSystemTime() - t);
if (pos.equals(point(-1, -1))) or (not isLoggedIn()) then
exit();
bmp := loadBitmap(self.__mapPath);
if (bitmapExists(bmp)) then
begin
getBitmapSize(bmp, w, h);
dec(w);
dec(h);
try // draw player pos, the minimap area and crop the bitmap
mbp := getMufasaBitmap(bmp);
mbp.drawCircle(pos, 2 , true, clLime);
mbp.drawBox(intToBox(max(1, pos.x - 70), max(1, pos.y - 70),
min(w, pos.x + 70), min(h, pos.y + 70)), false, clLime);
cropBitmap(bmp, max(1, pos.x - 150), max(1, pos.y - 150), min(w, pos.x + 150), min(h, pos.y + 150));
except
print('Exception on drawing/cropping TSPSArea.debugPlayerPos()', TDebug.ERROR);
end;
getBitmapSize(bmp, w, h);
setBitmapSize(bmp, mbp.getWidth() + 160, mbp.getHeight()); // add more width so we can print infomation on
mbp.copyClientToBitmap(client.getIOManager(), false, w + 10, 10, // draw picture of client on bitmap
minimap.cx - 70, minimap.cy - 70, minimap.cx + 70, minimap.cy + 70);
mbp.drawText('Map: '+between('\', '.', between('runescape_', 'png', self.__mapPath)), point(w + 10, 160), clRed); // draw infomation
mbp.drawText('Pos: ('+toStr(pos.x) + ', '+toStr(pos.y) + ')', point(w + 10, 180), clRed);
mbp.drawText('Took: '+toStr(timeTook) + 'ms', point(w + 10, 200), clRed);
debugBitmap(bmp);
freeBitmap(bmp);
end;
end;
(*
Gets the players postion.
Example:
writeln(sps.getPlayerPos());
*)
function TSPSArea.getPlayerPos(): TPoint;
var
foundMatches, wid, hei, t: integer;
bmp: TMufasaBitmap;
map: T3DIntegerArray;
p: TPoint;
searches, a: extended;
begin
result := [-1, -1];
if (not isLoggedIn()) then
exit();
if (not self.isSetup) then
begin
print('Unable to get players postion, sps isn''t setup', TDebug.ERROR);
exit();
end;
t := getSystemTime();
a := minimap.getAngleDegrees();
if (inRange(a, 10.0, 350.0)) and (not spsAnyAngle) then
begin
print(self.getName()+'.getPlayerPos(): Angle is at '+floatToStr(a)+', Setting angle to 0 degrees');
minimap.clickCompass();
// mainScreen.setAngle(MS_ANGLE_HIGH);
end;
bmp := SPS_GatherMinimap(spsAnyAngle, a);
wid := bmp.getWidth();
hei := bmp.getHeight();
SPS_BitmapToMap(bmp, self._accuracy, map);
if (length(map) > 0) then
begin
foundMatches := SPS_FindMapInMap(p.x, p.y, self.__areaMap, map, self._tolerance);
searches := ((wid / self._accuracy) * (hei / self._accuracy));
if ((foundMatches / searches) > self._minMatchPercent) then
begin
result.x := (p.x * self._accuracy + (wid div 2));
result.y := (p.y * self._accuracy + (wid div 2));
end else
print(self.getName()+'.getPlayerPos(): Didn''t find enough matches accurately calc your postion', TDebug.WARNING);
end;
bmp.free();
if (result = [-1, -1]) then
writeLn('Failed finding position');
print(self.getName()+'.getPlayerPos(): result = ' + toStr(result) + ', took ' + intToStr(getSystemTime() - t) + ' ms');
end;
(*
Converts a postion onto the minimap, based on the players pos.
Example:
SPS_PosToMM(point(50, 50), sps.getPlayerPos(), p);
*)
function SPS_PosToMM(pos, playerPos: TPoint; out res: TPoint): boolean;
var
a: extended;
begin
if (spsAnyAngle) then
begin
a := minimap.getAngleRadians();
if (not inRange(degrees(a), 8, 352)) then // no need to rotate
res := Point(minimap.cx + pos.x - playerPos.x, minimap.cy + pos.y - playerPos.y)
else
res := rotatePoint(Point(minimap.cx + pos.x - playerPos.x, minimap.cy + pos.y - playerPos.y), a, minimap.cx, minimap.cy);
end else
res := Point(minimap.cx + pos.x - playerPos.x, minimap.cy + pos.y - playerPos.y);
result := minimap.isPointOn(res);
if (not result) then
res := [-1, -1];
end;
(*
Walks to postion 'pos', judged on the players postion.
Example:
sps.walkToPos(point(250, 250), sps.getPlayerPos());
*)
function TSPSArea.walkToPos(pos: TPoint; playerPos: TPoint; waitMoving: Boolean = True; shiftInterval: Integer = 500): boolean;
var
p: TPoint;
begin
result := false;
if (SPS_PosToMM(pos, playerPos, p)) then
begin
result := true;
// if distance is less than 10 then there is no real point walking.
if (distance(p, minimap.getCenterPoint()) < 10) then
exit;
if (spsMultiMouse) then
multiClick(p, 25, 3)
else
mouse(p, MOUSE_LEFT);
if waitMoving then
begin
if (minimap.isFlagPresent(3000 + random(500))) then
minimap.waitPlayerMoving(shiftInterval);
if (minimap.isFlagPresent()) then //case failed
minimap.waitPlayerMoving(shiftInterval);
end;
end;
print(self.getName()+'.walkToPos(): result = '+boolToStr(result));
end;
(*
Overloaded function, reqiures no playerPos var, will automaticly call self.getPlayerPos().
Example:
sps.walkToPos(point(250, 250));
*)
function TSPSArea.walkToPos(pos: TPoint): boolean; overload;
begin
result := self.walkToPos(pos, self.getPlayerPos());
end;
(*
Overloaded function, reqiures no playerPos var, will automaticly call
self.getPlayerPos(), but has waitMoving parameter.
Example:
sps.walkToPos(point(250, 250));
*)
function TSPSArea.walkToPos(pos: TPoint; waitMoving: Boolean): boolean; overload;
begin
result := self.walkToPos(pos, self.getPlayerPos(), waitMoving);
end;
(*
Walks a path of points.
Example:
sps.walkPath([point(50, 50), point(100, 100)]);
sps.walkPath(PathToBank);
sps.walkPath(PathToBank, False); // Won't wait until the player is not moving
*)
function TSPSArea.walkPath(path: TPointArray; waitMoving: Boolean = True; shiftInterval: Integer = 500): boolean;
var
p, lastPos, mmPoint: TPoint;
t, fails, h, l, i: integer;
begin
result := false;;
h := high(path);
l := low(path);
t := (getSystemTime() + randomRange(15000, 20000));
repeat
if (not isLoggedIn()) then
exit(false);
p := self.getPlayerPos();
for i := h downto l do
if (SPS_PosToMM(path[i], p, mmPoint)) then
begin
if (distance(minimap.getCenterPoint(), mmPoint) >= 10) then
begin
if (spsMultiMouse) then
multiClick(mmPoint, 25, 3)
else
mouse(mmPoint, MOUSE_LEFT);
if (minimap.isFlagPresent(2500 + random(500))) then
minimap.waitFlag(10 + random(25));
end;
t := (getSystemTime() + randomRange(15000, 20000));
result := (i = h) or (distance(path[i], path[h]) < 10);
if (result) then
break(2)
else
break();
end;
if (p.x = lastPos.x) and (p.y = lastPos.y) then
inc(fails);
lastPos := p;
until (getSystemTime() > t) or (fails > 5);
if waitMoving then
if (minimap.isFlagPresent() or minimap.isPlayerMoving()) then
minimap.waitPlayerMoving(shiftInterval);
print(self.getName()+'.walkPath(): result = '+boolToStr(result));
end;
(*
Walks blindly to point 'pos'.
Example:
sps.blindWalk(point(50, 50));
*)
function TSPSArea.blindWalk(pos: TPoint): boolean;
var
tries: integer;
ctrlPoints: TPointArray;
p: TPoint;
begin
result := false;
repeat
if (not isLoggedIn()) then
exit();
p := self.getPlayerPos();
inc(tries);
if ((tries) > 10) then
break();
until (not p.equals([-1, -1]));
if (tries <= 10) then
begin
ctrlPoints := TPABetweenPoints(p, pos, 15 + random(25), 15);
result := self.walkPath(ctrlPoints);
end;
print(self.getName()+'.blindWalk(): result = '+boolToStr(result));
end;
(*
Returns true if the player is inside the TBox 'box'
Example:
myArea := intToBox(10, 10, 100, 150);
sps.isInBox(myArea);
*)
function TSPSArea.isInBox(box: TBox): boolean;
begin
result := PointInBox(self.getPlayerPos(), box);
print(self.getName() + '.isInBox: result = ' + boolToStr(result));
end;
(*
Returns true if the player is inside the TBox **b**, if not it'll walk towards
the center of the box.
Example:
fishArea := intToBox(10, 10, 100, 150);
if sps.walkToBox(fishArea) then
doSomeFishing();
*)
function TSPSArea.walkToBox(b: tbox): boolean;
var
pos: TPoint;
x, y: integer;
begin
pos := self.getPlayerPos();
if (pos.x = -1) or (pos.y = -1) then
exit(false);
result := pointInBox(pos, b);
if (not result) then
begin
x := randomRange(0, gaussBox(b).x - pos.x);
if (x > 75) then
x := randomRange(65, 75)
else if (x < -75) then
x := randomRange(-65, -75)
else if inRange(x, 1, 10) then
x := randomRange(10, 20)
else if inRange(x, -1, -10) then
x := randomRange(-10, -20);
y := randomRange(0, gaussBox(b).y - pos.y);
if (y > 75) then
y := randomRange(65, 75)
else if (y < -75) then
y := randomRange(-65, -75)
else if inRange(y, 1, 10) then
y := randomRange(10, 20)
else if inRange(y, -1, -10) then
y := randomRange(-10, -20);
self.walkToPos(point(pos.x + x, pos.y + y), false);
end;
print('TSPSArea.walkToBox(): Result = ' + boolToStr(result));
end;
(*
Returns true if the player is inside the TBox **b**, if not it'll walk towards
the center of the box. But will repeat untill **waitTime** has been reached.
Example:
fishArea := intToBox(10, 10, 100, 150);
if sps.walkToBox(fishArea, randomRange(5000, 7000)) then
doSomeFishing();
*)
function TSPSArea.walkToBox(b: tbox; waitTime: integer): boolean; overload;
var
t: TCountDown;
pos: TPoint;
begin
t.setTime(waitTime);
repeat
result := self.walkToBox(b);
if (not result) then
wait(randomRange(1200, 1800));
until result or t.isFinished();
print('TSPSArea.walkToBox(): Result = ' + boolToStr(result));
end;
(*
Returns true if the player is inside the polygon 'polygon'
Example:
myPoly := [Point(10, 10), Point(15, 10), Point(25, 20)];
sps.isInPolygon(myPoly);
*)
function TSPSArea.isInPolygon(polygon: TPointArray): boolean;
var
p: TPoint;
i, j: integer;
begin
result := false;
if (length(polygon) < 3) then
begin
print(self.getName() + '.isInPolygon: less than 3 vertice points in TPA', TDebug.ERROR);
exit;
end;
p := self.getPlayerPos();
j := high(polygon);
for i := low(polygon) to high(polygon) do
begin
if ((((polygon[i].y <= p.y) and (p.y < polygon[j].y)) or ((polygon[j].y <= p.y) and
(p.y < polygon[i].y)) ) and (p.x < ((polygon[j].x - polygon[i].x) *
(p.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x))) then
result := not result;
j := i;
end;
print(self.getName() + '.isInPolygon: result = ' + boolToStr(result));
end;