Results 1 to 21 of 21

Thread: Detailed TPA and ATPA tutorial

  1. #1
    Join Date
    Nov 2007
    Location
    Chile
    Posts
    1,901
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default Detailed TPA and ATPA tutorial

    Basic concepts:
    Point = a single pixel
    Points = 2+ pixels

    So whats a TPA? a TPointArray(array of TPoint). Whats a TPoint?:

    SCAR Code:
    Type
      TPoint = Record
        X, Y : Integer;
      End;
    It's basically X and Y coordinates stored in a type. It's the same as:
    SCAR Code:
    Var
      X, Y : Integer;
      TP : TPoint;
    Begin
      TP.X := X;
      TP.Y := Y;
    End.
    Therefore a TPointArray is this:
    SCAR Code:
    Type
      TPointArray = Array Of TPoint;
    It's the same as:
    SCAR Code:
    Var
      TP1, TP2, TP3 : TPoint;
      TPA : TPointArray;
    Begin
      SetLength(TPA, 3); // TPointArray's have an undefined length
      TPA[0] := TP1;
      TPA[1] := TP2;
      TPA[2] := TP3;
    End.

    When do you use TPA's? for example, FindColorTolerance saves the first point found on the screen, while FindColorsTolerance saves all the points found on the screen. So if you are searching for an object in Runescape, where there are similar objects(in colors), FindColorTolerance will give you only one point. If the point it gave you wasn't the one you where searching for, you can't do anything more. but while using FindColorsTolerance, you can try with every point till you find the correct one!

    Like FindColorTolerance and FindColorSpiralTolerance, SCAR have functions to find them all:
    SCAR Code:
    function FindColorsTolerance(var Points : TPointArray; Color, Xs, Ys, Xe, Ye, Tolerance : Integer): Boolean;
    Points has to be a var, so it can be filled with the ponts found. Color is the color to search for. Xs, Ys, Xe and Ye are the coordinates to search in and Tolerance is the tolerance used to find the colors. It will return true if any color was found.

    SCAR Code:
    procedure FindColorsSpiralTolerance(X, Y : Integer; var Points : TPointArray; Color, Xs, Ys, Xe, Ye, Tolerance : Integer);
    Here we have two new parameters - X and Y. The difference between Spiral search and normal one is that spiral search starts from the center(X and Y) outwards, while normal search starts from Xs and Ys to Xe and Ye. So for example, if you are spiral searching in the main screen you would get the nearest points because you are starting from the center(MSCX and MSCY). Here is an example:
    SCAR Code:
    Function FindRockPoints(RockColor : Integer): TPointArray;
    Begin
      FindColorsSpiralTolerance(MSCX, MSCY, Result, RockColor, MSX1, MSY1, MSX2, MSY2, 15);
    End;
    MSCX, MSCY = The middle of the main screen
    MSX1, MSY1, MSX2, MSY2 = Main screen coordinates


    Now that you have the TPAs, how would you know what points did you get?
    SCAR Code:
    function GetArrayLength(x): Integer;
    If you use it in a TPA, you would get its length example:
    SCAR Code:
    var
      TPA : TPointArray;
      L : Integer;
    Begin
      SetLength(TPA, Random(5)); //Random(5) will return a random number betwenn 0-4
      Writeln('Mhuahaha you don't know my length!');
      L := GetArrayLength(TPA);//Can be Length(TPA) too
      Writeln('
    Yes I do! it is ' + IntToStr(L));
    End.
    Note: Length does the same as GetArrayLength.
    SetLength(TPA, 5) for example, will set the length of TPA in this order:
    TPA[0]
    TPA[1]
    TPA[2]
    TPA[3]
    TPA[4]
    So if you want to search through every point, you have to use the function:
    SCAR Code:
    function High(x): Integer;
    It returns the highest array index, in this case, 4. If you use Length(), it would return 5. Do you see the difference?
    SCAR Code:
    Var
      TPA : TPointArray;
      I : Integer;
    Begin
      SetLength(TPA, 6);
      TPA[0] := Point(Random(50), Random(100)); //Point() mixes two values(x and y) into a tpoint
      TPA[1] := Point(Random(50), Random(100));
      TPA[2] := Point(Random(50), Random(100));
      TPA[3] := Point(Random(50), Random(100));
      TPA[4] := Point(Random(50), Random(100));
      TPA[5] := Point(Random(50), Random(100));
      For I := 0 To High(TPA) Do
        Writeln('TPA[' + IntToStr(I) + '].X = ' + IntToStr(TPA[I].X) + ', TPA[' + IntToStr(I) + '].Y := ' + IntToStr(TPA[I].Y));
    End.
    But every time it loops, high(TPA) will be called and that would waste time:
    SCAR Code:
    Var
      TPA : TPointArray;
      I, H : Integer;
    Begin
      SetLength(TPA, 6);
      TPA[0] := Point(Random(50), Random(100)); //Point() mixes two values(x and y) into a tpoint
      TPA[1] := Point(Random(50), Random(100));
      TPA[2] := Point(Random(50), Random(100));
      TPA[3] := Point(Random(50), Random(100));
      TPA[4] := Point(Random(50), Random(100));
      TPA[5] := Point(Random(50), Random(100));
      H := High(TPA); //Here
      For I := 0 To H Do
        Writeln('TPA[' + IntToStr(I) + '].X = ' + IntToStr(TPA[I].X) + ', TPA[' + IntToStr(I) + '].Y := ' + IntToStr(TPA[I].Y));
    End.
    If you use Length(TPA) - 1 (to get the correct highest index) it would cost you ~0.3 microseconds (approx.)

    Here is another example:
    SCAR Code:
    Var
      TPA : TPointArray;
      I, H, Col : Integer;

    begin
      FindColorsTolerance(TPA, 0, 0, 0, 100, 100, 15);
      H := High(TPA);
      For I := 0 To H Do
      Begin
        Col := GetColor(TPA[I].X, TPA[I].Y); //Gets the color of the current point
        Writeln('TPA[' + IntToStr(I) + '] Color = ' + IntToStr(Col));
      End;
    end.



    End of TPA's. Now, we will start talking about ATPA's. What's an ATPA? It is an Array of TPointArray, multiples TPAs in an array. What are they used for? To sort TPAs in order, because a TPA is just an array tpoint, which in the case of color finding in runescape, might have different objects sorted in the same array but while using an ATPA you can have sorted separately. Example:
    SCAR Code:
    Var
      TPA : TPointArray;
      ATPA : T2DPointArray; //That's how we declare an ATPA
    Begin
      SetLength(TPA, 2);
      SetLength(ATPA, 2);
      TPA[0] := Point(Random(50), Random(50));
      TPA[1] := Point(Random(50), Random(50));
      ATPA[0] := TPA;
      ATPA[1] := TPA;
      Writeln('ATPA[0][0].X = ' + IntToStr(ATPA[0][0].X));
      Writeln('ATPA[1][0].Y = ' + IntToStr(ATPA[0][0].Y));
    end.
    You can have multiple points(like a TPA) but sorted in order, starting from ATPA[0] to ATPA[1].

    But, what we can do with them while finding colors/objects?
    Here are the most important functions in color finding with "TPAs":

    TPAtoATPA, TPAtoATPAEx, SplitTPA and SplitTPAEx.

    TPAtoATPA:
    parameters: Dist : Integer. It makes many TPAs with the shape of a circle, that have points inside it. Look here:

    The red boxes are the points you find using FindColorsTolerance, and as you see TPAtoATPA groups them in 3 different TPAs, ATPA[0], ATPA[1] and ATPA[2]. The dist parameter is the max distance between points, so if you use dist 5 with points where their distance is 6, it won't group them in the same TPA. Do you understand?
    Imagine it in Runescape:

    (Fishing spots)

    TPAtoATPAEx
    Does the same as TPAtoATPA except that it sorts with the shape of a rectangle. In certain things it's better to use TPAtoATPAEx than TPAtoATPA. W parameter is Width and H is height.

    Example:


    SplitTPA
    The difference between this and TPAtoATPA, is that SplitTPA checks if one of the sorted tpas is in 'contact' with other tpa, or they are in a sortable range(according to Dist parameter) it groups them together. Example:



    RS example:

    These X and arrows indicate where SplitTPA groups two tpas, while TPAtoATPA leaves them apart. I use SplitTPA for example while finding trees because they have a dark and a light part, so I find colors from both sides and combine them.

    SplitTPAEx
    The same as SplitTPA except that it sorts with the shape of a rectangle. Parameters are W and H(see TPAtoATPAEx).


    Well, these are the most common ATPA functions used in object finding. How a function would look:
    SCAR Code:
    function FindChicken(Var X, Y : Integer): Boolean;
    var
      TPA : TPointArray;
      ATPA : T2DPointArray;
      I, H : Integer;
    Begin
      FindColorsSpiralTolerance(MSCX, MSCY, TPA, ChickenColor, MSX1, MSY1, MSX2, MSY2, 15);
      ATPA := TPAtoATPA(TPA, 25);
      If Length(ATPA) = 0 Then //If no points were found
        Exit;
      H := High(ATPA);
      For I := 0 To H Do
      Begin
        MiddleTPAEx(ATPA[I], X, Y); //Used to get the middle of the current sorted tpa
        MMouse(X, Y, 3, 3);
        Wait(50 + Random(50));
        If IsUpText('hicken') Then
        Begin
          Writeln('Found chicken!');
          GetMousePos(X, Y);
          Result := True;
          Exit;
        End;
      End;
    End;
    That's a common TPA object finding functions.

    Now, I'm explaining some tpa/atpa functions of the WizzyPlugin(where most of tpas functions are stored, big credits to him).

    RearrangeAndShortenArray/RearrangeAndShortenArrayEx
    They do the same as TPAtoATPA and TPAtoATPAEx, except they give the result in a TPointArray. But beware, it only gives the first point of every sorted tpa. Comparation:
    SCAR Code:
    //TPAtoATPA
    ATPA := TPAtoATPA(TPA, X);
    H := High(TPA);
    For I := 0 To H Do
    Begin
      MiddleTPAEx(ATPA[I], X, Y);
      MMouse(X, Y, 3, 3);
    SCAR Code:
    //RearrangeAndShortenArray
    TPA2 := RearrangeAndShortenArray(TPA, X);
    H := High(TPA2);
    For I := 0 To H Do
    Begin
      //What it does:
      //X := ATPA[I][0].X;
      //Y := ATPA[I][0].Y;
      //It gives the first point of the current sorted tpa
      //while you use TPAtoATPA you get the middle, not the first point
      MMouse(X, Y, 3, 3);
    Sometimes you prefer to use when you don't care about the middle or the first pixel. But how do you know if you care? because if you move mouse to the first pixel of an object, remembering that MMouse uses randomness, you may move the mouse outside and the uptext check will fail. Parameters(normal): Dist(the same as TPAtoATPA) and a which is the tpa to use. Parameters(Ex): W and H(see tpatoatpa) and a which is the tpa to use.

    RAaSTPA/RAaSTPAEx
    It's the same as the functions above except it has a shorter name Well, not the same, it overwrites the tpa given to the result tpa, so in fact you don't another TPA variable.

    CombineTPA
    Combines 2 tpas into one. Example:
    SCAR Code:
    FinalTPA := CombineTPA(TPA1, TPA2);


    SortTPAFrom/SortATPAFrom
    Sorts the tpa/atpa starting from the give point. Why would you use it? example:
    SCAR Code:
    function FindMultiPoints(Colors : TIntegerArray): TPointArray;
    Var
      I, H : Integer;
      TPAex : TPointArray;
    Begin
      H := High(Colors);
      For I := 0 To H Do
      Begin
        FindColorsTolerance(TPAex, Colors[I], MSX1, MSY1, MSX2, MSY2, 15);
        Result := CombineTPA(Result, TPAex);
      End;
      SortTPAfrom(Result, Point(MSCX, MSCY));
    End;

    SortATPASize:
    Sorts an atpa starting from the biggest or the smallest one, defined by the parameter const BigFirst : Boolean.
    Useful in some cases, in others it doesn't matter.

    GetTPABounds
    Gets the boundaries of a tpa, example:


    (SRL)FindColorsPie
    Finds all the points in a circle arc(mostly used in the minimap). Parameters:
    Points: a var to store points with(TPA)
    Color: Color to find
    Tol: Tolerance
    StartD, EndD: Start and end degrees
    MinR, MaxR: Min & Max radius to find in
    x1, y1, x2, y2: ()
    mx, my: Circle center.
    Example:
    SCAR Code:
    var
      TPA : TPointArray;
    begin
      FindColorsPie(TPA, FindVarrockRoadColor, 0, 0, 15, 1, 40, mmx1, mmy1, mmx2, mmy2, mmcx, mmcy);
    end.
    How SCAR will react:



    That's it as for now, if you want me to explain any more function from WizzyPlugin, I'll be happy



    TPA/ATPA useful functions:

    DebugTPA (By Wizzup?):
    SCAR Code:
    Function DebugTPA(Points: TPointArray; BmpName: String): Boolean;

    Var
       Width, Height, ClientBMP, I: Integer;
       xs, ys, xe, ye: Integer;

    Begin
      Try
      Begin
        xe := xs xor xs;
        ye := ys xor ys;
        xs := 1 shl 20;
        ys := 1 shl 20;

        For I := 0 To High(Points) Do
        Begin
          xs := Min(xs, Points[i].X);
          ys := Min(ys, Points[i].Y);

          xe := Max(xe, Points[i].X);
          ye := Max(ye, Points[i].Y);
        End;

        Width := xe - xs;
        Height := ye - ys;

        DisplayDebugImgWindow(0, 0);
        DisplayDebugImgWindow(Width, Height);
        ClientBMP := BitmapFromString(Width, Height, '');

        CopyClientToBitmap(ClientBMP, xs, ys, xe, ye);
        For I := 0 To High(Points) Do
          FastSetPixel(ClientBMP, Points[i].X - xs, Points[i].Y - ys, 255);
        If BmpName <> '' Then
          SaveBitmap(ClientBMP, ScriptPath + BmpName + '.bmp');
        SafeDrawBitmap(ClientBMP, GetDebugCanvas, 0, 0);
        DisplayDebugImgWindow(Width, Height);

        FreeBitmap(ClientBMP);
      End
      Except
        FreeBitmap(ClientBMP);
      End;
      Result := True;
    End;
    What does it do? Debugs all the points stored in the tpa given.


    DebugATPA (By Wizzup?):
    SCAR Code:
    Function DebugATPA(aPoints: Array Of TPointArray; BmpName: String): Boolean;

    Var
       Width, Height, ClientBMP, I, L, C, Col: Integer;
       xs, ys, xe, ye: Integer;
       OuterPoints: TPointArray;

    Begin
      For I := 0 To High(aPoints) Do
        L := L + Length(aPoints[i]);
      SetLength(OuterPoints, L + 1);
      C := 0;
      For I := 0 To High(aPoints) Do
        For L := 0 To High(aPoints[i]) Do
        Begin
          C := C + 1;
          OuterPoints[C] := aPoints[i][L];
        End;

      Try
      Begin
        xe := xs xor xs;
        ye := ys xor ys;
        xs := 1 shl 20;
        ys := 1 shl 20;

        For I := 0 To High(OuterPoints) Do
        Begin
          xs := Min(xs, OuterPoints[i].X);
          ys := Min(ys, OuterPoints[i].Y);

          xe := Max(xe, OuterPoints[i].X);
          ye := Max(ye, OuterPoints[i].Y);
        End;

        Width := xe - xs;
        Height := ye - ys;

        DisplayDebugImgWindow(0, 0);
        DisplayDebugImgWindow(Width, Height);
        ClientBMP := BitmapFromString(Width, Height, '');

        CopyClientToBitmap(ClientBMP, xs, ys, xe, ye)
        For I := 0 To High(aPoints) Do
        Begin
          Col := Random(16777215);
          For L := 0 To High(aPoints[i]) Do
            FastSetPixel(ClientBMP, aPoints[i][L].X - xs, aPoints[i][L].Y - ys, Col);
        End;

        SafeDrawBitmap(ClientBMP, GetDebugCanvas, 0, 0);
        DisplayDebugImgWindow(Width, Height);
        If BmpName <> '' Then
          SaveBitmap(ClientBMP, ScriptPath + BmpName + '.bmp');

        FreeBitmap(ClientBMP);
      End
      Except
        FreeBitmap(ClientBMP);
      End;
      Result := True;
    End;
    Debugs all the points of the sorted tpas in different colors.

    Tell me if I wrote , explained, showed, something wrong, or any other error that you think it deserves to be corrected.
    That's my tutorial, hope you like it
    Last edited by Cazax; 08-27-2010 at 12:01 AM.


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

  3. #3
    Join Date
    Dec 2008
    Location
    Qu├ębec
    Posts
    419
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    nice tut i learned lot of thing in it.
    but i have a question

    function FindChicken(Var X, Y : Integer): Boolean;
    var
    TPA : TPointArray;
    ATPA : T2DPointArray;
    I, H : Integer;
    Begin
    FindColorsSpiralTolerance(MSCX, MSCY, TPA, ChickenColor, MSX1, MSY1, MSX2, MSY2, 15);
    ATPA := TPAtoATPA(TPA, 25);
    If Length(ATPA) = 0 Then //If no points were found
    Exit;
    H := High(ATPA);
    For I := 0 To H Do
    Begin
    MiddleTPAEx(ATPA[i], X, Y); //Used to get the middle of the current sorted tpa
    MMouse(X, Y, 3, 3);
    Wait(50 + Random(50));
    If IsUpText('hicken') Then
    Begin
    Writeln('Found chicken!');
    GetMousePos(X, Y);
    Result := True;
    Exit;
    End;
    End;
    End;


    does the 25 means distance between points ?
    Formerly known as FrancisHelie

  4. #4
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,106
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default

    Very Nice Cazax!!

  5. #5
    Join Date
    Nov 2007
    Location
    Chile
    Posts
    1,901
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by francishelie View Post
    nice tut i learned lot of thing in it.
    but i have a question

    SCAR Code:
    function FindChicken(Var X, Y : Integer): Boolean;
    var
      TPA : TPointArray;
      ATPA : T2DPointArray;
      I, H : Integer;
    Begin
      FindColorsSpiralTolerance(MSCX, MSCY, TPA, ChickenColor, MSX1, MSY1, MSX2, MSY2, 15);
      ATPA := [SIZE="5"]TPAtoATPA(TPA, [U]25[/U]);[/SIZE]
      If Length(ATPA) = 0 Then //If no points were found
        Exit;
      H := High(ATPA);
      For I := 0 To H Do
      Begin
        MiddleTPAEx(ATPA[i], X, Y); //Used to get the middle of the current sorted tpa
        MMouse(X, Y, 3, 3);
        Wait(50 + Random(50));
        If IsUpText('hicken') Then
        Begin
          Writeln('Found chicken!');
          GetMousePos(X, Y);
          Result := True;
          Exit;
        End;
      End;
    End;

    does the 25 means the distance between point ??
    Yes it is, read what I explained
    Note: Distance is in pixels.

    Updated.


  6. #6
    Join Date
    Aug 2008
    Location
    !!LOL!!
    Posts
    247
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    FINALLY i have understood atpa at last thank you a million!!!!!!!!

  7. #7
    Join Date
    Aug 2007
    Posts
    259
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    Hey, great guide, though I have a few questions:

    What does the T in Tpoint stand for?

    How exactly do you measure TpointArrays? Does SetLength(TPA, 3); mean all Tpoints 3 pixels from a given Tpoint?

    In FindColorsSpiralTolerance(MSCX, MSCY, Result, RockColor, MSX1, MSY1, MSX2, MSY2, 15);
    What does the "Result" stand for?

  8. #8
    Join Date
    Nov 2007
    Location
    Chile
    Posts
    1,901
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    1. I think the T is like an abbreviation of Type, because TPoints are actually types. Nothing important really.

    2. A TPointArray holds multiple points(pixels, coordinate). So SetLength(TPA, 3); will carry 3 points.

    3. Since it's a function, and the result is a TPA, whe can use the result as a variable.


  9. #9
    Join Date
    Feb 2007
    Location
    Access Violation at 0x00000000
    Posts
    2,865
    Mentioned
    3 Post(s)
    Quoted
    18 Post(s)

    Default

    Thanks, amazing! This is exactly what I needed!
    But, in your MainScreen coords picture, you say that MSX2, MSY2 is in the bottom-right of the chat screen. But it ends higher then that, at the actual bottom-right corner of the MainScreen.
    Ce ne sont que des gueux


  10. #10
    Join Date
    Nov 2007
    Location
    Chile
    Posts
    1,901
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Didn't see that, I'm fixing it.
    EDIT: Reload the image


  11. #11
    Join Date
    Jul 2008
    Location
    Canada
    Posts
    1,612
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

  12. #12
    Join Date
    Aug 2008
    Location
    !!LOL!!
    Posts
    247
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    this should be stickied

  13. #13
    Join Date
    Feb 2007
    Location
    Access Violation at 0x00000000
    Posts
    2,865
    Mentioned
    3 Post(s)
    Quoted
    18 Post(s)

    Default

    Cazax, once more ^^. This tut ROCKS!

    I now fully understand and can use TPA's. They are great TBH.
    First I just couldn't visualize what all these functions did, but now I totally do!
    Ce ne sont que des gueux


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

    Default

    Erm... posting after 1 month on a great tut isn't gravediging, right?
    Anyway, this deserves a little bumb, great tut, and there I thought I knew most things about TPAs and ATPAs... lol, it seems I'm learning something new every day I'm on this forum...
    Well, now I'll incoperate some of it into my script, get 99 wc on my main, and then release it.
    There is nothing right in my left brain and there is nothing left in my right brain.

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

    Default

    It's still amazing and yes deserves a bump.
    ~Hermen

  16. #16
    Join Date
    Feb 2009
    Location
    AZ, USA
    Posts
    460
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    Awesome tut!
    Great explanations and pictures
    I didn't read it all yet, but still.

    (also thanks for helping me in irc)
    rep++
    Is your account in an old-school random? Help SRL-OSR solve randoms!

  17. #17
    Join Date
    Jan 2007
    Location
    Nomming bits in your RAM
    Posts
    385
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Excellent tutorial. I learned quite a bit about TPAs and their grouped counterparts that will most definitely assist in the making of my scripts.

    Rep++;

    Thank you ,
    ~Macro_FTW
    Current Project: Catching up. XD. Potentially back for the summer, depending on how things go.

  18. #18
    Join Date
    Dec 2006
    Posts
    907
    Mentioned
    1 Post(s)
    Quoted
    17 Post(s)

    Default

    now im fresh and understand what atpas and tpas r ^^ and the functions too

  19. #19
    Join Date
    Apr 2007
    Location
    The Buckeye State
    Posts
    482
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    I really never have understood TPAs. This has helped me gain more of an understanding to them. I do have one question though: Why do most TPA procedure get the middle of a TPA, say, instead of the beginning or end TPoint of the TPA?
    I like my coffee black just like my metal.

  20. #20
    Join Date
    Nov 2007
    Location
    Chile
    Posts
    1,901
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    It's like a habit, you could use TPA[0] or TPA[High(TPA)], but with MMouse randomness you could miss the object you are searching. So if you have the middle you probably won't miss(unless it moves).
    Last edited by Cazax; 08-27-2010 at 12:02 AM.


  21. #21
    Join Date
    Nov 2007
    Location
    Chile
    Posts
    1,901
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Re-uploaded pictures for new generations


Thread Information

Users Browsing this Thread

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

Similar Threads

  1. How to make a detailed progress report!
    By Naike in forum OSR Intermediate Scripting Tutorials
    Replies: 9
    Last Post: 06-21-2012, 08:04 PM
  2. Detailed tutorial about "hacking wep key"?
    By darky in forum General
    Replies: 12
    Last Post: 10-19-2007, 01:26 AM
  3. Your first script - Very Detailed
    By Ares in forum Outdated Tutorials
    Replies: 15
    Last Post: 09-22-2007, 09:32 AM
  4. Replies: 7
    Last Post: 09-05-2007, 12:49 AM
  5. Need Detailed Form Tut
    By Hugolord in forum OSR Help
    Replies: 10
    Last Post: 06-19-2007, 02:34 AM

Tags for this Thread

Posting Permissions

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