A Low-Down on Wizzy Plugin and TPA's
Table Of Contents
I - Intro.
II - Functions/Procedures of Wizzy Plugin and explanation.
III - Usage in Runescape (nearly said 'real life', lol ).
IV - End Note and Credits + Links to good tutorials.
I - Intro.
WizzyPlugin contains many functions relating to arrays, mainly arrays of TPoints, and TPoints. It is one of the most used plugins in TPA finding. WizzyPlugin is a plugin made in Delphi. Believe me, it isn't really that hard to figure it out, most of the stuff in there is easy to understand by looking at the comments. However, I had nothing else to do with my spare time, so I thought this would be mildly entertaining - for me, that is.
So you may ask, why are the functions contained in a plugin. Well, mixster say:
<mixster> Most stuff in WizzyPlugin can be time consuming, so placing in a plugin makes a huge difference in speed.
<NaumanAkhlaQ> can I quote you?
<mixster> No
II - Functions/Procedures of Wizzy Plugin and explanation.
OMG WizzyPlugin!! Eeeek!
That's how I felt after looking at it in the past. After many years (2) of shunning it aside, I decided it would be wise to tackle it. After understanding it I thought I might explain it. So without further chit-chat, lets get stuck in
The functions in WizzyPlugin are..
SCAR Code:
// * procedure tSwap(var a, b: TPoint);
// * procedure tpaSwap(var a, b: TPointArray);
// * procedure SwapE(var a, b: Extended);
// * procedure RAaSTPAEx(var a: TPointArray; const w, h: Integer);
// * procedure RAaSTPA(var a: TPointArray; const Dist: Integer);
// * function NearbyPointInArrayEx(const P: TPoint; w, h:Integer; a: TPointArray): Boolean;
// * function NearbyPointInArray(const P: TPoint; Dist:Integer; a: TPointArray): Boolean;
// * function ReArrangeandShortenArrayEx(a: TPointArray; w, h: Integer): TPointArray;
// * function ReArrangeandShortenArray(a: TPointArray; Dist: Integer): TPointArray;
// * function TPAtoATPAEx(TPA: TPointArray; w, h: Integer): T2DPointArray;
// * function TPAtoATPA(TPA: TPointArray; Dist: Integer): T2DPointArray;
// * procedure SortTPAFrom(var a: TPointArray; const From: TPoint);
// * procedure SortATPAFrom(var a: T2DPointArray; const From: TPoint);
// * procedure SortATPAFromFirstPoint(var a: T2DPointArray; const From: TPoint);
// * procedure InvertTPA(var a: TPointArray);
// * procedure InvertATPA(var a: T2DPointArray);
// * function MiddleTPAEx(TPA: TPointArray; var x, y: Integer): Boolean;
// * function MiddleTPA(tpa: TPointArray): TPoint;
// * procedure SortATPASize(var a: T2DPointArray; const BigFirst: Boolean);
// * procedure SortATPAFromSize(var a: T2DPointArray; const Size: Integer; CloseFirst: Boolean);
// * function CombineTPA(Ar1, Ar2: TPointArray): TPointArray;
// * function CombineIntArray(Ar1, Ar2: TIntegerArray): TIntegerArray;
// * function InIntArrayEx(a: TIntegerArray; var Where: Integer; const Number: Integer): Boolean;
// * function InIntArray(a: TIntegerArray; Number: Integer): Boolean;
// * procedure ClearSameIntegers(var a: TIntegerArray);
// * procedure ClearSameIntegersAndTPA(var a: TIntegerArray; var p: TPointArray);
// * function SplitTPAEx(arr: TPointArray; w, h: Integer): T2DPointArray;
// * function SplitTPA(arr: TPointArray; Dist: Integer): T2DPointArray;
// * procedure FilterPointsPie(var Points: TPointArray; const SD, ED, MinR, MaxR: Extended; Mx, My: Integer);
// * function RemoveDistTPointArray(x, y, dist: Integer; ThePoints: TPointArray; RemoveHigher: Boolean): TPointArray;
// * function GetTPABounds(TPA: TPointArray): TBox;
// * function FindTPAinTPA(SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
// * function FindTextTPAinTPA(Height : integer; SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
// * function FindGapsTPA(TPA: TPointArray; MinPixels: Integer): T2DPointArray;
// * Function CreateTPAFromBMP(BmpDC: HDC): TPointArray;
// * procedure SortCircleWise(var tpa: TPointArray; const mx, my, StartDegree, EndDegree: Integer; SortUp: Boolean);
// * procedure LinearSort(var tpa: TPointArray; const mx, my, Deg: Integer; SortUp: Boolean);
// * Function MergeATPA(ATPA : T2DPointArray) : TPointArray;
Note: This is the list from Dev Revision 211, Public Revision 37.
Okay, that is a huge list. So lets tackle it like boarding an aeroplane - 'one-at-a-time'.
tSwap
PHP Code:
{*******************************************************************************
procedure tSwap(var a, b: TPoint);
Description: Swaps the two TPoints.
*******************************************************************************}
This procedure swaps two TPoint data types.
For example, if Tp.x is 'a', and Tp.y is 'b' and you were to do this:
SCAR Code:
Var Tp : TPoint;
TP2 : TPoint;
Begin
TP := Point(1, 2);
TP2 := Point(10, 20);
TSwap(TP, TP2);
If Tp.x = 10 Then WriteLn('TP has switched with the values of TP2, and visa versa')
End.
It would replace TP with the value of TP2. Moreover, it would also replace TP2 with the value of TP; as shown in the above example.
Pretty Cool, Huh?
Not as cool as this baby:
tpaSwap
PHP Code:
{*******************************************************************************
procedure tpaSwap(var a, b: TPointArray);
Description: Swaps the two TPointArrays.
*******************************************************************************}
Like this procedure above, but this swaps arrays of TPoints, known as TPA's.
So taking TPA as 'a' and TPA2 as 'b', we can do this:
SCAR Code:
Var TPA, TPA2 : TPointArray;
Begin
TPA := [Point(7, 7), Point(8, 8)];
TPA2 := [Point(8, 8), Point(7, 7)];
TPASwap(TPA, TPA2);
If ((TPA[0].x = 8) and (TPA[0].y = 8)) Then WriteLn('Swap successful :)');
End.
It (the script) will swap the arrays so TPA will be equal to [Point(8, 8), Point(7, 7)]. Whereas TPA2 will be equal to [Point(7, 7), Point(8, 8)] .
SwapE
PHP Code:
{*******************************************************************************
procedure SwapE(var a, b: Extended);
Description: Swaps the two Extended values.
*******************************************************************************}
Does what it says on the Label, swaps two Extended (Decimal) values. Replaces the value of 'a' with the value of 'b' and visa versa.
Example:
SCAR Code:
Var Ex, Ex2 : Extended;
Begin
Ex := Pi;
Ex2 := Pi/2;
SwapE(Ex, Ex2);
If (Ex = (Pi/2)) Then WriteLn('Swapped');
End.
Pretty Neat Huh ??
This Kinda ends the Swapping part of WizzyPlugin, now lets go to the next part.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RAaSTPAEx
PHP Code:
{*******************************************************************************
procedure RAaSTPAEx(var a: TPointArray; const w, h: Integer);
Description: Leaves one point per box with side lengths W and H to the TPA.
*******************************************************************************}
Okay RAaSTPAEx does a really cool thing, it leaves one point in the box of w and H, With 'W' being width and 'H' being height:
Okay now, boys ans girls, look at this example script:
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, iAbs(ClBlue - ClWhite)+1, MIX1, MIY1, MIX2, MIY2, 0);
RAaSTPAEx(TPA, 26, 20);
//DebugTPA(Tpa, '');
End.
It modifies our array to only contain 1 point in a 26x20 box, remember this alters the TPA anyway so you do not need to assign it to a variable. So now time for pics:
The picture of the right is my inventory, and on the left is the result of the interrogation.
RAaSTPA
PHP Code:
{*******************************************************************************
procedure RAaSTPA(var a: TPointArray; const Dist: Integer);
Description: Leaves one point per box with the side length Dist.
*******************************************************************************}
This does what RAaSTPAEx does except it doesn't have the Width ('w') parameter. This means that it will make a circle of radius Dist around the point, in which not to have any points in.
Okay, boys and girls:
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, iAbs(ClBlue - ClWhite)+1, MIX1, MIY1, MIX2, MIY2, 0);
RAaSTPA(TPA, 20);
//DebugTPA(Tpa, '');
End.
Now time for the pic:
This has the same principle as the one before, except it has more points, why?
Well it does it in a 'circular' way. This means that less area is covered than a 20x20 box, hence more points.
NearbyPointInArrayEx
PHP Code:
{*******************************************************************************
function NearbyPointInArrayEx(const P: TPoint; w, h:Integer; a: TPointArray): Boolean;
Description: Returns true if the point P is near a point in the TPA a with the max X and Y distances W and H.
*******************************************************************************}
This uses the same 'Box' theory as RAaSTPAEx except it doesn't do what RAaTPAEx does. It checks if a point is near the point 'P', in a box of 'w' and 'h'; in the TPointArray 'a'. Since it is a function is gives an output. It happens to be a Boolean, so it outputs a true or false statement, depending on the query.
Sorry, cant give any good pics, however I can give you sample :
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, iAbs(ClBlue - ClWhite)+1, MIX1, MIY1, MIX2, MIY2, 0);
If NearbyPointInArrayEx(Point(MSCX, MSCY), 18, 27, TPA) Then
WriteLn('The mainscreen center is near the TPA, aborting!');
//DebugTPA(Tpa, '');
End.
This script will find if the mainscreen center (MSCX, MSCY) with a box of width 18 and height 28, is in the TPointArray 'TPA'. If it is, then it will result True.
NearbyPointInArray
PHP Code:
{*******************************************************************************
function NearbyPointInArray(const P: TPoint; Dist:Integer; a: TPointArray): Boolean;
Description: Returns true if the point P is near a point in the TPA a with the
max distance Dist.
*******************************************************************************}
This does what NearbyPointInArrayEx does except it doesn't have the Width ('w') parameter. This means that it will make a circle of radius 'Dist' around the point, so that the function can check if that cicle with the midpoint 'P' is in the TPA.
Okay, boys and girls:
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, iAbs(ClBlue - ClWhite)+1, MIX1, MIY1, MIX2, MIY2, 0);
If NearbyPointInArray(Point(MSCX, MSCY), 20, TPA) Then
WriteLn('The mainscreen center is near the TPA, aborting!');
//DebugTPA(Tpa, '');
End.
This script will find if the main screen center (MSCX, MSCY) with a circle of 20 radius, is in the TPointArray 'TPA'. If it is, then it will result True.
ReArrangeandShortenArrayEx
PHP Code:
{*******************************************************************************
function ReArrangeandShortenArrayEx(a: TPointArray; w, h: Integer): TPointArray;
Description: Results the TPointArray a with one point per box with side lengths
W and H left.
*******************************************************************************}
Refer to RAaSTPAEx, this does exactly the same, except you can assign a variable to it:
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA, TPA2 : TPointArray;
Begin
FindColorsTolerance(TPA, iAbs(ClBlue - ClWhite)+1, MIX1, MIY1, MIX2, MIY2, 0);
TPA2 := ReArrangeandShortenArrayEx(TPA, 26, 20);
If Length(TPA2) <> 25 Then Exit;
//DebugTPA(Tpa, '');
End.
It modifys our array to only contain 1 point in a 26x20 box, remember this alters the TPA but you need to assign a variable to it, for it to take affect. So now time for pics:
The picture of the right is my inventory, and on the left is the result of the interrogation.
ReArrangeandShortenArray
PHP Code:
{*******************************************************************************
function ReArrangeandShortenArray(a: TPointArray; Dist: Integer): TPointArray;
Description: Results the TPointArray a with one point per box with side length
Dist left.
*******************************************************************************}
Refer to RAaSTPA, this does exactly the same, except you can assign a variable to it:
This does what ReArrangeandShortenArrayEx does except it doesn't have the Width ('w') parameter. This means that it will make a circle of radius Dist around the point, in which not to have any points in.
Okay, boys and girls:
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, iAbs(ClBlue - ClWhite)+1, MIX1, MIY1, MIX2, MIY2, 0);
ReArrangeandShortenArray(TPA, 20);
//DebugTPA(Tpa, '');
End.
Now time for a pic:
This is the same principle as the one before, except it has more points, why?
Well it does it in a 'circular' way. This means that less area is covered than a 20x20 box, hence more points.
TPAtoATPAEx
PHP Code:
{*******************************************************************************
function TPAtoATPAEx(TPA: TPointArray; w, h: Integer): T2DPointArray;
Description: Splits the TPA to boxes with sidelengths W and H and results
them as a T2DPointArray.
*******************************************************************************}
Okay this will be very long.
So TPAToATPAEx, splits a TPA ('TPA') into boxes of width and height specified by 'w' and 'h' respectively. Its a function so you must assign a variable to it, remember this functions makes Arrays Of TPoints, the arrays being the amount of TPA's split.
So, our points are the green color on the tree. For example we did a FindColorsTolerance to find the green color, and to put points on them using this script:
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, 3238756, MSX1, MSY1, MSX2, MSY2, 10);
DebugTPA(TPA, '');
End.
These are the points you get:
Then if you add TPAToATPAEx, it will split these points, as said before.
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
ATPA : T2DPointArray;
Begin
FindColorsTolerance(TPA, 3238756, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 43, 40);
DebugATPABounds(ATPA, '');
End.
Remember TPAToATPAEx was assigned to a variable, we debug that and we get this:
They were split into squares of 43, 40 of width and height respectively.
So you may ask, why are the boxes different sizes, well... This is fundamentally because of the remaining points, 43x40 boxes do not cover all of the TPA so some must be made different sizes to accomodate this effect.
Also, you may have noticed that they overlap. Thats the main difference between it and it's counterparts (SplitTPA/Ex). This is very usefull for finding things in runescape, this will be told in the next chapter.
TPAtoATPA
PHP Code:
{*******************************************************************************
function TPAtoATPA(TPA: TPointArray; Dist: Integer): T2DPointArray;
Description: Splits the TPA to boxes with sidelength Dist and results
them as a T2DPointArray.
*******************************************************************************}
Not much do do here, it does the same TPAToATPAEx, but it follows the same relation as:
RAaSTPA - RAaSTPAEx
RearrangeandShortenArray - RearrangeandShortenArrayEx
You guessed it ! It splits the TPA into circles with radius 'Dist'.
Look, this is our TPA:
And using TPAToATPA we get:
Once again it overlaps sometimes, as explained before.
In my opinion TPAToATPAEx should be used instead of this for finding MainScreen objects because you have more parameters to specify to make it accurate, reliable and so on.
SortTPAFrom
PHP Code:
{*******************************************************************************
procedure SortTPAFrom(var a: TPointArray; const From: TPoint);
Description: Sorts the TPointArray a from the point From.
Closest one to the point is [0], second closest is [1] etc.
*******************************************************************************}
This procedure will sort a TPA (Array of TPoint), specified by 'a', from the TPoint 'From'. It sorts it in ascending order (from nearest to furthest).
The usage would be:
SCAR Code:
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, clWhite * 1, MSX1, MSY1, MSX2, MSY2, 10);
SortTPAFrom(TPA, Point(MSCX, MSCY));
If TPA[0].x = 0 Then WriteLn('Finder Failed :(');
End;
What this script does is that it sorts the TPA from the MainScreen center. If the first point's 'x' cord, from the MainScreen center, is equal to zero, then it debugs 'Find Failed'.
SortATPAFrom
PHP Code:
{*******************************************************************************
procedure SortATPAFrom(var a: T2DPointArray; const From: TPoint);
Description: Sorts the T2DPointArray a from the point From.
*******************************************************************************}
This procedure will sort an ATPA (Array of Array of TPoint), specified by 'a', from the TPoint 'From' in ascending order (from nearest to furthest). Remember your TPA must be split by SplitTPA/Ex or TPAToATPA/Ex, for an ATPA to be made.
The usage:
SCAR Code:
Var TPA : TPointArray;
ATPA : T2DPointArray;
Begin
FindColorsTolerance(TPA, clGreen * 1, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 20, 20);
SortATPAFrom(ATPA, Point(MSCX, MSCY));
If ATPA[1][0].x = 0 Then WriteLn('Finder Failed :(');
End;
What this scripts does is that it sorts the ATPA from the MainScreen center. If the second TPA's first point is zero then it debugs. (Remember its an ATPA ).
SortATPAFromFirstPoint
PHP Code:
{*******************************************************************************
procedure SortATPAFromFirstPoint(var a: T2DPointArray; const From: TPoint);
Description: Sorts the T2DPointArray a from the point From.
*******************************************************************************}
This procedure basically goes through each TPA and does SortTPAFrom, without changing the order.
There's a pretty good usage of this procedure, I use it in mining coal. But more of that later . The usage of it is the same as SortATPAFrom.
InvertTPA
PHP Code:
{*******************************************************************************
procedure InvertTPA(var a: TPointArray);
Description: Inverts / Reverts the TPointArray a.
*******************************************************************************}
InvertTPA does:
<Wizzup> Easy
<Wizzup> TPA[I] := TPA[Length(TPA) - I]
<Wizzup> Read the source
<Wizzup> It's open source for a reason
That means it turns the TPA the other way. So if out TPA was, say, 0,1,2,3. InvertTPA would print it as such: 3,2,1,0 . This is usefull, so for instance you find a wrong object in your first 6 points, so you invert
InvertATPA
InvertATPA inverts an ATPA (Array Of Array of TPoint). It does thus:
ATPA[0] --> ATPA[2]
ATPA[1] --> ATPA[1]
ATPA[2] --> ATPA[0]
See its as easy as 00, 01, 10, 11 .
MiddleTPAEx
PHP Code:
{*******************************************************************************
function MiddleTPAEx(TPA: TPointArray; var x, y: Integer): Boolean;
Description: Stores the coordinates of the middle of the TPointArray a to X & Y.
*******************************************************************************}
Okay, this is another very crucial function used in TPA Object Finding!
So this is going to be...kinda... long, but this will make up a chunck from the next section.
Lets begin,
MiddleTPAEx finds the middle of a TPA defined by 'TPA', and what it does it alters the 'x' and 'y' variables to contain cartesian co-ordinates. The principle behind it will be explained in the next description.
The Usage is simple:
SCAR Code:
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, clGreen, MSX1, MSY1, MSX2, MSY2, 34);
If MiddleTPAEx(TPA, x, y) Then
WriteLn('x is equal to '+IntToStr(x)+', y is equal to '+IntToStr(y));
End.
That script finds the middle of 'TPA' and debugs the x and y coords. Easy, no?
MiddleTPA
PHP Code:
{*******************************************************************************
function MiddleTPA(tpa: TPointArray): TPoint;
Description: Returns the middle of the TPointArray tpa.
*******************************************************************************}
This function is different than MiddleTPAEx, whereas MiddleTPAEx is a boolean, this is a TPoint. This means that you must assign a variable of data type TPoint, to it. But nevertheless it does the same thing:
SCAR Code:
Var TPA : TPointArray;
Pa : TPoint;
Begin
FindColorsTolerance(TPA, clGreen, MSX1, MSY1, MSX2, MSY2, 34);
Pa := MiddleTPAEx(TPA);
WriteLn('x is equal to '+IntToStr(Pa.x)+', y is equal to '+IntToStr(Pa.y));
End.
These are what both functions do, graphic-wise :
However, this is not the Exact principle of what MiddleTPA/Ex does, thanks to bullzeye. MiddleTPA/Ex will find the highest concentration of points and will find the middle of it via averaging. However, points outside the high concentration will have a minimal effect on the middle. Like this:
Assume we're working out an average:
69+69+56+60+70+68+2 / 7(the quantity of numbers) = 56. The points in the concentration are 50 - 72. You see the '2' in there? If MiddleTPA/Ex found the boundaries and found the middle of a Box and resulted that, then that to an extent would be wrong. Instead since it works out the average so the '2' has a small effect on the outcome, but still has an outcome. Doing it this way it will be much more accurate finding the middle of TPA's.
SortATPASize
PHP Code:
{*******************************************************************************
procedure SortATPASize(var a: T2DPointArray; const BigFirst: Boolean);
Description: Sorts the T2DPointArray a from either largest or smallest, by the
amount of points in the TPAs.
*******************************************************************************}
What SortATPASize does is that is sorts an ATPA (Array Of Array Of TPoint) specified by 'a' in ascending order from 0 onwards. It will either sort the Biggest first or the Smallest first depending on the constant 'BigFirst'.
To make it sort the biggest first.
BigFirst - True;
To make it sort the smallest first.
BigFirst - False;
This picture explains it:
Easy, yes?
CombineTPA
PHP Code:
{*******************************************************************************
function CombineTPA(Ar1, Ar2: TPointArray): TPointArray;
Description: Combines the TPointArrays Ar1 and Ar2, and results the combination.
*******************************************************************************}
What Combine TPA does it very easy. It combine the TPA 'Ar1' and 'Ar2' to form a TPA of those two combined.
The usage:
SCAR Code:
Var TPA, TPA2, FinalTPA : TPointArray;
Begin
FindColorsTolerance(TPA, 0, MSX1, MSY1, MSX2, MSY2, 10);
FindColorsTolerance(TPA2, 65535, MSX1, MSY1, MSX2, MSY2, 10);
FinalTPA := CombineTPA(TPA, TPA2);
WriteLn('The Length of TPA was '+Length(TPA)+', The Length of TPA2 was '+Length(TPA2));
WriteLn('Hence our final TPA would be TPA+TPA2 = '+Length(FinalTPA));
End;
What this script does is it find the occurances of the color black and yellow, then combines them. It then debugs the TPA's and them combined .
CombineIntArray
PHP Code:
{*******************************************************************************
function CombineIntArray(Ar1, Ar2: TIntegerArray): TIntegerArray;
Description: Combines the TIntegerArrays Ar1 and Ar2, and results the
combination.
*******************************************************************************}
This combines the two TIntegerArrays (Array of Integer) specified by 'Ar1' and 'Ar2'.
This is extremely easy:
SCAR Code:
Var TIA, TIA2, FinalTIA : TIntegerArray;
I : Byte;
Begin
SetLength(TIA, 5);
SetLength(TIA2, 4);
SetLength(FinalTIA, 9);
TIA := [0, 2, 4, 6, 8, 10];
TIA2 := [1, 3, 5, 7, 9];
FinalTIA := CombineIntArray(TIA, TIA2);
QuickSort(FinalTIA);
For I := 0 to High(FinalTIA) Do
WriteLn(FinalTIA[I]);
End.
This script will combine the TIA (TIntegerArrays) 'TIA' and 'TIA2' together and assign it to the variable of 'FinalTPA'. Remember to set the length of the array before you define the values . We then sort 'FinalTPA' by using QuickSort();. This makes sure it sorts then from 0 - 10. We then debug these values.
InIntArrayEx
PHP Code:
{*******************************************************************************
function InIntArrayEx(a: TIntegerArray; var Where: Integer; const Number: Integer): Boolean;
Description: Returns true if the integer Number was found in the integer array
a, and stores the index to Where.
*******************************************************************************}
This finds a number defined by the const 'Number' in a TIntegerArray (Array Of Integer) specified by 'a', stores it's location in the array. It stores the location to the variable 'Where'. It results true if 'Number' is found.
Example:
SCAR Code:
Var Int : Integer;
Begin
If InIntArrayEx([0, 4, 5, 4, 3, 4, 6, 999, 0], Int, 999) Then
WriteLn('The number 999 is in the index '+IntToStr(Int)+' of the TInt Array');
End.
Remember this function will only find the first number it comes to, it starts from the left on-wards.
InIntArray
PHP Code:
{*******************************************************************************
function InIntArray(a: TIntegerArray; Number: Integer): Boolean;
Description: Returns true if the integer Number was found in the integer array a.
*******************************************************************************}
This does the same as InIntArrayEx. Furthermore, this finds a number defined by the const 'Number' in a TIntegerArray (Array Of Integer) specified by 'a'. It results true if 'Number' is found.
Example:
SCAR Code:
Begin
If InIntArrayEx([0, 4, 5, 4, 3, 4, 6, 999, 0], 999) Then
WriteLn('The number 999 is in the TInt Array');
End.
ClearSameIntegers
PHP Code:
{*******************************************************************************
procedure ClearSameIntegers(var a: TIntegerArray);
Description: Clears the duplicates in the integer array a.
*******************************************************************************}
Yup, the guy who described this did a real great job. It saves me the trouble.
Now, the script you've all been waiting for:
SCAR Code:
Var TIA : TIntegerArray;
I : Integer;
Begin
TIA := [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7];
ClearSameIntegers(TIA);
For I := 0 to High(TIA) Do
WriteLn(TIA[I]);
End.
This script will clear all the duplicate numbers in the TIntegerArray. It will then output them.
ClearSameIntegersAndTPA
PHP Code:
{*******************************************************************************
procedure ClearSameIntegersAndTPA(var a: TIntegerArray; var p: TPointArray);
Description: Clears the duplicates in the integer array a and the TPointArray p.
*******************************************************************************}
This procedure does the same as ClearSameIntegers but has the added feature of clearing same TPA's.
They are defined by 'a' and 'p' respectively.
SCAR Code:
Var TIA : TIntegerArray;
TPA : TPointArray;
I : Integer;
Begin
TIA := [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7];
TPA := [Point(0, 0), Point(0, 0), Point(1, 1),
Point(1, 1), Point(2, 2), Point(2, 2)];
ClearSameIntegersAndTPA(TIA, TPA);
For I := 0 to High(TIA) Do
WriteLn(TIA[I]);
If Length(TPA) < 5 Then WriteLn('TPA cleared :)');
End.
This script will clear all the duplicate numbers in the TIntegerArray. It will then output them. However, it will also clear the duplicate TPA, then if the length of the TPA (Array of TPoint) is not equal to it's previous length (5) then it will output: 'TPA cleared '
SplitTPAEx
PHP Code:
{*******************************************************************************
function SplitTPAEx(arr: TPointArray; w, h: Integer): T2DPointArray;
Description: Splits the points with max X and Y distances W and H to their
own TPointArrays.
*******************************************************************************}
Okay SplitTPAEx is another must-know function to do with TPA Object finding. Remember TPAToATPAEx?? If you don't, here it is:
So TPAToATPAEx, splits a TPA ('TPA') into boxes of width and height specified by 'w' and 'h' respectively. Its a function so you must assign a variable to it, remember this functions makes Arrays Of TPoints, the arrays being the amount of TPA's split.
So, our points are the green color on the tree. For example we did a FindColorsTolerance to find the green color, and to put points on them using this script:
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, 3238756, MSX1, MSY1, MSX2, MSY2, 10);
DebugTPA(TPA, '');
End.
These are the points you get:
Then if you add TPAToATPAEx, it will split these points, as said before.
SCAR Code:
{.include srl/srl.scar}
{.Include srl/srl/misc/debug.scar}
Var TPA : TPointArray;
ATPA : T2DPointArray;
Begin
FindColorsTolerance(TPA, 3238756, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 43, 40);
DebugATPABounds(ATPA, '');
End.
Remember TPAToATPAEx was assigned to a variable, we debug that and we get this:
They were split into squares of 43, 40 of width and height respectively.
So you may ask, why are the boxes different sizes, well... This is fundamentally because of the remaining points, 43x40 boxes do not cover all of the TPA so some must be made different sizes to accomodate this effect.
Also, you may have noticed that they overlap. Thats the main difference between it and it's counterparts (SplitTPA/Ex). This is very usefull for finding things in runescape, this will be told in the next chapter.
You see, they both do the same thing, they split the TPA to an ATPA (Array of Array Of TPoint). So what's the difference?
Well, whereas TPAToATPAEx would over-lap boxes, what this function does is that it merges the boxes that overlap. This picture should explain it:
So why does it overlap, well Master Nava, correctly, states:
'SplitTPA Takes the TPoint array, and outputs a T2DPointArray based on the distance inputted into the Dist parameter.
Inside the function, a series of for..to..do loops check that every point which is within the distance of a different point is placed into the SAME TPointArray on a separate index than others.
This means, it will create TPA's of different boundaries and often is MUCH more accurate in finding objects as it has neither a max nor a minimum size of the object.
Although it is more accurate, it is also significantly slower, so there is a trade off .'
Happy? no? I will link some tutorials by master Cazax at the end section (V).
SplitTPA
PHP Code:
{*******************************************************************************
function SplitTPA(arr: TPointArray; Dist: Integer): T2DPointArray;
Description: Splits the points with max distance Dist to their own TPointArrays.
Dist 1 puts the points that are next to eachother to their own arrays.
*******************************************************************************}
Lets refer back to RAaSTPAEx, TPAToATPAEx, ReArrangeAndShortenArrayEx, NearbyPointInArrayEx, The list goes on.
However you may have been 'cool' enough to realise that the specified functions ending with 'Ex' contain the extra parameter of 'w' and 'h', and they sort and group via Boxes. However Functions with 'Ex' have what parameter???
Yes, thats right - 'Dist'. And how do they group?? No thats wrong, they don't group via Boxes they split and group in Circles. (Apologies if you got that right or wrong).
Now lets compare that to TPAToATPA, which sorts and groups in the shape of circles with Radius of 'Dist'. SplitTPA will look for a point in a range, specified by 'Dist', of each point in the TPA. If it finds a close one, then it will add it in.
And remember, any TPA in another reigon will also be grouped, hence the picture above under SplitTPAEx ^^.
FilterPointsPie
SCAR Code:
{*******************************************************************************
procedure FilterPointsPie(var Points: TPointArray; const SD, ED, MinR, MaxR: Extended; Mx, My: Integer);
Description: Removes the points in the TPointArray Points that are not within
the degrees SD (StartDegree) and ED (EndDegree) and the distances
MinR (MinRadius) and MaxR (MaxRadius) from the origin (Mx, My).
*******************************************************************************}
Okay, boys and girls, this is another CRUCIAL procedure. What this procedure does is that it makes a pie-slice, with the small part of the 'pie' starting at 'Mx' and 'My'. And the big part's width ranging at 'SD' to 'ED'. It makes filters the points defined by 'Points'. The pie slice is then sectioned, so that the needed points are between 'MinR'and 'MaxR'. Have I confused you yet? Good, time to clear it up with pics:
Pretend we did some cool TPA stuff to find the points. For example We did this:
SCAR Code:
{.Include SRL/SRL.Scar}
{.include Srl/Srl/Misc/Debug.Scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, FindVarrockRoadColor, MMX1, MMY1 ,MMX2, MMY2, 25);
DebugTPA(TPA, '');
End.
And we basically get the picture above.
However, we only want a section of those points, so if we do something uber cool like use the function FilterPointsPie..
SCAR Code:
{.Include SRL/SRL.Scar}
{.include Srl/Srl/Misc/Debug.Scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, FindVarrockRoadColor, MMX1, MMY1 ,MMX2, MMY2, 25);
FilterPointsPie(TPA, -10.5, 35.7, 15.4, 60.2, MMCX, MMCY);
DebugTPA(TPA, '');
End.
Please note the parameters, were based off the picture above.
While we're at 'the picture above' lets inquire what the script would do. Well, in the above picture we had a square block of points which went beyond the boundaries of our section of 'Black, Red, Green, Yellow' ('SD', 'ED', 'MinR', 'MaxR' respectively).
However, using that function we make sure that the points are only in the boundary we specify so instead of this:
we get:
More of this will be explained in the next section. Just so you know, this is used in RadialWalk, OMG!
RemoveDistTPointArray
PHP Code:
{*******************************************************************************
function RemoveDistTPointArray(x, y, dist: Integer; ThePoints: TPointArray; RemoveHigher: Boolean): TPointArray;
Description: Removes the points that are inside or outside the distance Dist
from the point (x, y) from the TPointArray ThePoints.
*******************************************************************************}
RemoveDistTPointArray, will make a circle of radius 'Dist' with it's center points being situated at cordinates 'x' and 'y'. The 'RemoveHigher' parameter of data type Boolean will remove points inside or outside of the circle.
RemoveHigher is True - Points removed outside the circle of radius 'Dist', points are kept within circle of radius 'Dist'
RemoveHigher is False - Points are kept outside the circle of radius 'Dist', points are removed within circle of radius 'Dist'.
Remember that this is a function so a data type of TPointArray must be assigned to it. It can be used as such:
SCAR Code:
program New;
{.Include SRL/SRL.Scar}
{.include srl/srl/misc/debug.scar}
Var x, y : Integer;
tpa : array of tpoint;
Begin
SetupSRL;
FindColorsTolerance(TPA, 7048347, msx1, msy1, msx2, msy2, 10);
MiddleTPAEx(TPA, x, y);
TPA := RemoveDistTPointArray(x, y, 20, TPA, true); // here
DebugTPA(tpa, '');
End.
What that script will do is find occurances of the color '7048347' in the mainscreen of runescape and find the middle of all those points. It then makes a circle of radius 20 (Dist) around the cordinates x and y of the TPointArray 'TPA'. The last parameter is true, so it will remove the points within the circle, and leave the ones outside of the circle untouched.
More will be explained in due time, in the next section.
GetTPABounds
PHP Code:
{*******************************************************************************
function GetTPABounds(TPA: TPointArray): TBox;
Description: Returns the boundaries of the TPA as a TBox.
*******************************************************************************}
This is one more useful function, it seems that the most used functions seem to be included at the end :/. What GetTPABounds does is that it makes a box around all the points 'TPA' and returns the Boundaries in the form of data type TBox.
A picture:
Usage:
SCAR Code:
{.Include SRL/SRL.Scar}
Var
TPA : TPointArray;
TB : TBox;
Begin
SetupSRL;
FindColorsTolerance(TPA, ClBlack, MSX1, MSY1, MSX2, MSY2, 50);
TB := GetTPABounds(TPA);
MouseBox(TB.X1, TB.Y1, TB.X2, TB.Y2, 1);
End.
What this script does it that it stores all the occurances of the color black, found in the RuneScape mainscreen to the TPA. It then gets the boundaries of the TPA and clicks randomly inside the box using MouseBox();.
FindTPAinTPA
PHP Code:
{*******************************************************************************
function FindTPAinTPA(SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
Description: Looks for the TPA SearchTPA in the TPA TotalTPA and returns
the matched points to the TPA Matches. Returns true if there were atleast one
match(es).
*******************************************************************************}
Okay this function does what it says on the label, (note to self - must thank the person who made this, makes my job shorter). So, just to make sure I did something. This function will look at the points in the TPointArray 'TotalTPA' and see if any of them match with the TPointArray 'SearchTPA', if more than one point matches then it (the function) will result true. This function will store the same points found, in SearchTPA and TotalTPA to a TPointArray called 'Matches'. Not much more to explain there .
FindTextTPAInTPA
PHP Code:
{*******************************************************************************
function FindTextTPAinTPA(Height: Integer; SearchTPA, TotalTPA: TPointArray; var Matches: TPointArray): Boolean;
Description: Read the description of FindTPAinTPA. Additional Height parameter.
*******************************************************************************}
This does exactly what FindTPAinTPA does except it has an additional height parameter, so whats the difference? Well this is used in FindTextTPA hence the extra text in the name.
Well, Boreas say:
it looks like height is just for the area to look in
.
He's right, ofc, it is. To put it more clearly its where the searchbox.y2 will stop.
FindGapsTPA
PHP Code:
{*******************************************************************************
function FindGapsTPA(TPA: TPointArray; MinPixels: Integer): T2DPointArray;
Description: Finds the possible gaps in the TPointArray TPA and results the
gaps as a T2DPointArray. Considers as a gap if the gap length is >= MinPixels.
Only horizontal, sorry folks.
*******************************************************************************}
FindGapsTPA will find all the gaps in a TPointArray 'TPA', provided its width is more or equal to 'Minpixels'. It will then output these as TPA's, arrays of TPointArray actually. Hence its output T2DPointArray (ATPA). Usage:
SCAR Code:
{.Include SRL/SRL.Scar}
Var
TPA : TPointArray;
ATPA : Array Of TPoint;
Begin
FindColorsTolerance(TPA, clBlack, MSX1, MSY1, MSX2, MSY2, 49);
ATPA := FindGapsTPA(TPA, 20);
WriteLn('The were '+IntToStr(High(ATPA))+' Point arrays found of 20 boxes or over.');
End.
This script will find all gaps of 20 pixels or more in the TPA then write how many TPA's were found in the Gaps.
CreateTPAFromBMP
PHP Code:
{*******************************************************************************
Function CreateTPAFromBMP(BmpDC: HDC): TPointArray;
Description: Creates a TPointArray of the bitmap dc BmpDC.
Use GetBitmapDC to get the dc.
*******************************************************************************}
This function will create a TPA from a bitmap. Or so it's meant to, however, I found out that it would ignore blue pixels and only get red and yellow colors and so on. , someone help here, please. Oh yeah, it's useful for finding text.
SortCircleWise
PHP Code:
{*******************************************************************************
procedure SortCircleWise(var tpa: TPointArray; mx, my, Deg: Integer; SortUp: Boolean; ClockWise: Boolean);
Description: Sorts all points in tpa by distance from degree (Deg) and distance from
mx and my. Sortup will return closest distance to mx and my first.
Distance will be sorted first (RadialWalk style).
*******************************************************************************}
Okay, a big hand to nielsie95 for explaining all of this, <3 him!!! SortCircleWise will sort points, 'tpa', by scanning from or to 'Deg' specified by the boolean 'ClockWise'. SortUp will return the points closest to 'mx' and 'my'.
Okay, it's pretty hard understanding it, i think. It basically sorts the points for use in RadialWalk like Yakman's Radial tool, when your drawing a radial. Okay, confused? Run this script and play about, credits go to Nielsie for this.
SCAR Code:
program New;
const
CircleWise = True; //False - LinearSort, True - SortCircleWise
SortUp = True; //Sort from degree?
ClockWise = False; //Only goes for CircleWise
Degree = 180; // The degree of which to sort depending on SortUp
var
t, i, x, y, bmp: Integer;
tpa: TPointArray;
Canv: TCanvas;
begin
bmp := BitmapFromString(200, 200, '');
SetTargetBitmap(bmp);
FastDrawClear(bmp, clRed);
FindColorsTolerance(tpa, clRed, 0, 0, 200, 200, 0);
Canv := GetBitmapCanvas(bmp);
MiddleTPAEx(tpa, x, y);
t := GetSystemTime;
if CircleWise then
SortCircleWise(tpa, x, y, Degree, SortUp, ClockWise)
else
LinearSort(tpa, x, y, Degree, SortUp);
WriteLn('time: '+IntToStr(GetSystemTime - t)+' l: '+IntToStr(Length(tpa)));
DisplayDebugImgWindow(400, 400);
t := GetSystemTime;
for i := 0 to High(tpa) do
begin
try
Canv.Pixels[tpa[i -1].x, tpa[i -1].y] := clBlue;
except end;
try
Canv.Pixels[tpa[i].x, tpa[i].y] := clYellow;
except end;
CopyCanvas(Canv, GetDebugCanvas, 0, 0, 200, 200, 0, 0, 400, 400);
Wait(3);
end;
end.
I would post pictures but, since this post is limited to only 20 pictures, I cant. Try and fiddle with the consts and see what you get. Within 5 minutes of fiddling im pretty sure you will have got what it does.
LinearSort
PHP Code:
{*******************************************************************************
procedure LinearSort(var tpa: TPointArray; mx, my, Deg: Integer; SortUp: Boolean);
Description: Sorts all points in tpa by distance from degree (Deg) and distance from
mx and my. Sortup will return closest distance to mx and my first.
Degree will be sorted first (LinearWalk style).
*******************************************************************************}
Okay this does exactly the same as SortCircleWise, there is only one fundamental difference. That is that SortCircleWise will sort sideways. However, LinearSort will sort linear (up or down), Specified by the boolean 'SortUp'. Once again, play with this script above. This is used in LinearWalk as it scans linear-wise.
MergeATPA
PHP Code:
{*******************************************************************************
Function MergeATPA(ATPA: T2DPointArray): TPointArray;
Description: Merges the TPointArrays of the T2DPointArray ATPA in to one TPA.
*******************************************************************************}
Yeah, another classic function. This function will group the TPA's of an ATPA into a TPA. Okay got that, no?
Okay, T2DPointArray is made up of TPointArray (TPA). This function gets all that and merges (that's the word xD) them into one TPA. Here's a table to make you understand:
ATPA - TPA[0] = 3, TPA[1] = 4, TPA[2] = 3.
TPA := MERGEATPA(ATPA);
TPA = (3+4+3) = 10
And here's a sample script:
SCAR Code:
Var TPA : Array [0..2] Of TPointArray;
FTPA : TPointArray;
I : Byte;
Begin
TPA[0] := [Point(0, 0)]; // length of 1
TPA[1] := [Point(0, 0), Point(1, 1)]; //length of 2
TPA[2] := [Point(999, 988)]; //length of 1
FTPA := MergeATPA(TPA); //should output 4 *fingers crossed*
For I := 0 To 2 Do
WriteLn('The Length of TPA['+IntToStr(i)+'] was '+IntToStr(Length(TPA[I])));
WriteLn('All Of That Merged gives the length (FTPA) of '+IntToStr(Length(FTPA)));
End.
It will output the respective lengths of TPA[0], TPA[1] etc. Then it will output the length of FTPA once all of the TPA (ATPA) has been merged.
So that concludes the current section on: Functions/Procedures of Wizzy Plugin and explanation.
Stay Tuned for the next section: Usage in RuneScape.
Thanks !