PDA

View Full Version : A low down on WizzyPlugin and TPA's



Naum
08-20-2009, 08:14 PM
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 :p).
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..

// * 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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic1.jpg

The picture of the right is my inventory, and on the left is the result of the interrogation.


RAaSTPA


{************************************************* ******************************
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:

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic2.jpg

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


{************************************************* ******************************
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 :D:

{.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


{************************************************* ******************************
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:

{.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


{************************************************* ******************************
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:

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic1.jpg

The picture of the right is my inventory, and on the left is the result of the interrogation.


ReArrangeandShortenArray


{************************************************* ******************************
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:

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic2.jpg

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


{************************************************* ******************************
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:

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic3.jpg

Then if you add TPAToATPAEx, it will split these points, as said before.

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic4.jpg

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


{************************************************* ******************************
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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic3.jpg

And using TPAToATPA we get:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic5.jpg

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


{************************************************* ******************************
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:
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


{************************************************* ******************************
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:
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


{************************************************* ******************************
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


{************************************************* ******************************
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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

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 :):

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic6.jpg

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


{************************************************* ******************************
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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic7.jpg

Easy, yes?


CombineTPA


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

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


{************************************************* ******************************
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.

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


{************************************************* ******************************
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:

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic3.jpg

Then if you add TPAToATPAEx, it will split these points, as said before.

{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic4.jpg

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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic8.jpg

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


{************************************************* ******************************
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

{************************************************* ******************************
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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic9.jpg

Pretend we did some cool TPA stuff to find the points. For example We did this:

{.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..


{.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:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic9.jpg

we get:

http://i140.photobucket.com/albums/r37/naumanakhlaq/tutpic10.jpg

More of this will be explained in the next section. Just so you know, this is used in RadialWalk, OMG!


RemoveDistTPointArray


{************************************************* ******************************
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:

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


{************************************************* ******************************
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:

http://i54.tinypic.com/2vv7682.jpg

Usage:
{.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


{************************************************* ******************************
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 :p.


FindTextTPAInTPA


{************************************************* ******************************
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


{************************************************* ******************************
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:

{.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


{************************************************* ******************************
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. :confused:, someone help here, please. Oh yeah, it's useful for finding text.


SortCircleWise


{************************************************* ******************************
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.

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


{************************************************* ******************************
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


{************************************************* ******************************
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:

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 :)!

Naum
08-20-2009, 08:15 PM
III - Usage in Runescape.


Yes, well done for making it this far :). Now for the meaty stuff, WizzyPlugin is used alot in RuneScape. It's main uses include AutoColoring, MapWalking and Object Finding. In this section I will explain how to make your own Object Finder using the plugin. Firstly I'll loop through the functions and procedures in order. I will present scenario's and I will show the usage in SRL.



procedure RAaSTPAEx(var a: TPointArray; const w, h: Integer);

This happens to be a very useful procedure for counting things in the inventory because it leaves one point per box. So for example we wanted to count the items in your inventory. Firstly, we would need to get one common color for all items. That color is 65536.

So we have:

Var TPA : TPointArray;
Function ItemCount : Integer;
Begin
FindColorsTolerance(TPA, 65536, MIX1, MIY1, MIX2, MIY2, 0);

The boundaries are set as the Inventory's bounds in the parameters, as we are indeed searching in the Iventory.

So what do we do next? Well RAaSTPAEx leaves a point per box, so we need to find the width and the height of each item, so we can construct a box out of those. Each inventory slot is approximately 42 by 36. With 42 being the width and 36 being the height. Using this information, we can input this into the 'w, h' parameters:

Var TPA : TPointArray;
Function ItemCount : Integer;
Begin
FindColorsTolerance(TPA, 65536, MIX1, MIY1, MIX2, MIY2, 0);
RAaSTPAEx(TPA, 42, 36);

Now all we need to do now is to make it output a result. We can use a handy function called Length(); this function will output the number of points, length, in integer form.

So we have it:

Var TPA : TPointArray;
Function ItemCount : Integer;
Begin
FindColorsTolerance(TPA, 65536, MIX1, MIY1, MIX2, MIY2, 0);
RAaSTPAEx(TPA, 42, 36);
Result := Length(TPA);
End;

So, what's the usage of this? Well, lets conjure up a scenario. For example, we're doing something fabulously entertaining, like killing pixels in the form of cows. Our script will pick up cow hides, and will only go to bank them once it has got an inventory full (28 hides).

Using, this we can make a failsafe:

Var TPA : TPointArray;
Function ItemCount : Integer;
Begin
FindColorsTolerance(TPA, 65536, MIX1, MIY1, MIX2, MIY2, 0);
RAaSTPAEx(TPA, 42, 36);
Result := Length(TPA);
End;

Procedure Stuff;
Begin
If ItemCount < 28 Then KillCows
Else Bank;
End;

Incorporating this technique into our scripts will help us leech as much resources as we can, earn enough money e.t.c. However, this technique can also be extended to grounds far away such as checking for yew logs in an inventory. Furthermore, SRL already uses this technique, it's called InvCount :).



procedure RAaSTPA(var a: TPointArray; const dist: Integer);

I'll just post some commented code for this one, I think there's only one usage of this procedure in SRL. And that is in the function GetMiniMapDotsIn:

{************************************************* ******************************
function GetMiniMapDotsIn(WhatDot: String; x1, y1, x2, y2: Integer): TPointArray;
By: footballjds, NaumanAkhlaQ, Nava2 & Cazax
Description: Results the dots specified by WhatDot in x1, y1, x2, y2.
Usage : 'npc', 'yellow' : Yellow Dot;
'cape', 'blue' : Blue Dot;
'item', 'red' : Red Dot;
'player', 'white' : White Dot;
'friend', 'green' : Green Dot;
************************************************** *****************************}
function GetMiniMapDotsIn(WhatDot: string; x1, y1, x2, y2: Integer): TPointArray;
var
Color: Integer;
begin
WhatDot := LowerCase(WhatDot);
case WhatDot Of
'npc', 'yellow': Color := 60909; //The one color
'cape', 'blue': Color := 12742980;// for FindColors is being setup here
'item', 'red': Color := 789758;
'player', 'white': Color := 16711422;
'friend', 'green': Color := 61440;
else
srl_Warn('GetMiniMapDotsIn', '"' + WhatDot + '" is not a valid dot type', warn_AllVersions);
end;
FindColorsSpiralTolerance(MMCX, MMCY, Result, Color, x1, y1, x2, y2, 0); //Finds all occurances of 'Color' this will search spiraling outwards from the MiniMap center.
RAaSTPA(Result, 4); //LOOK HERE > This will make one point per box on a player dot, great for counting.
if (Length(Result) < 1) then Exit; //Incase RAaSTPA sets Result as '0' due to no dots being found.
if (WhatDot = 'player') or (WhatDot = 'white') then //Necessary.
begin
InvertTPA(Result);
SetLength(Result, Length(Result) - 1);
InvertTPA(Result);
end;
end;


You see the prime usage of RAaSTPA is in this function, without it there would have been more lines of code, using this function makes it shorter. And remember the dots in the minimap are round, so RAaSTPA accommodates that very nicely.



function TPAtoATPAEx(TPA: TPointArray; w, h: Integer): T2DPointArray;

This will be slightly long. TPAToATPAEx is used throughout in Object finders. To show it's usage in SRL just check this code:

{************************************************* ******************************
Function FindFurnace(Var X, Y: Integer): Boolean;
By: n3ss3s
Description: Finds a furnace and stores the coordinates into X and Y.
************************************************** *****************************}

Function FindFurnace(Var X, Y: Integer): Boolean;

Var
TPAA: T2DPointArray; //Declare the variables
TPA: TPointArray;
CTS, I: Integer;
Begin
CTS := GetColorToleranceSpeed; //set CTS
ColorToleranceSpeed(2);
FindColorsSpiralTolerance(MSCX, MSCY, TPA, 3815998, MSX1, MSY1, MSX2, MSY2, 10); // finds all occurances of color 3815998 with 10 tolerance, spaning out from the main screen center.
ColorToleranceSpeed(CTS);
TPAA := TPAToATPAEx(TPA, 50, 50); // LOOK HERE > TPAA now contains at least one 50x50 box formed from the TPointArray (TPA).
SortATPASize(TPAA, True); //Sorts it by size, biggest first
For I := 0 To High(TPAA) Do //Loops through until it finds it
If GetArraylength(TPAA[i]) > 150 Then //Similar to 'length'
Begin
MiddleTPAEx(TPAA[i], X, Y); //Finds the middle via averaging
MMouse(X, Y, 3, 3);
If WaitUpText('urnac', 300) Then
Begin
Result := True;
GetMousePos(X, Y);
Break;
End;
End;
End;


You may have noticed that a few lines after a major splitting function such as TPAToATPAEx, you have a for..to..do loop. This is what makes an object finder an object finder. That piece of code will loop through the TPA's in the ATPA 'TPAA', if it finds one TPA which has a length of '150' points or more then it will find the middle of that array.
After it has found the middle, it will move the mouse over those coordinates to check if the UpText certifies a Furnace. If that is true then it will get the mouses position, set the result as True and break from the loop.

Okay thats all in all n3ss3s TPA c0dez0r. But what about us? What about the common people wishing to utilize this TPAToATPAEx. Well, fear no more.

I'm sure in the last part you would, or should :p, have understood the theory behind TPAToATPAEx. Now lets create a scenario. Imagine you have to pick up cowhides from the ground:

http://i140.photobucket.com/albums/r37/naumanakhlaq/pic1.jpg

We need to avoid the items in the blue boxes, but we need to pick up the items in the red boxes.

Firstly we need to create some points on the mainscreen, we can do this via FindColorsTolerance:

{.Include SRL/SRL.Scar}
{.Include SRL/SRL/Misc/Debug.Scar}
Var TPA : TPointArray;
Begin
FindColorsTolerance(TPA, 11447993, MSX1, MSY1, MSX2, MSY2, 10);
DebugTPA(TPA, '');
End.

This piece of code will find all occurrences of the color '11447993' with '10' tolerance on the RuneScape main screen. It will store all the found points to the array of points (TPA). If we run that script then we get these as our points:

http://i140.photobucket.com/albums/r37/naumanakhlaq/pic2.jpg

The points are the red pixels.

Yay! We've got our points. However you may have noticed that some of the points fell on the flowers, do not worry, we will sort this later :D.
Now, since you have the points, you now need to make boxes around them to increase the chance of finding the hide. So what should we use? Well, lets use our great friend TPAToATPAEx.
As, from the last section, you probably know that you need to 'w', width and 'h' height parameters inputted for the TPA to be split into an ATPA.

So how will we get that? We'll we look at the hide, and find the width and height of it:

http://i140.photobucket.com/albums/r37/naumanakhlaq/pic3-1.jpg

How did we find those numbers? Well we used the Color Picker in SCAR, we recorded the start and end then subtracted the End by the Start and found the Step:

{.Include SRL/SRL.Scar}
{.Include SRL/SRL/Misc/Debug.Scar}
Var TPA : TPointArray;
ATPA : T2DPointArray;
Begin
FindColorsTolerance(TPA, 11447993, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 20, 20);
DebugATPABounds(ATPA, '');
End.

We now have all the boxes stored in 'ATPA' of data type: T2DPointArray (Array of Array Of TPoint). We now need to create a loop sequence so that it will try and find the cowhide.

Now, that's good, but bear with me, as we introduce another crucial function used in all Object Finders..


function MiddleTPAEx(TPA: TPointArray; var x, y: Integer): Boolean;

As you know, from the last section, this function will find the middle of a TPA (Array Of TPoint) via averaging. So why is this useful, well to find a big object such as a cow hide you need to be sure you won't mis-click. Hence the usefulness of this :).

So, carrying on from before, we should have:

{.Include SRL/SRL.Scar}
{.Include SRL/SRL/Misc/Debug.Scar}
Var TPA : TPointArray;
ATPA : T2DPointArray;
I, X, Y : Integer;
Begin
FindColorsTolerance(TPA, 11447993, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 20, 20);
For I := 0 To High(ATPA) Do
Begin
If MiddleTPAEx(ATPA[I], X, Y) Then

End;
DebugATPABounds(ATPA, '');
End.

Wow, thats a big step. Let's break it down ;).
Firstly, we looped through the ATPA (Array Of Array Of TPoint), we then try to find the middle of ATPA[I] which is a TPointArray (Array Of TPoint). The middle of that TPA is stored to the x and y co-ord. If this is successful then the function, MiddleTPAEx, results 'True' :).

Let's add some more, to make sure it's a cow hide and not a flower etc. To do this we can check the RuneScape 'UpText'. The function for this is:

{************************************************* ******************************
function IsUpText(UpText: String): Boolean;
By: Freddy1990
Description: Returns up text that might be to the right
************************************************** *****************************}


In RuneScape when you hover over anything, do you notice the text which appears in the top left hand corner of the main screen?
We can exploit this and use it was a fail safe. The text for hovering over a cow hide is 'Pickup Cowhide', we only need 3 - 5 letters of this, preferably non capitals.

So before we can do that we need to move the mouse over it. We do this using MMouse():

{.Include SRL/SRL.Scar}
{.Include SRL/SRL/Misc/Debug.Scar}
Var TPA : TPointArray;
ATPA : T2DPointArray;
I, X, Y : Integer;
Begin
FindColorsTolerance(TPA, 11447993, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 20, 20);
For I := 0 To High(ATPA) Do
Begin
If MiddleTPAEx(ATPA[I], X, Y) Then
MMouse(x, y, 0, 0);
If IsUpText('owhid') Then

End;
DebugATPABounds(ATPA, '');
End.

Yay! We now have the template! Now, all we need is to add what we want to do with it. I just want to click it. I will use the procedure Mouse() :).

{.Include SRL/SRL.Scar}
{.Include SRL/SRL/Misc/Debug.Scar}
Var TPA : TPointArray;
ATPA : T2DPointArray;
I, X, Y : Integer;
Begin
FindColorsTolerance(TPA, 11447993, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 20, 20);
For I := 0 To High(ATPA) Do
Begin
If MiddleTPAEx(ATPA[I], X, Y) Then
MMouse(x, y, 0, 0);
If IsUpText('owhid') Then
Mouse(x, y, 0, 0, True);
End;
DebugATPABounds(ATPA, '');
End.

Yay! It works!, now finally make sure you 'Break' out of the procedure, otherwise it will just continue regardless of if you've found it or not :):

{.Include SRL/SRL.Scar}
{.Include SRL/SRL/Misc/Debug.Scar}
Var TPA : TPointArray;
ATPA : T2DPointArray;
I, X, Y : Integer;
Begin
FindColorsTolerance(TPA, 11447993, MSX1, MSY1, MSX2, MSY2, 10);
ATPA := TPAToATPAEx(TPA, 20, 20);
For I := 0 To High(ATPA) Do
Begin
If MiddleTPAEx(ATPA[I], X, Y) Then
MMouse(x, y, 0, 0);
If IsUpText('owhid') Then
Begin
Mouse(x, y, 0, 0, True);
Break; //need this!
End;
End;
DebugATPABounds(ATPA, '');
End.

That's much of the Object finding tutorial part done. Next are other functions such as SplitTPA/Ex and FilterPointsPie :).



function SplitTPAEx(arr: TPointArray; w, h: Integer): T2DPointArray;

Arrr. Welcome to some of the other functions that can be used for object finding. SplitTPAEx is another crucial function used! It can be substituted in for functions like: TPAToATPA, TPAToATPAEx.
You should know what SplitTPAEx does, if not here's a breif description:

SplitTPAEx will loop through the points in 'arr' of data type TPointArray. If any of the points in 'arr' are within the box of 'w' by 'h', then they will be put into their seperate TPA's :).

Basically, look at a graphical representation, side-by-side:

http://i140.photobucket.com/albums/r37/naumanakhlaq/pic4.png

This can have very good uses, for example it is used in this procedure:

function GetDoorPoints: T2DPointArray;
var
CTS: integer; //Color Tolerance speed
P: TPointArray; //the points
begin
CTS := GetColorToleranceSpeed; //stored the color tolerance speed in the variable 'CTS'
ColorToleranceSpeed(2); //chnaged the color tolerance speed
SetColorspeed2Modifiers(0.0, 0.0);
FindColorsTolerance(P, 227, MMX1, MMY1, MMX2, MMY2, 6); //finds all the occurances of 227 in the minimap, with 6 tolerance :)
SetColorspeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(CTS); //Sets the color tolerance speed back
if Length(P) < 1 then Exit; //Just in case...
Result := SplitTPA(FilterDropDots(P), 6); //Yay! This will group all the TPA's within distance of 6 pixels of each other. Useful for finding doors, as doors have no fixed dimensions ;)
SortATPAFrom(Result, Point(MMCX, MMCY)); //Remember this from before?
end;


See SplitTPA can be used in exactly the same way. The only difference is it checks if the point is within a circle of radius, instead of 'Ex' which uses the 'Box' method :).



FilterPointsPie(var Points: TPointArray; const SD, ED, MinR, MaxR: Extended; Mx, My: Integer);


As promised in the last section, I will show you how it is used in SRL. There's one critical procedure its used in, and that is the MAIN walking, color, function. That is RadialWalk/Ex, LinearWalk/Ex:

function RadialWalkEx(var TPA: TPointArray; cx, cy, TheColor, tol, StartRadial, EndRadial, Radius: Integer): Boolean;
var
i, SD, ED: Integer;
begin
Result := False;
SD := StartRadial;
ED := EndRadial;
if (SD = ED) then
begin
srl_Warn('RadialWalkEx', 'StartRadial = EndRadial, using LinearWalkEx.', warn_Warning);
Result := LinearWalkEx(tpa, cx, cy, TheColor, tol, StartRadial, Radius);
end;
if (SD > ED) then
Swap(SD, ED);
SD := Trunc(FixD(SD + 0.0));
ED := Trunc(FixD(ED + 0.0));
if (not LoggedIn) then Exit;
i := GetSystemTime;
try
FindColorsTolerance(tpa, TheColor, MMX1, MMY1, MMX2, MMY2, tol); //finds all occurance of 'TheColor' with tolerance of 'tol', it then stores it to the TPointArray 'tpa'.
FilterPointsPie(tpa, SD, ED, 10, Radius, cx, cy); //Gets all the points in the segment of SD and ED, within the distance of 10 and 'Radius'. Stores that to the TPointArray 'tpa'
SortCircleWise(tpa, cx, cy, StartRadial, False, StartRadial > EndRadial); //Sorts it circlewise, like Yakman's RadialWalker when you draw the path :)
Result := (Length(tpa) > 0);
except
srl_Warn('RadialWalkEx', 'An exception has occured', warn_AllVersions); Exit;
end;
srl_Warn('RadialWalkEx', 'Took ' + IntToStr(GetSystemTime - i) +
' ms, found' + IntToStr(Length(TPA)) + ' points', warn_Debug);
end;



Happy with that? Its main usage it in Walking. It is extremely useful, I shall link some tutorials in the next section.



IV - End Note and Credits + Links to good tutorials.


Credits:

Firstly I would like to say a BIG thanks to Nielsie, Zeph and Bullzeye, for putting up with my constant bothering :). Secondly a further thanks is due to RM and Nava, who would find time to read over it and give pointers. Thirdly, a MASSIVE thank-you is due to the creators and anyone who helped make WizzyPlugin.
Last but not least, another thanks goes out to all the SRL Members who commented on the tutorial, helped fix bugs, and generally gave good feedback <3 2 u!
Anyone else who helped me write this tutorial :).


End Note:


I write tutorials to help the community. Script's will come and go, Ideas will be acknowledged and modified, knowledge will last for ever. I help people to contribute to the BEST community I've ever visited.


Links:

http://www.villavu.com/forum/showthread.php?t=42428 - By Cazax
http://www.villavu.com/forum/showthread.php?t=48915 - By JAD
http://www.villavu.com/forum/showthread.php?t=48822 - By 3Garrett3
http://www.villavu.com/forum/showthread.php?t=21786 - By n3sss3s
http://www.villavu.com/forum/showthread.php?t=48491 - By Blumblebee
http://www.villavu.com/forum/showthread.php?t=19162 - By Zeph
http://www.villavu.com/forum/showthread.php?t=33111 - By Dusk412
http://www.villavu.com/forum/showthread.php?t=36016 - By Niels
http://www.villavu.com/forum/showthread.php?t=49089 - A BFF by Coh3n :D
http://www.villavu.com/forum/showthread.php?t=38295 - By NiCbaZ
http://www.villavu.com/forum/showthread.php?t=28484 - By Timothegreat
http://www.villavu.com/forum/showthread.php?t=27456 - By Ray

THANKS!

nielsie95
08-20-2009, 08:27 PM
It's looking good :)

Zyt3x
08-20-2009, 09:58 PM
Wow, you have done a great job on this tutorial! Well explained and with pictures! :)
Good job! I would rep+ you if I could (You must spread some Reputation around before giving it to NaumanAkhlaQ again.).

Sabzi
08-20-2009, 10:08 PM
This will be such a great read(don't have time now)! Thank you! But same as Zyt3y I can't rep you, atm. And I am looking forward for the upcoming sections. Nice job!

bugger0001
08-20-2009, 11:55 PM
Wow...That's really great piece of reading.

But found a bugger in it: MiddleTPA example has MiddleTPAEx in it instead of MiddleTPA and therefore is causing a type mismatch error.

Naum
08-21-2009, 12:30 AM
Wow...That's really great piece of reading.

But found a bugger in it: MiddleTPA example has MiddleTPAEx in it instead of MiddleTPA and therefore is causing a type mismatch error.

I absolutely LOVE you for finding the bug :)! :D Rep++. Fixed.

Other guys: Thanks for all the comments and positive feedback :)

ShowerThoughts
08-21-2009, 12:53 AM
Good job!

Blumblebee
08-21-2009, 01:01 AM
amazing, well done :) +rep

bullzeye95
08-21-2009, 01:44 AM
Big tutorial is big. Nice job.

Nadeem
08-21-2009, 02:14 AM
gawd u have no life...
although very nice :P



~NS

Nava2
08-21-2009, 03:47 AM
You have Split TPA poorly explained.

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 boundries 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.

Also, you might as well take a look into the .dpr if you want a better understanding. :)

Naum
08-21-2009, 03:54 AM
You have Split TPA poorly explained.

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 boundries 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.

Also, you might as well take a look into the .dpr if you want a better understanding. :)

Yeah, thanks for that. I also figured out, thanks to bullzeye, that MiddleTPA isn't fully explained. Can I use your words nava in the tutorial? I will get to my corrections in the morning :). Rep+

EDIT: Yeah I checked .dpr. I guess I have a different way (poorly) of explaining it :(

Torrent of Flame
08-21-2009, 03:58 AM
kin ell. 5 rep balls.

noidea
08-21-2009, 04:06 AM
omfg
This is what you've been working on?
whats the betting you have 6 by tommorows D:

NICE TUT

btw: I think this is the biggest post on SRL :p

Pure1993
08-21-2009, 05:45 AM
NAAAIIIICCCEEEE! Gr8 JOB! Geesh, someone give this guy a second tut writers cup. ;)

Freddy1990
08-21-2009, 06:08 AM
Remind me to hire you to write my manuals

Naum
08-21-2009, 07:23 PM
Remind me to hire you to write my manuals

Haha thanks :D.

@ Everyone else, I fixed a few bugs and cleared up some stuff. Thanks to Nava and Bullzeye. Please read and see if it makes sense, thanks :)

Torrent of Flame
08-21-2009, 07:26 PM
There should be a special cup for naum or something :p

Sabzi
08-21-2009, 07:31 PM
There should be a special cup for naum or something :p

When I read the post saying he should got a second tut writer cup I was thinking about the same.
A Nauman cup?
How to get it? : Be NaumanAkhlaQ
Description: NaumanAkhlaQs get it.

Daniel
08-21-2009, 07:49 PM
Thanks Nauman for the tutorial :) Although most of the stuff is clearly explained in WizzyPlugin.scar file itself (well to me, anyway).

But yo summed it all up with pictures xD Rep++ by all means.


omfg
btw: I think this is the biggest post on SRL :p

Nah, my type tutorial is the biggest :p (check signature).

BobboHobbo
08-21-2009, 08:06 PM
gawd u have no life...
although very nice :P



~NS

Lol +1!, Rep+

HyperSecret
08-21-2009, 11:33 PM
Very nice Naum, this had to take quite some time to put together so far. If I may make one suggestion. To help people see the difference between, SplitTPA and TPAtoATPA try using a roadcolor and debugging that. I always find that to be very useful to see the difference in the two.

Either way, very nice

Simtoon
08-22-2009, 05:33 AM
You told me to check ou the tutorial and i already did about half of it, this really helps...

Markus
08-22-2009, 05:45 AM
tl;dr

na, good job =p Its just so freakin big its near impossible to comment on it lol

cycrosism
08-22-2009, 07:02 AM
Thats a HUGE tutorial but it helped me lots, ty!!!

Naum
08-22-2009, 05:13 PM
Very nice Naum, this had to take quite some time to put together so far. If I may make one suggestion. To help people see the difference between, SplitTPA and TPAtoATPA try using a roadcolor and debugging that. I always find that to be very useful to see the difference in the two.

Either way, very nice


You told me to check ou the tutorial and i already did about half of it, this really helps...


tl;dr

na, good job =p Its just so freakin big its near impossible to comment on it lol


Thats a HUGE tutorial but it helped me lots, ty!!!

Hyper: That's the idea for the next section :p. Thanks.

Simtoon: Wha?

Markus: heh, thanks :)

Cycro: Glad it helped you.

Rubix
08-23-2009, 10:36 AM
grats on 5 bawlz o' rep! (i assume you got it from this tut)

Simtoon
08-23-2009, 04:10 PM
Is this why you make tutorials for more ballz?

Naum
08-23-2009, 06:19 PM
Is this why you make tutorials for more ballz?

I really can't help it I'm sorry. If people find it in their heart's to rep me then it's fine, I appreciate it. But otherwise, I'm fine if they do or don't. And, no is the answer to that. Find a thread, which I have posted, within the last 6 which has me celebrating about my 'ballz'.

Rep points were disabled, do you know the use for them before? Do you remember when SRL was private?


SRL-member by manually giving you 30 Reputation points

Try saying that again in that time, 'Do you want rep to become an SRL Member?', guess the response..

Anyway, I write tutorials to help the community. Script's will come and go, Ideas will be acknowledged and modified, knowledge will last for ever. I help people now to contribute to the BEST community I've ever visited.

On the other hand, why are you so pissed of with me? (http://www.villavu.com/forum/forumdisplay.php?f=21)

If your mad at me, use the 'block' or 'delete' button on MSN. Oh yeah and Simtoon, I would very much value your opinion on the context of the tutorial :)

@Rubix: Thanks :).

Simtoon
08-23-2009, 06:25 PM
Remember on msn when you said it was for fun, i can't believe you write things for fun i hate writing, why am i writing this now! omg!
No wonder my post count is so low...

I shall write my life story..

I saw a white light and now here i am

Naike
08-24-2009, 09:59 PM
I hate ruining the fun, but I thought this section was for tutorials which wasn't for jr.members?

And as I see it, SRL is open source, no need to start hiding advanced tutorials in here..

Naum
08-24-2009, 10:20 PM
I hate ruining the fun, but I thought this section was for tutorials which wasn't for jr.members?

And as I see it, SRL is open source, no need to start hiding advanced tutorials in here..

Well n1ke, my dear friend, there was a clear and valid reason to have it situated here, before I release it to the masses.
If you would have asked me beforehand I would have given you an answer, just as I gave to Zeph and whomsoever inquired. The reason I want it here is that anything I have missed or could have explained better be taken into account. As you see I have received a lot of feedback stating how I could improve it, Nava2 <3.
I want it clear and understandable before I release it. And, I'm sure you would agree, who better than to judge it than my fellow peers?

I will release it soon to the jr.members once it is done and ironed out. I had the liberty of asking many people to have a look over it on MSN. However, there were certain things that I missed.

Also, I am not 'hiding advanced tutorials' as I'm going to release it once I finish my next section. I'd love any feedback on it so far. I'm pretty sure many things could be cleared up :)


EDIT: Upped some of the second section, that was how much I got done yesterday :p!

Read Please!

Smarter Child
08-31-2009, 04:16 AM
This has to be the best tutorial I have ever read, when I was junior member not too long ago, i was dying to read this tutorial ;).

Sir R. M8gic1an
08-31-2009, 05:03 AM
http://i140.photobucket.com/albums/r37/naumanakhlaq/pic3.jpg

w is actually the blue line.... ;) but good going.

~RM

Naum
09-12-2009, 06:25 PM
Done!

The tutorial is in it's final stages, after days of slacking of :p.
Feel free to give your Final Critique or Feedback, as this will be moved to Jr's soon.

thanks!

Simtoon
09-12-2009, 07:05 PM
Ib4 move!

Zyt3x
09-13-2009, 01:25 AM
This will help a lot of people :)

Naum
09-26-2009, 04:37 PM
OMG, Thanks for the Sticky :D!
<3 YoHoJo!

EDIT: My first sticky at SRL!!

Dynamite
02-17-2010, 10:49 PM
Reading through it all now :)
Needs recognition.
Rep++

RAM
04-07-2010, 12:14 AM
Thanks, I really like the example pictures :)

Tim0suprem0
04-10-2010, 02:14 AM
Yeah this is sexy! I think I'm going to have to read it in stages though...

But it definitely makes Wizzyplugin less intimidating.

BraK
07-17-2010, 05:47 PM
Wow A huge Tut to read and it proved to be great refrence and learning material.

Edit: Apparently I like too many of your Tuts. Can't Rep

Naum
07-17-2010, 09:11 PM
It's bad

BraK
07-17-2010, 09:53 PM
What's bad???

Naum
07-18-2010, 08:10 AM
The tut, couldn't explain some shit properly

BraK
07-18-2010, 08:45 AM
I understand a good few of the functions better than I did previously. The rest is the experiment with it and test out how they work for me. I'm Writing up a script that'll get sand and bank it over in yanelle right now to get the hang of it.

Naum
07-18-2010, 11:59 AM
I understand a good few of the functions better than I did previously. The rest is the experiment with it and test out how they work for me. I'm Writing up a script that'll get sand and bank it over in yanelle right now to get the hang of it.

Main ones were Linear and SortCircleWise.
Good luck with that project bro, I'm on MSN a bit now so dont be afraid to hit me up:
Ty!

Dervish
12-27-2011, 05:35 PM
I finally undestood.. Fantastic tutorial Naum, lots of love.

Flight
12-28-2011, 01:03 AM
Yes it really is, this is an absolutely wonderful tutorial. I wish more people would use this, it's very detailed.

Swatarianess
01-01-2012, 03:16 PM
I've remember this from ages ago still one of my Fav tuts to read :D

NickMystre
01-14-2012, 05:03 AM
I'm sure I must be missing something.

Just what is it with what Naum refers to as his '69' pics illustrations are they / he trying to demonstrate ?

They all look exactly the same to me. What am I missing ? I going slightly mad looking at these and for the life of me, I just don't get it.

Anyone with some insight, please share it with me. Thanks!

Flight
01-14-2012, 05:13 AM
I'm sure I must be missing something.

Just what is it with what Naum refers to as his '69' pics illustrations are they / he trying to demonstrate ?

They all look exactly the same to me. What am I missing ? I going slightly mad looking at these and for the life of me, I just don't get it.

Anyone with some insight, please share it with me. Thanks!

I've been wondering the same thing. Good question.

Brandon
01-14-2012, 05:15 AM
http://i.imgur.com/SA1ZR.jpg

For RAaSTPA you'd only iterate through 28 points when clicking the item.. for a TPA, it can find multiple points on ONE item so when clicking, it would iterate through all the points on the first item before going to the second. You can obviously use MiddleTPA to avoid this but RAaSTPA is much much better.

NickMystre
01-14-2012, 05:52 AM
http://i.imgur.com/SA1ZR.jpg

For RAaSTPA you'd only iterate through 28 points when clicking the item.. for a TPA, it can find multiple points on ONE item so when clicking, it would iterate through all the points on the first item before going to the second. You can obviously use MiddleTPA to avoid this but RAaSTPA is much much better.

Thank you ggzz. I will have to go back to the tutorial and review it with the new perspective you have given me. Once more unto the breach, dear friends ...

@Flight: Let me know if this opens any new doors for you. :)

Thank you!

Flight
01-14-2012, 07:02 AM
I've always used MiddleTPA for that.

NickMystre
01-14-2012, 07:38 AM
I've always used MiddleTPA for that.

Yes, MiddleTPA I am quite happy with, as well.

What also makes the difference for me too, is that the name lends itself to the result. It's fairly intuitive. I can't always say that for some of the other routines I have come across. At this stage though, I reason that this is more to do with my level of understanding.

'We shall not surrender ...' :)

Nemesis3X
02-22-2012, 03:02 AM
Well, The Best Guide Out There fr TPA. I was Using TPA but after reading this, I changed Most of My procedure for Better TPA Function like Middle and RAaSTPA.

Thanks you.

I am Karma
02-27-2012, 11:43 PM
Just came from scripting for begginners to this place and this is an awful headache :D

Limoncello
03-19-2012, 06:16 PM
Now that's an excellent tutorial! Well done!

Abu
05-08-2012, 05:41 AM
Darn it!!!!!

Wasn't supposed to post.

Remove post I guess :(

mr. pali
12-31-2012, 12:58 AM
Amazing. + Rep

Sjoe
01-12-2013, 05:49 AM
Lovely tutsy, didn't understand it the first time I read it.
had to go through other TPA tutorials first

samerdl
04-30-2013, 12:36 PM
This guide is awesome, i must of read it 5 or so times till i actually started to understand tpa's.

The best part is the examples, they put everything into proper perspective, tpa's really help out execute difficult tasks, thanks a lot!