From: Thanatos
I believe that page is members+
Ah yes indeed it is… I'll post it here:
First off, I worked really hard on this believe it or not, so if you use it in a script please do give credits… With that being said, thanks again Markus for helping me with that 'Range check error'. :duh:
What this function does is finds available (not in combat) NPCs on your screen (based on your input), and returns a TPA with each point containing the middle of each of those NPCs, sorted from the center of the screen.
Some examples of beta tests on Giant Rats behind Lumbridge castle: (Using CTS3, for what it's worth)


I explained out
exactly how this function works, so maybe it would be good for some to learn from. The parameters are obvious, and if you're reading this post then you've already proven you have enough knowledge to understand what each parameter means, if not just ask questions here. For the record, I already know that it's a bit messy. :p
Function FindFreeTargets(Color, Tol, CTS, MinCount, Width, Height: Integer): TPointArray;
var
NPCBox,HPZone: TBox;
TopPoint,MiddleHPZone,
MiddleNPCBox: TPoint;
TPA,GreenPointsA,RedPointsA,
GreenPointsB,RedPointsB,
RTPA: TPointArray;
L,i,CTS_Old,R: Integer;
ATPA: T2DPointArray;
begin
CTS_Old := GetColorToleranceSpeed;
{Find NPC colors}
ColorToleranceSpeed(CTS);
FindColorsSpiralTolerance(MSCX, MSCY, TPA, Color, MSX1, MSY1, MSX2, MSY2, Tol);
if (Length(TPA) < 1) then
begin
ColorToleranceSpeed(CTS_Old);
Exit;
end;
{Split TPA's into boxes defined by 'Width' & 'Height'}
ATPA := SplitTPAEx(TPA, Width, Height); //In this instance, I prefer SplitTPA
L := High(ATPA);
SetArrayLength(ATPA, L+1);
{Loop through each box}
for i := 0 to L do
begin
{If the # of color points found inside the box is >= to 'MinCount'}
if (Length(ATPA[i]) >= MinCount) then
NPCBox := GetTPABounds(ATPA[i]);
{Inside each valid NPC box}
with NPCBox do
begin
{Get middle top point of the box}
TopPoint := Point(((NPCBox.X1+NPCBox.X2)/2), NPCBox.Y1);
if (TopPoint.X < MSX1) then
TopPoint.X := MSX1;
if (TopPoint.Y < MSY1) then
TopPoint.Y := MSY1;
{Using 'TopPoint', specify a static region in which a health bar would be present}
HPZone := IntToBox(TopPoint.X-30, TopPoint.Y-40, TopPoint.X+30, TopPoint.Y);
if (HPZone.X1 < MSX1) then
HPZone.X1 := MSX1;
if (HPZone.X2 > MSX2) then
HPZone.X2 := MSX2;
if (HPZone.Y1 < MSY1) then
HPZone.Y1 := MSY1;
if (HPZone.Y2 > MSY2) then
HPZone.Y1 := MSY2;
{These two aren't really needed}
MiddleHPZone := Point(((HPZone.x1+HPZone.x2)/2), ((HPZone.y1+HPZone.y2)/2));
MiddleNPCBox := Point(((NPCBox.x1+NPCBox.x2)/2), ((NPCBox.y1+NPCBox.y2)/2));
{Search within both the 'NPCBox' and the HPZone for both red & green colors}
ColorToleranceSpeed(3);
FindColorsSpiralTolerance(MiddleNPCBox.X, MiddleNPCBox.Y, GreenPointsA, 49242, NPCBox.X1, NPCBox.Y1, NPCBox.X2, NPCBox.Y2, 2);
FindColorsSpiralTolerance(MiddleNPCBox.X, MiddleNPCBox.Y, RedPointsA, 524459, NPCBox.X1, NPCBox.Y1, NPCBox.X2, NPCBox.Y2, 2);
FindColorsSpiralTolerance(MiddleHPZone.X, MiddleHPZone.Y, GreenPointsB, 49242, HPZone.X1, HPZone.Y1, HPZone.X2, HPZone.Y2, 2);
FindColorsSpiralTolerance(MiddleHPZone.X, MiddleHPZone.Y, RedPointsB, 524459, HPZone.X1, HPZone.Y1, HPZone.X2, HPZone.Y2, 2);
ColorToleranceSpeed(CTS_Old);
{If no red or green is found within the NPCBox and HPZone}
if ((Length(GreenPointsA) = 0) and (Length(RedPointsA) = 0)
and (Length(GreenPointsB) = 0) and (Length(RedPointsB) = 0)) then
begin
{Add the center of the NPCBox to 'RTPA'}
SetArrayLength(RTPA, (Length(RTPA)+1));
RTPA[R] := MiddleNPCBox;
Inc(R);
end;
end;
end;
{Sort the 'RTPA' from the center of the screen}
SortTPAFrom(RTPA, Point(MSCX, MSCY));
{RTPA now holds the center point for each NPCBox of 'avaiable' targets}
Result := RTPA;
end;
Here's a quick script I threw together to fight level 10 Minotaurs in Stronghold of Security:
program MinotaurMasher;
{$DEFINE SRL5}
{$DEFINE SMART}
{$i SRL/srl.simba}
{$i SRL/SRL/misc/paintsmart.simba}
Const
WeaponSpeed = 'Fast';
Training = 'Strength';
HPLevel = 80;
Var
KillCount,Exp,HPExp,
WeaponTimer: Integer;
Procedure DeclarePlayers;
begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;
with Players[0] do
begin
Name := '';
Pass := '';
Level[SKILL_HITPOINTS] := HPLevel;
BoxRewards := ['XP','xp','lamp'];
LampSkill := 'Mining';
Active := True;
end;
end;
Procedure LoadVars;
begin
case Lowercase(WeaponSpeed) of
'fast': WeaponTimer := 800;
'normal': WeaponTimer := 1500;
'slow': WeaponTimer := 3000;
end;
end;
Procedure OnScreen;
var
XPH,XPH2,TTB,
KPH: Integer;
begin
XPH := Round((Exp * 3600) / (GetTimeRunning / 1000));
XPH2 := Round((HPExp * 3600) / (GetTimeRunning / 1000));
KPH := Round((KillCount * 3600) / (GetTimeRunning / 1000));
//TTB := (((w) + (y) + BreakRounds)-GetTimeRunning);
SMART_DrawTextMulti(True, True, ['Minotaur Masher 1.0 by Flight','',
''+MsToTime(GetTimeRunning, Time_Abbrev),'',
''+Capitalize(Training)+' XP: '+IntToStr(Exp)+' ('+IntToStr(XPH)+' / hour)','',
'Hitpoints XP: '+IntToStr(HPExp)+' ('+IntToStr(XPH2)+' / hour)','',
'Kills: '+IntToStr(KillCount)+' ('+IntToStr(KPH)+' / hour)'],
Point(10, 200), SmallCharsNS, 16777215);
//SMART_DrawTextMulti(False, True, ['Time till break: '+MsToTime(TTB,Time_Bare)], Point(570, 445), SmallCharsNS, 65280);
end;
Procedure HumanMMouse(eX, eY, ranX, ranY: Integer);
var
randSpeed: extended;
X,Y,X2,Y2,A,Dist,MP: integer;
begin
A := MouseSpeed;
GetMousePos(X, Y);
Dist := Distance(X, Y, eX, eY);
MP := Round(Dist/150);
if MP < 0 then
MP := 1;
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
X2 := RandomRange(eX-(A*MP), eX+(A*MP));
Y2 := RandomRange(eY-(A*MP), eY+(A*MP));
WindMouse(X, Y, X2, Y2, 11, 8, 10.0 / randSpeed, 12.0 / randSpeed, 10.0 * randSpeed, 10.0 * randSpeed);
GetMousePos(X, Y);
MMouse(eX, eY, ranX, ranY);
MouseSpeed := A;
end;
Procedure HumanRandomMouse;
var
randSpeed: extended;
x, y, firstSpeed: integer;
begin
case(Random(10)) of
2..8:
begin
firstSpeed := mouseSpeed;
mouseSpeed := RandomRange(5,10);
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
GetMousePos(x, y);
WindMouse(x, y, RandomRange(x - 75, x + 75), RandomRange(y - 75, y + 75),
30, 55, 10.0 / randSpeed, 12.0 / randSpeed, 10.0 * randSpeed, 10.0 * randSpeed);
mouseSpeed := firstSpeed;
end;
end;
end;
Function IsMoving_F: Boolean;
begin
Result := PixelShift(IntToBox(MMCX-30, MMCY-30, MMCX+30, MMCY+30), 200) > 200;
end;
Function Attacking: Boolean;
var
PBox: TBox;
begin
PBox := IntToBox(245, 135, 280, 185);
Result := (AveragePixelShift(PBox, 250, 500) > 500);
end;
Procedure GetShiftCount;
var
PBox: TBox;
begin
PBox := IntToBox(245, 135, 280, 185);
Writeln(IntToStr(AveragePixelShift(PBox, 250, 500)));
end;
Function DidAntiban: Boolean;
var
i: Integer;
begin
Result := False;
if not LoggedIn then Exit;
i := Random(450);
case i of
1..45:
begin
HumanRandomMouse;
Result := True;
end;
46:
begin
HoverSkill('Strength', False);
Result := True;
end;
47:
begin
HoverSkill('Attack', False);
Result := True;
end;
48:
begin
HoverSkill('Hitpoints', False);
Result := True;
end;
49..450: Exit;
end;
end;
Function Eat: Boolean;
var
i: Integer;
begin
Result := False;
if Not LoggedIn then Exit;
if InvEmpty then Exit;
if (HPPercent >= 60) then Exit;
for i := 0 to 28 do
begin
FindNormalRandoms;
if ExistsItem(i) then
begin
InvMouse(i, mouse_move);
if WaitUpText('Eat', 300) then
begin
ClickMouse2(True);
Wait(RandomRange(875, 990));
if (HPPercent >= 90) then
Exit;
end;
if (i = 28) then
Exit;
end;
end;
end;
Function FindFreeTargets(Color, Tol, CTS, MinCount, Width, Height: Integer): TPointArray;
var
NPCBox,HPZone: TBox;
TopPoint,MiddleHPZone,
MiddleNPCBox: TPoint;
TPA,GreenPointsA,RedPointsA,
GreenPointsB,RedPointsB,
RTPA: TPointArray;
L,i,CTS_Old,R: Integer;
ATPA: T2DPointArray;
begin
CTS_Old := GetColorToleranceSpeed;
{Find NPC colors}
ColorToleranceSpeed(CTS);
FindColorsSpiralTolerance(MSCX, MSCY, TPA, Color, MSX1, MSY1, MSX2, MSY2, Tol);
if (Length(TPA) < 1) then
begin
ColorToleranceSpeed(CTS_Old);
Exit;
end;
{Split TPA's into boxes defined by 'Width' & 'Height'}
ATPA := SplitTPAEx(TPA, Width, Height);
L := High(ATPA);
SetArrayLength(ATPA, L+1);
{Loop through each box}
for i := 0 to L do
begin
{If the # of color points found inside the box is >= to 'MinCount'}
if (Length(ATPA[i]) >= MinCount) then
NPCBox := GetTPABounds(ATPA[i]);
{Inside each valid NPC box}
with NPCBox do
begin
{Get middle top point of the box}
TopPoint := Point(((NPCBox.X1+NPCBox.X2)/2), NPCBox.Y1);
if (TopPoint.X < MSX1) then
TopPoint.X := MSX1;
if (TopPoint.Y < MSY1) then
TopPoint.Y := MSY1;
{Using 'TopPoint', specify a static region in which a health bar would be present}
HPZone := IntToBox(TopPoint.X-30, TopPoint.Y-40, TopPoint.X+30, TopPoint.Y);
if (HPZone.X1 < MSX1) then
HPZone.X1 := MSX1;
if (HPZone.X2 > MSX2) then
HPZone.X2 := MSX2;
if (HPZone.Y1 < MSY1) then
HPZone.Y1 := MSY1;
if (HPZone.Y2 > MSY2) then
HPZone.Y1 := MSY2;
{These two aren't really needed}
MiddleHPZone := Point(((HPZone.x1+HPZone.x2)/2), ((HPZone.y1+HPZone.y2)/2));
MiddleNPCBox := Point(((NPCBox.x1+NPCBox.x2)/2), ((NPCBox.y1+NPCBox.y2)/2));
{Search within both the 'NPCBox' and the HPZone for both red & green colors}
ColorToleranceSpeed(3);
FindColorsSpiralTolerance(MiddleNPCBox.X, MiddleNPCBox.Y, GreenPointsA, 49242, NPCBox.X1, NPCBox.Y1, NPCBox.X2, NPCBox.Y2, 2);
FindColorsSpiralTolerance(MiddleNPCBox.X, MiddleNPCBox.Y, RedPointsA, 524459, NPCBox.X1, NPCBox.Y1, NPCBox.X2, NPCBox.Y2, 2);
FindColorsSpiralTolerance(MiddleHPZone.X, MiddleHPZone.Y, GreenPointsB, 49242, HPZone.X1, HPZone.Y1, HPZone.X2, HPZone.Y2, 2);
FindColorsSpiralTolerance(MiddleHPZone.X, MiddleHPZone.Y, RedPointsB, 524459, HPZone.X1, HPZone.Y1, HPZone.X2, HPZone.Y2, 2);
ColorToleranceSpeed(CTS_Old);
{If no red or green is found within the NPCBox and HPZone}
if ((Length(GreenPointsA) = 0) and (Length(RedPointsA) = 0)
and (Length(GreenPointsB) = 0) and (Length(RedPointsB) = 0)) then
begin
{Add the center of the NPCBox to 'RTPA'}
SetArrayLength(RTPA, (Length(RTPA)+1));
RTPA[R] := MiddleNPCBox;
Inc(R);
end;
end;
end;
{Sort the 'RTPA' from the center of the screen}
SortTPAFrom(RTPA, Point(MSCX, MSCY));
{RTPA now holds the center point for each NPCBox of 'avaiable' targets}
Result := RTPA;
end;
procedure AttackMinotaur;
var
T: Integer;
GoOn: Boolean;
TPA: TPointArray;
label
Search;
begin
if not LoggedIn then Exit;
Eat;
Search:
GoOn := False;
MouseSpeed := RandomRange(14, 22);
TPA := FindFreeTargets(10594473, 3, 3, 10, 20, 20);
if (Length(TPA) > 0) then
begin
HumanMMouse(TPA[0].X, TPA[0].Y, 5, 5);
if WaitUpTextMulti(['ck M','inot', 'taur'], 300) then
begin
ClickMouse2(True);
if not DidRedClick then
goto Search;
end else
goto Search;
FFlag(0);
While IsMoving_F do
Wait(1);
MarkTime(T);
repeat
if not LoggedIn then Exit;
FindNormalRandoms;
if (TimeFromMark(T) > 3000) then
Exit;
if Attacking then
break;
if FindBlackChatMessage('omeone else is fighting') then
break;
until(false)
if FindBlackChatMessage('omeone else is fighting') then
goto Search;
GoOn := True;
MarkTime(T);
repeat
if not LoggedIn then Exit;
FindNormalRandoms;
Eat;
//if (Attacking or DidAntiBan) then
if Attacking then
MarkTime(T);
if (TimeFromMark(T) > WeaponTimer) then
break;
until(false)
if GoOn then
begin
GoOn := False;
Inc(KillCount);
IncEx(Exp, 40);
IncEx(HPExp, 14);
//Inc(KillCount_C);
OnScreen;
end;
end;
end;
begin
Smart_Server := 86;
Smart_Members := True;
Smart_Signed := True;
Smart_SuperDetail := False;
setupSRL();
DeclarePlayers;
LoadVars;
Smart_ClearCanvas;
Wait(RandomRange(500, 675));
OnScreen;
Repeat
//GetShiftCount;
if not LoggedIn then
begin
LoginPlayer;
ClickNorth(SRL_ANGLE_HIGH);
end;
FindNormalRandoms;
AttackMinotaur;
Until(False)
end.