Page 1 of 3 123 LastLast
Results 1 to 25 of 64

Thread: A low down on WizzyPlugin and TPA's

  1. #1
    Join Date
    Mar 2007
    Posts
    4,810
    Mentioned
    3 Post(s)
    Quoted
    3 Post(s)

    Default A low down on WizzyPlugin and TPA's

    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 abTPoint);
    DescriptionSwaps 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 abTPointArray);
    DescriptionSwaps 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 abExtended);
    DescriptionSwaps 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 aTPointArray; const whInteger);
    DescriptionLeaves 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 aTPointArray; const DistInteger);
    DescriptionLeaves 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 PTPointwh:IntegeraTPointArray): Boolean;
    DescriptionReturns 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 PTPointDist:IntegeraTPointArray): Boolean;
    DescriptionReturns 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(aTPointArraywhInteger): TPointArray;
    DescriptionResults the TPointArray a with one point per box with side lengths
    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(aTPointArrayDistInteger): TPointArray;
    DescriptionResults 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(TPATPointArraywhInteger): T2DPointArray;
    DescriptionSplits the TPA to boxes with sidelengths W and 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(TPATPointArrayDistInteger): T2DPointArray;
    DescriptionSplits 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 aTPointArray; const FromTPoint);
    DescriptionSorts the TPointArray a from the point From.
    Closest one to the point is [0], second closest is [1etc.
    *******************************************************************************} 
    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 aT2DPointArray; const FromTPoint);
    DescriptionSorts 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 aT2DPointArray; const FromTPoint);
    DescriptionSorts 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 aTPointArray);
    DescriptionInverts 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(TPATPointArray; var xyInteger): Boolean;
    DescriptionStores 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(tpaTPointArray): TPoint;
    DescriptionReturns 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 aT2DPointArray; const BigFirstBoolean);
    DescriptionSorts the T2DPointArray a from either largest or smallestby 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(Ar1Ar2TPointArray): TPointArray;
    DescriptionCombines 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(Ar1Ar2TIntegerArray): TIntegerArray;
    DescriptionCombines 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(aTIntegerArray; var WhereInteger; const NumberInteger): Boolean;
    DescriptionReturns 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(aTIntegerArrayNumberInteger): Boolean;
    DescriptionReturns 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 aTIntegerArray);
    DescriptionClears 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 aTIntegerArray; var pTPointArray);
    DescriptionClears the duplicates in the integer array 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(arrTPointArraywhInteger): T2DPointArray;
    DescriptionSplits 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(arrTPointArrayDistInteger): T2DPointArray;
    DescriptionSplits 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(xydistIntegerThePointsTPointArrayRemoveHigherBoolean): TPointArray;
    DescriptionRemoves the points that are inside or outside the distance Dist
    from the point 
    (xyfrom 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(TPATPointArray): TBox;
    DescriptionReturns 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(SearchTPATotalTPATPointArray; var MatchesTPointArray): Boolean;
    DescriptionLooks 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(HeightIntegerSearchTPATotalTPATPointArray; var MatchesTPointArray): Boolean;
    DescriptionRead the description of FindTPAinTPAAdditional 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(TPATPointArrayMinPixelsInteger): T2DPointArray;
    DescriptionFinds the possible gaps in the TPointArray TPA and results the
    gaps 
    as a T2DPointArrayConsiders as a gap if the gap length is >= MinPixels.
    Only horizontalsorry 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(BmpDCHDC): TPointArray;
    DescriptionCreates 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 tpaTPointArraymxmyDegIntegerSortUpBooleanClockWiseBoolean);
    DescriptionSorts all points in tpa by distance from degree (Deg) and distance from
    mx 
    and mySortup 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 tpaTPointArraymxmyDegIntegerSortUpBoolean);
    DescriptionSorts all points in tpa by distance from degree (Deg) and distance from
    mx 
    and mySortup 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(ATPAT2DPointArray): TPointArray;
    DescriptionMerges 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 !
    Last edited by Naum; 12-08-2017 at 11:57 PM.

  2. #2
    Join Date
    Mar 2007
    Posts
    4,810
    Mentioned
    3 Post(s)
    Quoted
    3 Post(s)

    Default

    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:

    SCAR Code:
    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:

    SCAR Code:
    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:

    SCAR Code:
    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:

    SCAR Code:
    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:

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

    SCAR 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 , have understood the theory behind TPAToATPAEx. Now lets create a scenario. Imagine you have to pick up cowhides from the ground:



    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:

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



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



    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:

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

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

    SCAR Code:
    {*******************************************************************************
    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():

    SCAR Code:
    {.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() .

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

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



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

    SCAR Code:
    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:

    SCAR Code:
    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
    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!
    Last edited by Naum; 09-13-2009 at 01:06 AM.

  3. #3
    Join Date
    Sep 2006
    Posts
    6,089
    Mentioned
    77 Post(s)
    Quoted
    43 Post(s)

    Default

    It's looking good

  4. #4
    Join Date
    Jan 2007
    Posts
    8,876
    Mentioned
    123 Post(s)
    Quoted
    327 Post(s)

    Default

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

  5. #5
    Join Date
    Feb 2009
    Location
    Hungary (GMT + 1)
    Posts
    1,774
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    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!

  6. #6
    Join Date
    Mar 2008
    Location
    In a cave
    Posts
    345
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    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.
    A Chinese wiseman once said: "Shu ciu!", it was considered very smart, but now people know it means: "Something stinks here!"
    FalBuggySmelter v.1.31
    [Updated on the 1st of March 2010]
    RimmBugger BETA V1.8

  7. #7
    Join Date
    Mar 2007
    Posts
    4,810
    Mentioned
    3 Post(s)
    Quoted
    3 Post(s)

    Default

    Quote Originally Posted by bugger0001 View Post
    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 ! Rep++. Fixed.

    Other guys: Thanks for all the comments and positive feedback
    Last edited by Naum; 08-21-2009 at 12:32 AM.

  8. #8
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,553
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Good job!
    ~Hermen

  9. #9
    Join Date
    Feb 2007
    Location
    Alberta,Canada
    Posts
    2,358
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    amazing, well done +rep

  10. #10
    Join Date
    Jun 2006
    Posts
    3,861
    Mentioned
    3 Post(s)
    Quoted
    0 Post(s)

    Default

    Big tutorial is big. Nice job.

  11. #11
    Join Date
    Dec 2008
    Location
    In a galaxy far, far away...
    Posts
    584
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    gawd u have no life...
    although very nice :P



    ~NS

  12. #12
    Join Date
    Jan 2008
    Location
    Ontario, Canada
    Posts
    7,805
    Mentioned
    5 Post(s)
    Quoted
    3 Post(s)

    Default

    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.
    Last edited by Nava2; 08-21-2009 at 03:50 AM.
    Writing an SRL Member Application | [Updated] Pascal Scripting Statements
    My GitHub

    Progress Report:
    13:46 <@BenLand100> <SourceCode> @BenLand100: what you have just said shows you 
                        have serious physchological problems
    13:46 <@BenLand100> HE GETS IT!
    13:46 <@BenLand100> HE FINALLY GETS IT!!!!1

  13. #13
    Join Date
    Mar 2007
    Posts
    4,810
    Mentioned
    3 Post(s)
    Quoted
    3 Post(s)

    Default

    Quote Originally Posted by Nava2 View Post
    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

  14. #14
    Join Date
    Feb 2007
    Location
    South East England
    Posts
    2,906
    Mentioned
    2 Post(s)
    Quoted
    8 Post(s)

    Default

    kin ell. 5 rep balls.
    Jus' Lurkin'

  15. #15
    Join Date
    Jan 2008
    Location
    NC, USA.
    Posts
    4,429
    Mentioned
    0 Post(s)
    Quoted
    4 Post(s)

    Default

    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
    Last edited by noidea; 08-21-2009 at 04:17 AM.
    Quote Originally Posted by irc
    [00:55:29] < Guest3097> I lol at how BenLand100 has become noidea
    [01:07:40] <@BenLand100> i'm not noidea i'm
    [01:07:44] -!- BenLand100 is now known as BenLand42-
    [01:07:46] <@BenLand42-> shit
    [01:07:49] -!- BenLand42- is now known as BenLand420
    [01:07:50] <@BenLand420> YEA

  16. #16
    Join Date
    Jan 2008
    Location
    Frankfurt, Germany
    Posts
    742
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    NAAAIIIICCCEEEE! Gr8 JOB! Geesh, someone give this guy a second tut writers cup.
    There is nothing right in my left brain and there is nothing left in my right brain.

  17. #17
    Join Date
    Feb 2006
    Location
    Belgium
    Posts
    3,137
    Mentioned
    3 Post(s)
    Quoted
    5 Post(s)

    Default

    Remind me to hire you to write my manuals

  18. #18
    Join Date
    Mar 2007
    Posts
    4,810
    Mentioned
    3 Post(s)
    Quoted
    3 Post(s)

    Default

    Quote Originally Posted by Freddy1990 View Post
    Remind me to hire you to write my manuals
    Haha thanks .

    @ 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

  19. #19
    Join Date
    Feb 2007
    Location
    South East England
    Posts
    2,906
    Mentioned
    2 Post(s)
    Quoted
    8 Post(s)

    Default

    There should be a special cup for naum or something
    Jus' Lurkin'

  20. #20
    Join Date
    Feb 2009
    Location
    Hungary (GMT + 1)
    Posts
    1,774
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by Torrent of Flame View Post
    There should be a special cup for naum or something
    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.

  21. #21
    Join Date
    Dec 2006
    Location
    Sydney, New South Wales, Australia
    Posts
    4,603
    Mentioned
    15 Post(s)
    Quoted
    42 Post(s)

    Default

    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.

    Quote Originally Posted by noidea View Post
    omfg
    btw: I think this is the biggest post on SRL
    Nah, my type tutorial is the biggest (check signature).
    You may contact me with any concerns you have.
    Are you a victim of harassment? Please notify me or any other staff member.

    | SRL Community Rules | SRL Live Help & Chat | Setting up Simba | F.A.Q's |

  22. #22
    Join Date
    May 2007
    Location
    NSW, Australia
    Posts
    2,823
    Mentioned
    3 Post(s)
    Quoted
    25 Post(s)

    Default

    Quote Originally Posted by Nadeem View Post
    gawd u have no life...
    although very nice :P



    ~NS
    Lol +1!, Rep+

  23. #23
    Join Date
    Jun 2007
    Location
    La Mirada, CA
    Posts
    2,484
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    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

    "Failure is the opportunity to begin again more intelligently" (Henry Ford)


  24. #24
    Join Date
    May 2007
    Location
    Sydney, Australia (Faggot Region)
    Posts
    1,465
    Mentioned
    0 Post(s)
    Quoted
    11 Post(s)

    Default

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


  25. #25
    Join Date
    Feb 2007
    Location
    Het ademt zwaar en moedeloos vannacht.
    Posts
    7,211
    Mentioned
    26 Post(s)
    Quoted
    72 Post(s)

    Default

    tl;dr

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

Page 1 of 3 123 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •