Page 1 of 2 12 LastLast
Results 1 to 25 of 36

Thread: How to script for a RSPS -Intermediate level

  1. #1
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default How to script for a RSPS -Intermediate level

    Table of contents

    >Making your own uptext function
    > Map walking
    >>Get Compass Angle
    >>SPS
    >>DTM
    >Inventory functions



    Making your own uptext function

    Making your own uptext for your RSPS of choice is a pretty good idea if you want to find objects that may have the same colors as others. Uptext will help you always click on the correct object! Now this section is not on creating a font set, it's on creating your own uptext so we will be taking a shortcut: There are 1 of 2 font sets the RSPS will use, either 'P07Chars' (even if the server is from 2008-2011!) or the current upchars set! This means we can use the font set that is already on your computer. In order to get the uptext we will be using GetTextATPA, because it is IMO the most easy to use.

    Simba Code:
    GetTextATPA(ATPA:T2DPointArray, maxvspacing:LongInt, font:String):string;

    First, we are going to want to grab the colors of the text, you WILL need to get the best coloring using ACA(this is a intermediate tutorial I am going to assume you know how to grab good colors using ACA). You will have to keep relogging until ACA highlights all of the uptext. Re-log a few times to make sure it finds all of the uptext like this:



    First make a function and define the variables needed for a TPA and ATPA:

    Simba Code:
    function rsps_getUpText:string;
    var
      blueTPA: tpointarray;
      blueATPA: t2dpointarray;

    Next, you will want to find all of the text color of your choice:

    Simba Code:
    FindColorsTolerance(blueTPA, color, X1, Y1, X2, Y2, tol);

    Make sure the area it's searching is were the uptext is!

    Next, if the length is > 1 then we want to continue:

    Simba Code:
    if (length(blueTPA) > 1) then


    After it continues, we want to split it into an ATPA:

    Simba Code:
    blueATPA := splitTPAEx(blueTPA, 1, 10);


    Next we want to sort the ATPAs from 0,0 so the text does not end up all jumbled up!

    Simba Code:
    sortATPAFromFirstPointX(blueATPA, point(0, 0));

    Now we return whatever GetTextATPA finds:

    Simba Code:
    result:= getTextATPA(blueATPA, 5, 'UpChars07');

    blueATPA is the found ATPA, 5 is the minimum vertical spacing(you may have to play around with this) and 'UpChars07' is the font set that is located in C:Simba/fonts

    This should return 99% accurate uptext. If it does not then debug the TPA to make sure it's finding all of the text:

    Simba Code:
    DebugTPA(blueTPA, 'bmp');
    (bmp must be declared as a interger)

    Reasons for incorrect uptext:

    -Wrong or bad font set
    -Bad colors
    -Not searching in the whole uptext area


    Map Walking

    Get Compass Angle

    In order to accurately walk, you are going to have to make a function that will correctly be able to either:

    A) Make the Compass close to perfect north
    B) Be able to accurately determine the compass angle

    I am going to start with being able to determine the compass angle first, because it will make making the compass to perfect north more easy.

    Getting the exact compass angle in (degrees) is fairly easy because there is already a function for that in SRL! Why re-invent the wheel?

    Simba Code:
    Function rsps_GetCompassAngleRadians: Extended;
    var
      TPA: TPointArray;
      T: TPoint;
      B: TBox;
    begin
      B := IntToBox(519, 1, 564, 46);
      with B do
        FindColorsSpiralTolerance(T.x, T.y, TPA, 1911089, x1, y1, x2, y2, 0);
      if Length(TPA) < 1 then
        exit;
      T := MiddleTPA(TPA);
      Result := ArcTan2(-(T.Y - 24), T.X - 543) + Radians(90);
      Result := fixRad(Result - Pi);
    end;

    Now all of this is confusing right? WRONG! There are only 2 lines that we need to edit:

    this:
    Code:
    B := IntToBox(519, 1, 564, 46);
    Change the numbers to the bounds of the compass (hopefully you know how to do this?) This box is were it's going to search for the color. Make it as EXACT as possible

    and this:
    Change COLOR to the color of the 'N' on the compass
    Code:
    FindColorsSpiralTolerance(T.x, T.y, TPA, COLOR, x1, y1, x2, y2, 0);
    and then your done... getting the compass angle in radians. To get it in degrees just do:

    Simba Code:
    function rsps_GetCompassAngleDegrees: Extended;
    begin
      Result := Degrees(rsps_GetCompassAngleRadians());
    end;

    SPS

    This tutorial will not cover how to SPS walk, it will cover how to edit SPS to work on the RSPS of your choice. Editing SPS is fairly simple, open up SPS.simba (C:\Simba\Includes\SPS). Now paste the SPS source into a new simba script, and save that simba script to your include folder. Now, it is important that you do everything I say or else it won't work. Here is what my SPS.simba looks like so you can accurately follow along:

    MySPS
    Simba Code:
    (*
    SPS ~ SRL Positioning System
    ============================

    Concept and original work done by marpis @ SRL-Forums.  Work continued by Coh3n
    and members of the SRL community.

    *)


    {$loadlib sps}

    const
      // Path where all the SPS files are
      SPS_IMG_PATH = IncludePath + 'SPS\img\';
      SPS_IMG_FMT  = '.png';

      // Surfaces
      RUNESCAPE_SURFACE = 0;
      RUNESCAPE_SURFACE_FOLDER = 'runescape_surface\';

      RUNESCAPE_OTHER = 1;
      RUNESCAPE_OTHER_FOLDER = 'runescape_other\';

    // User defined SPS global variables
    var
      SPS_Debug: boolean;
      SPS_MultiMouse: boolean; // simulates a human like "spam-click" when walking
      SPS_AnyAngle: boolean;   // true = work at any angle; false = only north
      SPS_ClickNorth: boolean; // call ClickNorth instead of MakeCompass to set the compass to north

    // SPS Global variables
    var
      SPS_Areas: TStringArray;
      SPS_AreaMaps: T3DIntegerArray; // Grids of the combined SPS_Areas
      SPS_Tolerance, SPS_MatchesPercent: extended;
      SPS_Accuracy: integer; // Splits minimap/areas into squares of this side length; used for area recognition
      SPS_IsSetup: boolean; // Used to make sure the user calls SPS_Setup

    // Author: marpis & Coh3n
    // Returns an image of the minimap in a TMufasaBitmap
    function SPS_GatherMinimap: TMufasaBitmap;
    var
      c: TClient;
    begin
      try
        Result := TMufasaBitmap.Create;
        Result.SetSize(150, 150);

        c := getTClient;
        Result.CopyClientToBitmap(
            c.IOManager, false, 0, 0, MMCX-75, MMCY-75, MMCX+75, MMCY+75
          );

      except
        Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: Ollybest & J J
    // gets the rotated RS minimap and rotates to face north
    // needed for SPS to work at any compass angle
    function SPS_RotateMinimap: TMufasaBitmap;
    var
      W, H, t: Integer;
      mmBMP, rBMP: TMufasaBitmap;
      MiddleBMP: TPoint;
    begin
      try
        t := getSystemTime();

        //gathering minimap
        mmBMP := SPS_GatherMinimap;

        //rotating minimap
        rBMP := GetMufasaBitmap(RotateBitmap(mmBMP.index, 0-rs_GetCompassAngleRadians))

        //getting the middle of the rotated bitmap
        GetBitmapSize(rBMP.Index, W, H);
        MiddleBMP := Point(W/2, H/2);

        //creating the result by using a 74 radius around the centre
        Result := rbmp.Copy(MiddleBMP.X-74, MiddleBMP.Y-74, MiddleBMP.X+74, MiddleBMP.Y+74);

        mmBMP.free
        rbmp.free

        If SPS_Debug Then
          Writeln('Rotating map took '+toStr(getSystemTime - t)+' ms.');

      except
        Writeln('SPS_RotateMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: marpis & Coh3n
    // Gets the starting area coordinates depending on the area image
    procedure SPS_GetAreaCoords(Area: string; var x, y: integer);
    var
      p: integer;
    begin
      // if it's a specific dungeon map (i.e. name isn't 0_0, 10_2, etc.)
      if (length(getNumbers(Area)) < 2) then
      begin
        x := 0;
        y := 0;
        Exit;
      end;

      p := pos('_', Area);

      x := StrToIntDef(copy(Area, 1, p - 1), -1);
      y := StrToIntDef(copy(Area, p + 1, Length(Area) - p), -1);

      //writeln('SPS_GetAreaCoords: '+toStr(point(x, y)));
    end;

    // Author: marpis
    // Converts a point from a map piece to a point on the entire map
    function SPS_LocalToGlobal(Area: string; x, y: integer): TPoint;
    var
      cx, cy: integer;
    begin
      SPS_GetAreaCoords(Area, cx, cy);
      Result.x := (cx * 400) + x;
      Result.y := (cy * 400) + y;
    end;

    // Author: marpis
    // Converts a point from the entire map to a point on the main screen
    function SPS_GlobalToLocal(x, y: integer): TPoint;
    var
      cx, cy: integer;
    begin
      cx := Floor(x / 400);
      cy := Floor(y / 400);

      Result.x := x - (cx * 400);
      Result.y := y - (cy * 400);
    end;

    // Author: marpis
    // Returns the coordinates (x, y) in the form of a string
    function SPS_AreaCoordsToString(x, y: integer): string;
    begin
      Result := IntToStr(x)+'_'+IntToStr(y);
    end;

    // Author: Coh3n
    // Returns a TPA of the areas' values
    function SPS_TPAFromAreas(areas: TStringArray): TPointArray;
    var
      i: integer;
    begin
      setLength(result, length(areas));

      for i := 0 to high(areas) do
        SPS_GetAreaCoords(areas[i], result[i].x, result[i].y);
    end;

    // Author: Coh3n
    // Sorts the areas by columns, and sorts each column by rows
    // Example: ['1_5', '1_3', '0_5'] results ['0_5', '1_3', '1_5']
    function SPS_SortAreas(areas: TStringArray): TStringArray;
    var
      i, j: integer;
      tpa: TPointArray;
    begin
      setLength(tpa, length(areas));

      tpa := SPS_TPAFromAreas(areas);
      clearDoubleTPA(tpa);

      sortTPAByX(tpa, true); // first sort by column number

      // then sort the Y values for each column number
      for i := 0 to high(tpa) do
        for j := i to high(tpa) do
          if (tpa[i].x = tpa[j].x) then
            if (tpa[i].y > tpa[j].y) then
              tSwap(tpa[i], tpa[j]);

      setLength(result, length(tpa));

      for i := 0 to high(tpa) do
        result[i] := SPS_AreaCoordsToString(tpa[i].x, tpa[i].y);

      //writeln('SPS_SortAreas: '+toStr(result));
    end;

    // Author: Coh3n
    // Loads the "Area" image
    function SPS_GetArea(Area: string; surface: integer): TMufasaBitmap;
    var
      x, y: integer;
      S: string;
    begin
      SPS_GetAreaCoords(Area, x, y);

      case surface of
        RUNESCAPE_SURFACE: s := RUNESCAPE_SURFACE_FOLDER;
        RUNESCAPE_OTHER: s := RUNESCAPE_OTHER_FOLDER;
      end;

      try
          Result := TMufasaBitmap.Create;
            Result.LoadFromFile(SPS_IMG_PATH + s + Area + SPS_IMG_FMT);
      except
        Writeln('SPS_GetArea ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: Coh3n
    // Merges the SPS 'areas' into one bitmap (makes more more accurate GetMyPos)
    function SPS_MergeAreas(areas: TStringArray): TMufasaBitmap;
    var
      t, i, l, x, y, diffX, diffY, newWidth, newHeight: integer;
      startPoint: TPoint;
      newAreas: TStringArray;
      xVals, yVals: TIntegerArray;
      bmpTemp: TMufasaBitmap;
      tmpTPA: TPointArray;
    begin
      if (length(areas) <= 0) then
        exit;

      t := getSystemTime();

      // sort the areas from by columns/rows; remove duplicates
      newAreas := SPS_SortAreas(areas);
      l := length(newAreas);

      // if there's only one area in the array
      if (l = 1) then
      begin
        result := SPS_GetArea(areas[0], RUNESCAPE_SURFACE);
        exit;
      end;

      // get the x and y values for each area
      setLength(xVals, l);
      setLength(yVals, l);

      for i := 0 to high(newAreas) do
        SPS_GetAreaCoords(newAreas[i], xVals[i], yVals[i]);

      // get the lowest Y value so we can calculate the starting point to draw the first image
      tmpTPA := SPS_TPAFromAreas(newAreas);
      sortTPAByY(tmpTPA, true);

      try
        result := TMufasaBitmap.create();

        // calculate the starting point
        // x is always 0 because of how the areas are sorted
        // y is relative to the lowest y value in the areas
        SPS_GetAreaCoords(newAreas[0], x, y);
        startPoint.x := 0;
        startPoint.y := ((y - tmpTPA[0].y) * 400);

        // draw the first area to the starting point on the bitmap
        bmpTemp := SPS_GetArea(newAreas[0], RUNESCAPE_SURFACE);
        result.SetSize(bmpTemp.width, bmpTemp.height + startPoint.y);
        bmpTemp.fastDrawTransparent(startPoint.x, startPoint.y, result);
        bmpTemp.free();

        // loop through each area, drawing them to the result bitmap
        // coordinates are calculated relative to the first area drawn (areas[0])
        for i := 0 to (l - 2) do
        begin
          diffX := (xVals[i + 1] - xVals[0]);
          diffY := (yVals[i + 1] - yVals[0]);

          newWidth := 500 + (round(abs(diffX)) * 400);
          newHeight := 500 + (round(abs(diffY)) * 400);

          // only set the size if the width or height is increasing
          if (newWidth > result.width) then
            result.setSize(newWidth, result.height);

          if (newHeight > result.height) then
            result.setSize(result.width, newHeight);

          // copy the area image to the resulting bitmap
          bmpTemp := SPS_GetArea(newAreas[i + 1], RUNESCAPE_SURFACE);
          bmpTemp.fastDrawTransparent(startPoint.x + (diffX * 400 + 1),
                                      startPoint.y + (diffY * 400 + 1), result);
          bmpTemp.free();
        end;

        //result.saveToFile('C:/Simba/test.bmp');
      except
        Writeln('SPS_MergeAreas ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;

      if (SPS_Debug) then
        writeln('SPS_MergeAreas: Merged areas in '+toStr(getSystemTime - t)+' ms.');
    end;

    // Author: Coh3n
    // Returns an SPS area of lowest x and y value. Used for calculating the
    // player's correct position
    function SPS_GetTopLeftCoords(areas: TStringArray): string;
    var
      tpa: TPointArray;
    begin
      tpa := SPS_TPAFromAreas(areas);

      if (length(tpa) <= 0) then
      begin
        result := '0_0';
        exit;
      end;

      sortTPAByX(tpa, true);
      result := toStr(tpa[0].x);

      sortTPAByY(tpa, true);
      result := result + '_'+toStr(tpa[0].y);

      //writeln('SPS_GetTopLeftCoords: '+result);
    end;

    // Author: marpis & SRL Community
    function SPS_GetMyPos(): TPoint;
    var
      Minimap: TMufasaBitmap;
      SmallMap: T3DIntegerArray;
      a, t, FoundMatches: integer;
      P: TPoint;
      Searches: extended;
    begin
      Result := Point(-1, -1);

      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;

      if (not LoggedIn) then
        Exit;

      if (SPS_Tolerance < 1.0) then
        SPS_Tolerance := 600.0;

      if (SPS_MatchesPercent = 0.0) then
        SPS_MatchesPercent := 0.35;

      a := round(rs_GetCompassAngleDegrees);

      if (SPS_AnyAngle) and (inRange(a, 10, 350)) then
        Minimap := SPS_RotateMinimap()
      else begin
        if (inRange(a, 10, 350)) then
          if (SPS_ClickNorth) then
            ClickNorth(SRL_ANGLE_HIGH)
          else
            MakeCompass('N');

        Minimap := SPS_GatherMinimap();
      end;

      t := getSystemTime();
      SPS_FilterMinimap(Minimap);
      //DrawBitmapDebugImg(Minimap.Index);
      //DisplayDebugImgWindow(150, 150);

      {$IFDEF SIMBAMAJOR990}
      SetLength(SmallMap, 0); // Using this instead of SmallMap := [];
      SPS_BitmapToMap(Minimap, SPS_Accuracy, SmallMap);
      {$ELSE}
      SmallMap := [];
      SmallMap := SPS_BitmapToMap(Minimap, SPS_Accuracy);
      {$ENDIF}

      FoundMatches := SPS_FindMapInMap(P.x, P.y, SPS_AreaMaps, SmallMap, SPS_Tolerance);
      Searches := ((Minimap.Width / SPS_Accuracy) * (Minimap.Height / SPS_Accuracy));
    {
      writeln('fx: '+toStr(p.x)+' ~ on area: '+toStr(P.X * SPS_Accuracy + (Minimap.Width / 2)));
      writeln('fy: '+toStr(p.y)+' ~ on area: '+toStr(P.Y * SPS_Accuracy + (Minimap.Width / 2)));
      writeln('matches: '+toStr(foundMatches));
      writeln('searches: '+toStr(searches));
      writeln('percent: '+toStr(FoundMatches / Searches));
    }

      if ((FoundMatches / Searches) > SPS_MatchesPercent) then
        Result := SPS_LocalToGlobal(SPS_GetTopLeftCoords(SPS_Areas), // the top left of the total area
                                    P.x * SPS_Accuracy + (Minimap.Width / 2),
                                    P.y * SPS_Accuracy + (Minimap.Width / 2));

      Minimap.Free;

      t := (GetSystemTime - t);
      if (SPS_Debug) then
        Writeln('SPS_GetMyPos: Finished in '+ToStr(t)+' ms. Result = '+ToStr(Result));
    end;

    // Author: marpis
    // Finds position P in minimap by checking your own location
    function SPS_PosToMM(P: TPoint): TPoint;
    var
      MyPos: TPoint;
    begin
      if not LoggedIn then
        Exit;

      Result := Point(-1, -1);
      MyPos := SPS_GetMyPos;

      if (Distance(MyPos.X, MyPos.Y, P.X, P.Y) < 75) then
        Result := RotatePoint(Point(MMCX + P.X - MyPos.X, MMCY + P.Y - MyPos.Y), 0-rs_GetCompassAngleRadians, MMCX, MMCY);
    end;

    // Author: marpis
    // Walks to position, P.
    function SPS_WalkToPos(P: TPoint): boolean;
    var
      MM: TPoint;
    begin
      if not LoggedIn then
        Exit;

      MM := SPS_PosToMM(P);

      if (MM.X > 0) then
      begin
        if (SPS_MultiMouse) then
          MultiMouse(MM.X, MM.Y, 25, 3, false)
        else
          Mouse(MM.X, MM.Y, 0, 0, mouse_Left);

        if WaitFunc(@IsMoving, 1, 3000 + random(500)) then
          while IsMoving do
            Flag;

        Result := True;
      end;
    end;

    // Author: marpis
    // Returns true if the point "Pt" is on the minimap
    function SPS_PosOnMM(Pt: TPoint): Boolean;
    var
      p: TPoint;
    begin
      p := SPS_PosToMM(Pt);
      Result := rs_OnMinimap(p.x, p.y);
    end;

    // Author: marpis & Coh3n
    // Walks the path "Path"; always walks to the furthest point possible
    function SPS_WalkPath(Path: TPointArray): boolean;
    var
      I, H, T, D, Fails: integer;
      P, MM, MMF: TPoint;
    begin
      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;

      H := High(Path);
      T := GetSystemTime + 20000 + Random(5000);
      Fails := 0;

      while (not Result) and (GetSystemTime < T) and (Fails < 5) do
      begin
        if (not LoggedIn()) then
          Exit;

        RunEnergy(20);
        P := SPS_GetMyPos();

        for I := H downto 0 do
        begin
          MM := RotatePoint(Point(MMCX + Path[I].X - P.X, MMCY + Path[I].Y - P.Y),
                            0-rs_GetCompassAngleRadians, MMCX, MMCY);

          if MM = MMF then
            Inc(Fails);

          D := Distance(MM.X, MM.Y, MMCX, MMCY);

          if (D < 10) then
            break
          else
            if (D < 70) then
            begin
              if (SPS_MultiMouse) then
                MultiMouse(MM.X, MM.Y, 25, 3, false)
              else
                Mouse(MM.X, MM.Y, 5, 5, mouse_Left);

              MMF := MM;
              FFlag(5 + (Integer(I <> H) * 15));

              T := getSystemTime + 20000 + Random(1000);
                Break;
            end;
        end;

        Result := (I = H);
      end;
    end;

    // Walks blindly from the player's current position to the point T
    function SPS_BlindWalk(P: TPoint): Boolean;
    var
      Tries: Integer;
      M: TPoint;
      ctrlPoints: TPointArray;
    begin
      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;

      repeat
        if (not LoggedIn()) then
          Exit;

        M := SPS_GetMyPos();

        if (M.X = -1) then
          Continue;

        if (Length(ctrlPoints) = 0) then
          ctrlPoints := TPABetweenPoints(Point(M.X, M.Y), Point(P.X, P.Y), 20 + Random(15), 10);

        Inc(Tries);
        if (Tries > 20) then
          Exit;

        Result := SPS_WalkPath(ctrlPoints);
      until(Result);
    end;

    // Author: Coh3n
    // Sets up SPS; needs to be called if you want to switch RS surfaces
    function SPS_Setup(surface: integer; areas: TStringArray): boolean;
    var
      t: integer;
      tmp: TMufasaBitmap;
    begin
      t := getSystemTime;

      setLength(SPS_AreaMaps, 0);
      setLength(SPS_Areas, 0);

      SPS_MultiMouse := true;
      SPS_Accuracy := 4;

      if (length(areas) > 0) then
      begin
        if (surface = RUNESCAPE_SURFACE) then
          tmp := SPS_MergeAreas(areas) // combine the SPS areas into 1; makes for a more accurate read
        else
          if (surface = RUNESCAPE_OTHER) then
            if (length(areas) = 1) then
              tmp := SPS_GetArea(areas[0], surface)
            else begin
              writeln('SPS_Setup(): Invalid dungeon areas. You can only select one!');
              exit;
            end;

        SPS_IsSetup := true;
        result := true;

        {$IFDEF SIMBAMAJOR990}
        SPS_BitmapToMap(tmp, SPS_Accuracy, SPS_AreaMaps);
        {$ELSE}
        SPS_AreaMaps := SPS_BitmapToMap(tmp, SPS_Accuracy);
        {$ENDIF}

        if (surface = RUNESCAPE_SURFACE) then
          SPS_Areas := SPS_SortAreas(areas)
        else
          if (surface = RUNESCAPE_OTHER) then
            SPS_Areas := areas;

        tmp.free();

      end else
        writeln('SPS_Setup(): ERROR: SPS areas are not set!');

      t := (getSystemTime - t);

      if (SPS_Debug) and (result) then
        writeln('[SPS] SPS_Setup() took '+toStr(t)+' ms. Areas: '+toStr(SPS_Areas));
    end;


    Step 1)
    Go to line 51. Were it says:

    Simba Code:
    c.IOManager, false, 0, 0, MMCX-75, MMCY-75, MMCX+75, MMCY+75

    Change MMCX and MMCY to the center of the minimap of your RSPS of choice. Change 75 to the distance from the center of the minimap to the very edge of the minimap (probably still 75, but you can change it if you want it to be exact)

    step 2)

    Go to line 340. Were it says
    Simba Code:
    if (not LoggedIn) then
        Exit;

    There are 1 of 2 things you can do:

    1) make your own logged in function and change it to that

    2) Erase those 2 lines


    Step 3) go to line 403. Repeat step 2, and then go to line 410 were it says:

    Simba Code:
    Result := RotatePoint(Point(MMCX + P.X - MyPos.X, MMCY + P.Y - MyPos.Y), 0-rs_GetCompassAngleRadians, MMCX, MMCY);

    Change all MMCX and MMCY to the center of your minimap, and change rs_GetCompassAngleRadians to your compass function that you created in the compass section(MAKE SURE IT'S THE RADIANS ONE)

    Step 4) Go to line 419. Repeat step 2. Go to line 432, were it says

    Simba Code:
    while IsMoving do
            Flag;

    Create a procedure that will look for the flag DTM on your minimap and wait until it's gone. Replace 'Flag' with this procedures name. Here is what mine looks like:

    Simba Code:
    function rsps_FFlag:Boolean;
    var
      x, y:Integer;
    begin
      result := FindDTM(Flag_DTM, x, y, rsps_MMX1, rsps_MMY1, rsps_MMX2, rsps_MMY2);
    end;
    procedure rsps_Flag;
    begin
      waitFunc(@rsps_FFlag, 100, 6000);
    end;

    Replace rsps_MMX1, rsps_MMY1, rsps_MMX2, and rsps_MMY2 with the bounds of the minimap.

    Step 5) Go to line 468. Repeat step 2 again and then go to line 476 were it says:

    Simba Code:
    MM := RotatePoint(Point(MMCX + Path[I].X - P.X, MMCY + Path[I].Y - P.Y),
                            0-rs_GetCompassAngleRadians, MMCX, MMCY);

    Change all MMCY and MMCX to the center of your minimap, and rs_GetCompassAngleRadians to your compass functions to get the compass angle(MAKE SURE IT'S THE RADIANS ONE)


    Step 6) Go to line 520, and repeat step 2 yet again(you catching what I'm doing yet?) and your done!


    In order for SPS to work for your RSPS of your choice you will have to use custom maps, guide on how to use custom maps: http://villavu.com/forum/showthread.php?t=84360

    DTM

    DTM walking is a good way to walk if your too lazy to edit SPS or if the compass angle is > 15 degrees off the actual minimap. In order for a DTM to be found accurately we must use FindDTMRotated. This will look for the DTM as different angles! But before we do that, you should learn how to create a good DTM on the minimap. First, open up Simba's DTM editor. Next, find the point you want to walk and click there, and then make the tolerance '255'. Example:



    Next, create points with a tolerance of around 35-40 on areas were NPCs/Players can't walk:



    Now click show matching DTM's and make sure the point you want to walk at is the only red point:



    Next, use the FindDTMRotated function to click on it:

    Simba Code:
    FindDTMRotated(DTM, x, y, rsps_MMX1, rsps_MMY1, rsps_MMX2, rsps_MMY2, startD, endD, step, FA)

    startD is the start angle it will look for the DTM, I always put 0, endD is the ending angle that it will look for the DTM at I always put 360, and step is the amount (in degrees) that it will look each time. So if you put 10.00 as step, it will start at startD degrees, go to 10.00, go to 20.00 and so on until it reaches the endD degrees. The lower the number you put, the longer it will take. I advise (if) you are just going to look for 1 7.00-10.00.

    Now just looking for 1 DTM for 1 point may not be accurate, so I created this function that allows you have have multple DTMs each point. If the first DTM isn't found for the point, it moves onto the second, then third etc etc.
    function:

    Simba Code:
    function walk_dtmPath(Points:T2DIntegerArray):Boolean;
    var
      i, l, x, y:Integer;
      FA:Extended;
    begin
      for i := 0 to high(Points) do
      begin
        for l := 0 to high(Points[i]) do
        begin
          if FindDTMRotated(Points[i][l], x, y, rsps_MMX1, rsps_MMY1, rsps_MMX2, rsps_MMY2, 0, 360, 14.00, FA) then
          begin
            if (distance(x, y, 648, 83) > 15) then
            begin
              Mouse(x, y, 0, 0, Mouse_left);
              wait(1200);
              if (rsps_FFlag) then
              begin
                rsps_Flag;
                break;
              end;
            end;
          end;
        end;
      end;
    end;

    Of course you will have to make your own rsps_FFlag and rsps_Flag functions.

    Here is how I use it. First I declare a path as a record:

    Simba Code:
    type Path = record
      dtmpoint:T2DIntegerArray;
    end;

    Next, I create a variable and make it refer to that record like so:

    Simba Code:
    var
      toBank:Path;

    And then I declare DTMs for each point:

    Simba Code:
    toBank.dtmPoint[0][0] := DTMFromString('m1gAAAHic42JgYOhiYmCoBeJZQNwLxCVAvBqIC4G4DSo+H4gdgGoNgdgEiA2A2AmI/YDYEsq3A2JXIH77loHhzZMXePG7d+8Y/gPV6hKBGYnECAAAvt4k7w==');

    To add another DTM for that point just increase the second 0 by 1:

    Simba Code:
    toBank.dtmPoint[0][1] := DTMFromString('mrAAAAHic42BgYJjHxMCwFIjXAPFGIN4CxJuAeD4QdwJxKlBNKRBnM0DYMUAcDsRlQFwIxGfOMDC8efICBb979w7O1gWqwYcZCWAYAAAybh6t');

    Then to add Points increase the first 0 by 1. Example of a path with 4 points:

    Simba Code:
    toBank.dtmPoint[0][0] := DTMFromString('m1gAAAHic42JgYOhiYmCoBeJZQNwLxCVAvBqIC4G4DSo+H4gdgGoNgdgEiA2A2AmI/YDYEsq3A2JXIH77loHhzZMXePG7d+8Y/gPV6hKBGYnECAAAvt4k7w==');
      toBank.dtmPoint[0][1] := DTMFromString('mrAAAAHic42BgYJjHxMCwFIjXAPFGIN4CxJuAeD4QdwJxKlBNKRBnM0DYMUAcDsRlQFwIxGfOMDC8efICBb979w7O1gWqwYcZCWAYAAAybh6t');
      toBank.dtmPoint[1][0] := DTMFromString('blahblahhhfdjfk');
      toBank.dtmPoint[1][1] := DTMFromString('dfgsdfgdfsd');
      toBank.dtmPoint[1][2] := DTMFromString('dsfgfdsgdfdg');
      toBank.dtmPoint[2][0] := DTMFromString('blahblahhhfdjfk');
      toBank.dtmPoint[2][1] := DTMFromString('dfgsdfgdfsd');
      toBank.dtmPoint[3][0] := DTMFromString('blahblahhhfdjfk');
      toBank.dtmPoint[3][1] := DTMFromString('dfgsdfgdfsd');
      toBank.dtmPoint[3][2] := DTMFromString('dsfgfdsgdfdg');

    And then to walk the path I just do

    Simba Code:
    walk_dtmPath(ToBank.dtmPoint);



    Inventory functions

    Inventory functions are hella useful. I will be using @Janilabo's Explode box function here! Ok first let's say you want to get the amount of items in your inventory. First declare a TBoxArray variable:

    Simba Code:
    var
      Inventory:TBoxArray;

    Next use this function to make the variable Inventory Represent every one of the inventory slots:

    Simba Code:
    function ExplodeBox(bx: TBox; rows, columns: integer): TBoxArray;
    var
      r, c, w, h, ew, eh, ow, oh, i, x, y: integer;
    begin
      if ((rows > 0) and (columns > 0) and (bx.X1 <= bx.X2) and (bx.Y1 <= bx.Y2)) then
      begin
        w := ((bx.X2 - bx.X1) + 1);
        h := ((bx.Y2 - bx.Y1) + 1);
        if (rows < 1) then
          rows := 1
        else
          if (rows > h) then
            rows := h;
        if (columns < 1) then
          columns := 1
        else
          if (columns > w) then
            columns := w;
        w := (w div columns);
        h := (h div rows);
        ew := (((bx.X2 - bx.X1) + 1) - (w * columns));
        eh := (((bx.Y2 - bx.Y1) + 1) - (h * rows));
        SetLength(Result, (rows * columns));
        y := bx.Y1;
        for r := 0 to (rows - 1) do
        begin
          x := bx.X1;
          if ((eh > 0) and (r < eh)) then
            oh := 1
          else
            oh := 0;
          for c := 0 to (columns - 1) do
          begin
            if ((ew > 0) and (c < ew)) then
              ow := 1
            else
              ow := 0;
            i := ((r * columns) + c);
            Result[i].X1 := x;
            Result[i].X2 := (x + (w - 1) + ow);
            Result[i].Y1 := y;
            Result[i].Y2 := (y + (h - 1) + oh);
            x := (Result[i].X2 + 1);
          end;
          y := (Result[i].Y2 + 1);
        end;
      end else
        SetLength(Result, 0);
    end;

    You use it by getting the exact bounds of the inventory:



    The most easy way to do this is to put a large item in the first slot, and another large item in the last slot.

    Simba Code:
    Inventory := ExplodeBox(IntToBox(X1, Y1, X2, Y2), 7, 4);

    7 is the number of rows, 4 is the number of colums.

    Replaces X1, Y1, X2, and Y2 with the bounds of the inventory.

    Now, EVERY SINGLE item in the whole entire game of Runescape that has ever been released has a black outline. There is no such thing as an item without a black outline, we you will have to find out what color that is by finding.... the black outline on a item like this:



    The color will usually 65536 but it's different for some servers. I advise you use ACA so you can make sure the color you chose is infact the black outline. As you can see here, 65536 is infact the black outline:


    Now first, we want to see if a selected slot is full:

    Simba Code:
    function rsps_slotFull(slot:Integer):Boolean;
    var
      x, y:Integer;
    begin
      if FindColor(x, y, 65536, Inventory[slot].x1, Inventory[slot].y1, Inventory[slot].x2, Inventory[slot].y2) then
        result := true;
    end;

    This will look at the index that you have chosen, so if you do rsps_slotFull(0) it will check the first slot.

    Now to get the inventory count, all you have to do is call the rsps_slotFull function inside of another function like so:

    Simba Code:
    function rsps_Invcount:Integer;
    var
      i:Integer;
    begin
     for i := 0 to high(Inventory) do
      begin
        if rsps_slotFull(i) then
          result := result + 1;
      end;
    end;

    TADA!

    Infull:

    Simba Code:
    function rsps_invFull:Boolean;
    begin
      result := (rsps_invcount = 28);
    end;

    Count Item(DTM):

    Simba Code:
    function rsps_CountInventoryDTM(DTMSearch:Integer):Integer;
    var
      i, x, y:Integer;
    begin
      for i := 0 to high(Inventory) do
      begin
        if FindDTM(DTMSearch, x, y, Inventory[i].x1, Inventory[i].y1, Inventory[i].x2, Inventory[i].y2) then
          result := result + 1;
      end;
    end;



    Hope this guide help! If you see any grammar mistakes or need help just post below

  2. #2
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Wow thank you! Going to try SPS soon

    Also, you should totally make a guide on killing monsters and looting them...

  3. #3
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    Wow thank you! Going to try SPS soon

    Also, you should totally make a guide on killing monsters and looting them...
    I feel like killing monsters and looting would be under the TPA/ATPA category since it is the same as you would for RS

  4. #4
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    I feel like killing monsters and looting would be under the TPA/ATPA category since it is the same as you would for RS
    What about just killing the monsters or detecting if you're in combat? I know it's very different on RSPS's.

    Also do you plan on making an advanced guide?

  5. #5
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    What about just killing the monsters or detecting if you're in combat? I know it's very different on RSPS's.

    Also do you plan on making an advanced guide?
    I think I'll write a more advanced guide when I learn more advanced stuff (such as loading smart(which only works with a small portion if any servers))

  6. #6
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    I think I'll write a more advanced guide when I learn more advanced stuff (such as loading smart(which only works with a small portion if any servers))
    I feel like a noob for asking this.. but how do you find the bounds for the compass angle? Is that just another name for finding like a cord at the top left and a cord at the bottom right? (Making a box basically)

  7. #7
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    I feel like a noob for asking this.. but how do you find the bounds for the compass angle? Is that just another name for finding like a cord at the top left and a cord at the bottom right? (Making a box basically)
    Yea find the very top left and the very bottom right

  8. #8
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    Yea find the very top left and the very bottom right
    So far all the inventory functions are working great, but I have one question.

    For the Count Item, do we replace the DTMsearch with the DTM to count?

  9. #9
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    So far all the inventory functions are working great, but I have one question.

    For the Count Item, do we replace the DTMsearch with the DTM to count?
    DTMSearch is a parameter for the function. Example:

    var
    IronOre:Integer;

    IronOre := DTMFromString('jkdffffffffffffffffffffffffffffffff ffffffffffffff');

    rsps_CountInventoryDTM(IronOre);



    DTM's are integer's

  10. #10
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    DTMSearch is a parameter for the function. Example:

    var
    IronOre:Integer;

    IronOre := DTMFromString('jkdffffffffffffffffffffffffffffffff ffffffffffffff');

    rsps_CountInventoryDTM(IronOre);



    DTM's are integer's
    Yeah that's what I was trying to say :P Thanks again.

  11. #11
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Well um... I can't get SPS to work... I'm not getting errors, I start the script and it doesn't do anything... lol


    Simba Code:
    Program TestPath;
    {$i srl/srl.Simba}
    {$I RL_SPS.Simba}

    var

      testpath: tpointarray;


    begin
      testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
      SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
      SPS_WalkPath(testpath);
    end.

  12. #12
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    Well um... I can't get SPS to work... I'm not getting errors, I start the script and it doesn't do anything... lol


    Simba Code:
    Program TestPath;
    {$i srl/srl.Simba}
    {$I RL_SPS.Simba}

    var

      testpath: tpointarray;


    begin
      testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
      SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
      SPS_WalkPath(testpath);
    end.
    You gotta call SetupSPS; I think

    Can I see a copy of your SPS file?

  13. #13
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    You gotta call SetupSPS; I think

    Can I see a copy of your SPS file?
    Yup,

    Simba Code:
    (*
    SPS ~ SRL Positioning System
    ============================

    Concept and original work done by marpis @ SRL-Forums.  Work continued by Coh3n
    and members of the SRL community.

    *)

    {$include_once RLTools.simba}
    {$loadlib sps}

    const
      // Path where all the SPS files are
      SPS_IMG_PATH = IncludePath + 'SPS\img\';
      SPS_IMG_FMT  = '.png';

      // Surfaces
      RUNESCAPE_SURFACE = 0;
      RUNESCAPE_SURFACE_FOLDER = 'runescape_surface\';

      RUNESCAPE_OTHER = 1;
      RUNESCAPE_OTHER_FOLDER = 'runescape_other\';

    // User defined SPS global variables
    var
      SPS_Debug: boolean;
      SPS_MultiMouse: boolean; // simulates a human like "spam-click" when walking
      SPS_AnyAngle: boolean;   // true = work at any angle; false = only north
      SPS_ClickNorth: boolean; // call ClickNorth instead of MakeCompass to set the compass to north

    // SPS Global variables
    var
      SPS_Areas: TStringArray;
      SPS_AreaMaps: T3DIntegerArray; // Grids of the combined SPS_Areas
      SPS_Tolerance, SPS_MatchesPercent: extended;
      SPS_Accuracy: integer; // Splits minimap/areas into squares of this side length; used for area recognition
      SPS_IsSetup: boolean; // Used to make sure the user calls SPS_Setup

    // Author: marpis & Coh3n
    // Returns an image of the minimap in a TMufasaBitmap
    function SPS_GatherMinimap: TMufasaBitmap;
    var
      c: TClient;
    begin
      try
        Result := TMufasaBitmap.Create;
        Result.SetSize(150, 150);

        c := getTClient;
        Result.CopyClientToBitmap(
            c.IOManager, false, 0, 0, 628-75, 86-75, 628+75, 86+75
          );

      except
        Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: Ollybest & J J
    // gets the rotated RS minimap and rotates to face north
    // needed for SPS to work at any compass angle
    function SPS_RotateMinimap: TMufasaBitmap;
    var
      W, H, t: Integer;
      mmBMP, rBMP: TMufasaBitmap;
      MiddleBMP: TPoint;
    begin
      try
        t := getSystemTime();

        //gathering minimap
        mmBMP := SPS_GatherMinimap;

        //rotating minimap
        rBMP := GetMufasaBitmap(RotateBitmap(mmBMP.index, 0-rs_GetCompassAngleRadians))

        //getting the middle of the rotated bitmap
        GetBitmapSize(rBMP.Index, W, H);
        MiddleBMP := Point(W/2, H/2);

        //creating the result by using a 74 radius around the centre
        Result := rbmp.Copy(MiddleBMP.X-74, MiddleBMP.Y-74, MiddleBMP.X+74, MiddleBMP.Y+74);

        mmBMP.free
        rbmp.free

        If SPS_Debug Then
          Writeln('Rotating map took '+toStr(getSystemTime - t)+' ms.');

      except
        Writeln('SPS_RotateMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: marpis & Coh3n
    // Gets the starting area coordinates depending on the area image
    procedure SPS_GetAreaCoords(Area: string; var x, y: integer);
    var
      p: integer;
    begin
      // if it's a specific dungeon map (i.e. name isn't 0_0, 10_2, etc.)
      if (length(getNumbers(Area)) < 2) then
      begin
        x := 0;
        y := 0;
        Exit;
      end;

      p := pos('_', Area);

      x := StrToIntDef(copy(Area, 1, p - 1), -1);
      y := StrToIntDef(copy(Area, p + 1, Length(Area) - p), -1);

      //writeln('SPS_GetAreaCoords: '+toStr(point(x, y)));
    end;

    // Author: marpis
    // Converts a point from a map piece to a point on the entire map
    function SPS_LocalToGlobal(Area: string; x, y: integer): TPoint;
    var
      cx, cy: integer;
    begin
      SPS_GetAreaCoords(Area, cx, cy);
      Result.x := (cx * 400) + x;
      Result.y := (cy * 400) + y;
    end;

    // Author: marpis
    // Converts a point from the entire map to a point on the main screen
    function SPS_GlobalToLocal(x, y: integer): TPoint;
    var
      cx, cy: integer;
    begin
      cx := Floor(x / 400);
      cy := Floor(y / 400);

      Result.x := x - (cx * 400);
      Result.y := y - (cy * 400);
    end;

    // Author: marpis
    // Returns the coordinates (x, y) in the form of a string
    function SPS_AreaCoordsToString(x, y: integer): string;
    begin
      Result := IntToStr(x)+'_'+IntToStr(y);
    end;

    // Author: Coh3n
    // Returns a TPA of the areas' values
    function SPS_TPAFromAreas(areas: TStringArray): TPointArray;
    var
      i: integer;
    begin
      setLength(result, length(areas));

      for i := 0 to high(areas) do
        SPS_GetAreaCoords(areas[i], result[i].x, result[i].y);
    end;

    // Author: Coh3n
    // Sorts the areas by columns, and sorts each column by rows
    // Example: ['1_5', '1_3', '0_5'] results ['0_5', '1_3', '1_5']
    function SPS_SortAreas(areas: TStringArray): TStringArray;
    var
      i, j: integer;
      tpa: TPointArray;
    begin
      setLength(tpa, length(areas));

      tpa := SPS_TPAFromAreas(areas);
      clearDoubleTPA(tpa);

      sortTPAByX(tpa, true); // first sort by column number

      // then sort the Y values for each column number
      for i := 0 to high(tpa) do
        for j := i to high(tpa) do
          if (tpa[i].x = tpa[j].x) then
            if (tpa[i].y > tpa[j].y) then
              tSwap(tpa[i], tpa[j]);

      setLength(result, length(tpa));

      for i := 0 to high(tpa) do
        result[i] := SPS_AreaCoordsToString(tpa[i].x, tpa[i].y);

      //writeln('SPS_SortAreas: '+toStr(result));
    end;

    // Author: Coh3n
    // Loads the "Area" image
    function SPS_GetArea(Area: string; surface: integer): TMufasaBitmap;
    var
      x, y: integer;
      S: string;
    begin
      SPS_GetAreaCoords(Area, x, y);

      case surface of
        RUNESCAPE_SURFACE: s := RUNESCAPE_SURFACE_FOLDER;
        RUNESCAPE_OTHER: s := RUNESCAPE_OTHER_FOLDER;
      end;

      try
          Result := TMufasaBitmap.Create;
            Result.LoadFromFile(SPS_IMG_PATH + s + Area + SPS_IMG_FMT);
      except
        Writeln('SPS_GetArea ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: Coh3n
    // Merges the SPS 'areas' into one bitmap (makes more more accurate GetMyPos)
    function SPS_MergeAreas(areas: TStringArray): TMufasaBitmap;
    var
      t, i, l, x, y, diffX, diffY, newWidth, newHeight: integer;
      startPoint: TPoint;
      newAreas: TStringArray;
      xVals, yVals: TIntegerArray;
      bmpTemp: TMufasaBitmap;
      tmpTPA: TPointArray;
    begin
      if (length(areas) <= 0) then
        exit;

      t := getSystemTime();

      // sort the areas from by columns/rows; remove duplicates
      newAreas := SPS_SortAreas(areas);
      l := length(newAreas);

      // if there's only one area in the array
      if (l = 1) then
      begin
        result := SPS_GetArea(areas[0], RUNESCAPE_SURFACE);
        exit;
      end;

      // get the x and y values for each area
      setLength(xVals, l);
      setLength(yVals, l);

      for i := 0 to high(newAreas) do
        SPS_GetAreaCoords(newAreas[i], xVals[i], yVals[i]);

      // get the lowest Y value so we can calculate the starting point to draw the first image
      tmpTPA := SPS_TPAFromAreas(newAreas);
      sortTPAByY(tmpTPA, true);

      try
        result := TMufasaBitmap.create();

        // calculate the starting point
        // x is always 0 because of how the areas are sorted
        // y is relative to the lowest y value in the areas
        SPS_GetAreaCoords(newAreas[0], x, y);
        startPoint.x := 0;
        startPoint.y := ((y - tmpTPA[0].y) * 400);

        // draw the first area to the starting point on the bitmap
        bmpTemp := SPS_GetArea(newAreas[0], RUNESCAPE_SURFACE);
        result.SetSize(bmpTemp.width, bmpTemp.height + startPoint.y);
        bmpTemp.fastDrawTransparent(startPoint.x, startPoint.y, result);
        bmpTemp.free();

        // loop through each area, drawing them to the result bitmap
        // coordinates are calculated relative to the first area drawn (areas[0])
        for i := 0 to (l - 2) do
        begin
          diffX := (xVals[i + 1] - xVals[0]);
          diffY := (yVals[i + 1] - yVals[0]);

          newWidth := 500 + (round(abs(diffX)) * 400);
          newHeight := 500 + (round(abs(diffY)) * 400);

          // only set the size if the width or height is increasing
          if (newWidth > result.width) then
            result.setSize(newWidth, result.height);

          if (newHeight > result.height) then
            result.setSize(result.width, newHeight);

          // copy the area image to the resulting bitmap
          bmpTemp := SPS_GetArea(newAreas[i + 1], RUNESCAPE_SURFACE);
          bmpTemp.fastDrawTransparent(startPoint.x + (diffX * 400 + 1),
                                      startPoint.y + (diffY * 400 + 1), result);
          bmpTemp.free();
        end;

        //result.saveToFile('C:/Simba/test.bmp');
      except
        Writeln('SPS_MergeAreas ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;

      if (SPS_Debug) then
        writeln('SPS_MergeAreas: Merged areas in '+toStr(getSystemTime - t)+' ms.');
    end;

    // Author: Coh3n
    // Returns an SPS area of lowest x and y value. Used for calculating the
    // player's correct position
    function SPS_GetTopLeftCoords(areas: TStringArray): string;
    var
      tpa: TPointArray;
    begin
      tpa := SPS_TPAFromAreas(areas);

      if (length(tpa) <= 0) then
      begin
        result := '0_0';
        exit;
      end;

      sortTPAByX(tpa, true);
      result := toStr(tpa[0].x);

      sortTPAByY(tpa, true);
      result := result + '_'+toStr(tpa[0].y);

      //writeln('SPS_GetTopLeftCoords: '+result);
    end;

    // Author: marpis & SRL Community
    function SPS_GetMyPos(): TPoint;
    var
      Minimap: TMufasaBitmap;
      SmallMap: T3DIntegerArray;
      a, t, FoundMatches: integer;
      P: TPoint;
      Searches: extended;
    begin
      Result := Point(-1, -1);

      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;


      if (SPS_Tolerance < 1.0) then
        SPS_Tolerance := 600.0;

      if (SPS_MatchesPercent = 0.0) then
        SPS_MatchesPercent := 0.35;

      a := round(rs_GetCompassAngleDegrees);

      if (SPS_AnyAngle) and (inRange(a, 10, 350)) then
        Minimap := SPS_RotateMinimap()
      else begin
        if (inRange(a, 10, 350)) then
          if (SPS_ClickNorth) then
            ClickNorth(SRL_ANGLE_HIGH)
          else
            MakeCompass('N');

        Minimap := SPS_GatherMinimap();
      end;

      t := getSystemTime();
      SPS_FilterMinimap(Minimap);
      //DrawBitmapDebugImg(Minimap.Index);
      //DisplayDebugImgWindow(150, 150);

      {$IFDEF SIMBAMAJOR990}
      SetLength(SmallMap, 0); // Using this instead of SmallMap := [];
      SPS_BitmapToMap(Minimap, SPS_Accuracy, SmallMap);
      {$ELSE}
      SmallMap := [];
      SmallMap := SPS_BitmapToMap(Minimap, SPS_Accuracy);
      {$ENDIF}

      FoundMatches := SPS_FindMapInMap(P.x, P.y, SPS_AreaMaps, SmallMap, SPS_Tolerance);
      Searches := ((Minimap.Width / SPS_Accuracy) * (Minimap.Height / SPS_Accuracy));
    {
      writeln('fx: '+toStr(p.x)+' ~ on area: '+toStr(P.X * SPS_Accuracy + (Minimap.Width / 2)));
      writeln('fy: '+toStr(p.y)+' ~ on area: '+toStr(P.Y * SPS_Accuracy + (Minimap.Width / 2)));
      writeln('matches: '+toStr(foundMatches));
      writeln('searches: '+toStr(searches));
      writeln('percent: '+toStr(FoundMatches / Searches));
    }

      if ((FoundMatches / Searches) > SPS_MatchesPercent) then
        Result := SPS_LocalToGlobal(SPS_GetTopLeftCoords(SPS_Areas), // the top left of the total area
                                    P.x * SPS_Accuracy + (Minimap.Width / 2),
                                    P.y * SPS_Accuracy + (Minimap.Width / 2));

      Minimap.Free;

      t := (GetSystemTime - t);
      if (SPS_Debug) then
        Writeln('SPS_GetMyPos: Finished in '+ToStr(t)+' ms. Result = '+ToStr(Result));
    end;

    // Author: marpis
    // Finds position P in minimap by checking your own location
    function SPS_PosToMM(P: TPoint): TPoint;
    var
      MyPos: TPoint;
    begin

      Result := Point(-1, -1);
      MyPos := SPS_GetMyPos;

      if (Distance(MyPos.X, MyPos.Y, P.X, P.Y) < 75) then
        Result := RotatePoint(Point(964 + P.X - MyPos.X, 104 + P.Y - MyPos.Y), 0-RL_GetCompassAngleRadians, 964, 104);
    end;

    // Author: marpis
    // Walks to position, P.
    function SPS_WalkToPos(P: TPoint): boolean;
    var
      MM: TPoint;
    begin

      MM := SPS_PosToMM(P);

      if (MM.X > 0) then
      begin
        if (SPS_MultiMouse) then
          MultiMouse(MM.X, MM.Y, 25, 3, false)
        else
          Mouse(MM.X, MM.Y, 0, 0, mouse_Left);

        if WaitFunc(@IsMoving, 1, 3000 + random(500)) then
          while IsMoving do
            Flag;

        Result := True;
      end;
    end;

    // Author: marpis
    // Returns true if the point "Pt" is on the minimap
    function SPS_PosOnMM(Pt: TPoint): Boolean;
    var
      p: TPoint;
    begin
      p := SPS_PosToMM(Pt);
      Result := rs_OnMinimap(p.x, p.y);
    end;

    // Author: marpis & Coh3n
    // Walks the path "Path"; always walks to the furthest point possible
    function SPS_WalkPath(Path: TPointArray): boolean;
    var
      I, H, T, D, Fails: integer;
      P, MM, MMF: TPoint;
    begin
      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;

      H := High(Path);
      T := GetSystemTime + 20000 + Random(5000);
      Fails := 0;

      while (not Result) and (GetSystemTime < T) and (Fails < 5) do
      begin

        RunEnergy(20);
        P := SPS_GetMyPos();

        for I := H downto 0 do
        begin
          MM := RotatePoint(Point(964 + Path[I].X - P.X, 104 + Path[I].Y - P.Y),
                            0-RL_GetCompassAngleRadians, 964, 104);

          if MM = MMF then
            Inc(Fails);

          D := Distance(MM.X, MM.Y, MMCX, MMCY);

          if (D < 10) then
            break
          else
            if (D < 70) then
            begin
              if (SPS_MultiMouse) then
                MultiMouse(MM.X, MM.Y, 25, 3, false)
              else
                Mouse(MM.X, MM.Y, 5, 5, mouse_Left);

              MMF := MM;
              FFlag(5 + (Integer(I <> H) * 15));

              T := getSystemTime + 20000 + Random(1000);
                Break;
            end;
        end;

        Result := (I = H);
      end;
    end;

    // Walks blindly from the player's current position to the point T
    function SPS_BlindWalk(P: TPoint): Boolean;
    var
      Tries: Integer;
      M: TPoint;
      ctrlPoints: TPointArray;
    begin
      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;

      repeat

        M := SPS_GetMyPos();

        if (M.X = -1) then
          Continue;

        if (Length(ctrlPoints) = 0) then
          ctrlPoints := TPABetweenPoints(Point(M.X, M.Y), Point(P.X, P.Y), 20 + Random(15), 10);

        Inc(Tries);
        if (Tries > 20) then
          Exit;

        Result := SPS_WalkPath(ctrlPoints);
      until(Result);
    end;

    // Author: Coh3n
    // Sets up SPS; needs to be called if you want to switch RS surfaces
    function SPS_Setup(surface: integer; areas: TStringArray): boolean;
    var
      t: integer;
      tmp: TMufasaBitmap;
    begin
      t := getSystemTime;

      setLength(SPS_AreaMaps, 0);
      setLength(SPS_Areas, 0);

      SPS_MultiMouse := true;
      SPS_Accuracy := 4;

      if (length(areas) > 0) then
      begin
        if (surface = RUNESCAPE_SURFACE) then
          tmp := SPS_MergeAreas(areas) // combine the SPS areas into 1; makes for a more accurate read
        else
          if (surface = RUNESCAPE_OTHER) then
            if (length(areas) = 1) then
              tmp := SPS_GetArea(areas[0], surface)
            else begin
              writeln('SPS_Setup(): Invalid dungeon areas. You can only select one!');
              exit;
            end;

        SPS_IsSetup := true;
        result := true;

        {$IFDEF SIMBAMAJOR990}
        SPS_BitmapToMap(tmp, SPS_Accuracy, SPS_AreaMaps);
        {$ELSE}
        SPS_AreaMaps := SPS_BitmapToMap(tmp, SPS_Accuracy);
        {$ENDIF}

        if (surface = RUNESCAPE_SURFACE) then
          SPS_Areas := SPS_SortAreas(areas)
        else
          if (surface = RUNESCAPE_OTHER) then
            SPS_Areas := areas;

        tmp.free();

      end else
        writeln('SPS_Setup(): ERROR: SPS areas are not set!');

      t := (getSystemTime - t);

      if (SPS_Debug) and (result) then
        writeln('[SPS] SPS_Setup() took '+toStr(t)+' ms. Areas: '+toStr(SPS_Areas));
    end;

  14. #14
    Join Date
    May 2011
    Posts
    24
    Mentioned
    0 Post(s)
    Quoted
    3 Post(s)

    Default

    Hi this tutorial something I wish there was like 2 years a go while I was playing few p servers where I was making pretty basic scripts with just help of color finding boosted with ACA.

    Where I am struggling now is the uptext part where you have to put in TPA and ATPA values. I read the guide about TPAs but didn't really find a way to apply it on this. Maybe if you could add one of your working functions I could try and study it to make mine work as well.

    Thanks in advance.

  15. #15
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by I am new View Post
    Hi this tutorial something I wish there was like 2 years a go while I was playing few p servers where I was making pretty basic scripts with just help of color finding boosted with ACA.

    Where I am struggling now is the uptext part where you have to put in TPA and ATPA values. I read the guide about TPAs but didn't really find a way to apply it on this. Maybe if you could add one of your working functions I could try and study it to make mine work as well.

    Thanks in advance.
    Simba Code:
    function rsps_uptext:string;
    var
      TPA: tpointarray;
      ATPA: t2dpointarray;
    begin
      FindColorsTolerance(TPA, 65535, 438, 14, 469, 23, 0);
      if (length(TPA) > 1) then
      begin
        ATPA := splitTPAEx(TPA, 1, 10);
        filterTPAsbetween(ATPA, 1, 10);
        sortATPAFromFirstPointX(ATPA, point(0, 0));
        result.x := StrToInt(getTextATPA(ATPA, 5, 'fontname'));
      end;
    end;

  16. #16
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    You gotta call SetupSPS; I think

    Can I see a copy of your SPS file?
    Also SetupSPS; doesn't exist lol

  17. #17
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    Also SetupSPS; doesn't exist lol
    Lol haven't used SPS in a while

  18. #18
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    Lol haven't used SPS in a while
    It still doesn't seem to want to do anything...
    Here's the full SPS file again:

    Simba Code:
    (*
    SPS ~ SRL Positioning System
    ============================

    Concept and original work done by marpis @ SRL-Forums.  Work continued by Coh3n
    and members of the SRL community.

    *)

    {$include_once RLTools.simba}
    {$loadlib sps}

    const
      // Path where all the SPS files are
      SPS_IMG_PATH = IncludePath + 'SPS\img\';
      SPS_IMG_FMT  = '.png';

      // Surfaces
      RUNESCAPE_SURFACE = 0;
      RUNESCAPE_SURFACE_FOLDER = 'runescape_surface\';

      RUNESCAPE_OTHER = 1;
      RUNESCAPE_OTHER_FOLDER = 'runescape_other\';

    // User defined SPS global variables
    var
      SPS_Debug: boolean;
      SPS_MultiMouse: boolean; // simulates a human like "spam-click" when walking
      SPS_AnyAngle: boolean;   // true = work at any angle; false = only north
      SPS_ClickNorth: boolean; // call ClickNorth instead of MakeCompass to set the compass to north

    // SPS Global variables
    var
      SPS_Areas: TStringArray;
      SPS_AreaMaps: T3DIntegerArray; // Grids of the combined SPS_Areas
      SPS_Tolerance, SPS_MatchesPercent: extended;
      SPS_Accuracy: integer; // Splits minimap/areas into squares of this side length; used for area recognition
      SPS_IsSetup: boolean; // Used to make sure the user calls SPS_Setup

    // Author: marpis & Coh3n
    // Returns an image of the minimap in a TMufasaBitmap
    function SPS_GatherMinimap: TMufasaBitmap;
    var
      c: TClient;
    begin
      try
        Result := TMufasaBitmap.Create;
        Result.SetSize(150, 150);

        c := getTClient;
        Result.CopyClientToBitmap(
            c.IOManager, false, 0, 0, 628-75, 86-75, 628+75, 86+75
          );

      except
        Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: Ollybest & J J
    // gets the rotated RS minimap and rotates to face north
    // needed for SPS to work at any compass angle
    function SPS_RotateMinimap: TMufasaBitmap;
    var
      W, H, t: Integer;
      mmBMP, rBMP: TMufasaBitmap;
      MiddleBMP: TPoint;
    begin
      try
        t := getSystemTime();

        //gathering minimap
        mmBMP := SPS_GatherMinimap;

        //rotating minimap
        rBMP := GetMufasaBitmap(RotateBitmap(mmBMP.index, 0-rs_GetCompassAngleRadians))

        //getting the middle of the rotated bitmap
        GetBitmapSize(rBMP.Index, W, H);
        MiddleBMP := Point(W/2, H/2);

        //creating the result by using a 74 radius around the centre
        Result := rbmp.Copy(MiddleBMP.X-74, MiddleBMP.Y-74, MiddleBMP.X+74, MiddleBMP.Y+74);

        mmBMP.free
        rbmp.free

        If SPS_Debug Then
          Writeln('Rotating map took '+toStr(getSystemTime - t)+' ms.');

      except
        Writeln('SPS_RotateMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: marpis & Coh3n
    // Gets the starting area coordinates depending on the area image
    procedure SPS_GetAreaCoords(Area: string; var x, y: integer);
    var
      p: integer;
    begin
      // if it's a specific dungeon map (i.e. name isn't 0_0, 10_2, etc.)
      if (length(getNumbers(Area)) < 2) then
      begin
        x := 0;
        y := 0;
        Exit;
      end;

      p := pos('_', Area);

      x := StrToIntDef(copy(Area, 1, p - 1), -1);
      y := StrToIntDef(copy(Area, p + 1, Length(Area) - p), -1);

      //writeln('SPS_GetAreaCoords: '+toStr(point(x, y)));
    end;

    // Author: marpis
    // Converts a point from a map piece to a point on the entire map
    function SPS_LocalToGlobal(Area: string; x, y: integer): TPoint;
    var
      cx, cy: integer;
    begin
      SPS_GetAreaCoords(Area, cx, cy);
      Result.x := (cx * 400) + x;
      Result.y := (cy * 400) + y;
    end;

    // Author: marpis
    // Converts a point from the entire map to a point on the main screen
    function SPS_GlobalToLocal(x, y: integer): TPoint;
    var
      cx, cy: integer;
    begin
      cx := Floor(x / 400);
      cy := Floor(y / 400);

      Result.x := x - (cx * 400);
      Result.y := y - (cy * 400);
    end;

    // Author: marpis
    // Returns the coordinates (x, y) in the form of a string
    function SPS_AreaCoordsToString(x, y: integer): string;
    begin
      Result := IntToStr(x)+'_'+IntToStr(y);
    end;

    // Author: Coh3n
    // Returns a TPA of the areas' values
    function SPS_TPAFromAreas(areas: TStringArray): TPointArray;
    var
      i: integer;
    begin
      setLength(result, length(areas));

      for i := 0 to high(areas) do
        SPS_GetAreaCoords(areas[i], result[i].x, result[i].y);
    end;

    // Author: Coh3n
    // Sorts the areas by columns, and sorts each column by rows
    // Example: ['1_5', '1_3', '0_5'] results ['0_5', '1_3', '1_5']
    function SPS_SortAreas(areas: TStringArray): TStringArray;
    var
      i, j: integer;
      tpa: TPointArray;
    begin
      setLength(tpa, length(areas));

      tpa := SPS_TPAFromAreas(areas);
      clearDoubleTPA(tpa);

      sortTPAByX(tpa, true); // first sort by column number

      // then sort the Y values for each column number
      for i := 0 to high(tpa) do
        for j := i to high(tpa) do
          if (tpa[i].x = tpa[j].x) then
            if (tpa[i].y > tpa[j].y) then
              tSwap(tpa[i], tpa[j]);

      setLength(result, length(tpa));

      for i := 0 to high(tpa) do
        result[i] := SPS_AreaCoordsToString(tpa[i].x, tpa[i].y);

      //writeln('SPS_SortAreas: '+toStr(result));
    end;

    // Author: Coh3n
    // Loads the "Area" image
    function SPS_GetArea(Area: string; surface: integer): TMufasaBitmap;
    var
      x, y: integer;
      S: string;
    begin
      SPS_GetAreaCoords(Area, x, y);

      case surface of
        RUNESCAPE_SURFACE: s := RUNESCAPE_SURFACE_FOLDER;
        RUNESCAPE_OTHER: s := RUNESCAPE_OTHER_FOLDER;
      end;

      try
          Result := TMufasaBitmap.Create;
            Result.LoadFromFile(SPS_IMG_PATH + s + Area + SPS_IMG_FMT);
      except
        Writeln('SPS_GetArea ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;
    end;

    // Author: Coh3n
    // Merges the SPS 'areas' into one bitmap (makes more more accurate GetMyPos)
    function SPS_MergeAreas(areas: TStringArray): TMufasaBitmap;
    var
      t, i, l, x, y, diffX, diffY, newWidth, newHeight: integer;
      startPoint: TPoint;
      newAreas: TStringArray;
      xVals, yVals: TIntegerArray;
      bmpTemp: TMufasaBitmap;
      tmpTPA: TPointArray;
    begin
      if (length(areas) <= 0) then
        exit;

      t := getSystemTime();

      // sort the areas from by columns/rows; remove duplicates
      newAreas := SPS_SortAreas(areas);
      l := length(newAreas);

      // if there's only one area in the array
      if (l = 1) then
      begin
        result := SPS_GetArea(areas[0], RUNESCAPE_SURFACE);
        exit;
      end;

      // get the x and y values for each area
      setLength(xVals, l);
      setLength(yVals, l);

      for i := 0 to high(newAreas) do
        SPS_GetAreaCoords(newAreas[i], xVals[i], yVals[i]);

      // get the lowest Y value so we can calculate the starting point to draw the first image
      tmpTPA := SPS_TPAFromAreas(newAreas);
      sortTPAByY(tmpTPA, true);

      try
        result := TMufasaBitmap.create();

        // calculate the starting point
        // x is always 0 because of how the areas are sorted
        // y is relative to the lowest y value in the areas
        SPS_GetAreaCoords(newAreas[0], x, y);
        startPoint.x := 0;
        startPoint.y := ((y - tmpTPA[0].y) * 400);

        // draw the first area to the starting point on the bitmap
        bmpTemp := SPS_GetArea(newAreas[0], RUNESCAPE_SURFACE);
        result.SetSize(bmpTemp.width, bmpTemp.height + startPoint.y);
        bmpTemp.fastDrawTransparent(startPoint.x, startPoint.y, result);
        bmpTemp.free();

        // loop through each area, drawing them to the result bitmap
        // coordinates are calculated relative to the first area drawn (areas[0])
        for i := 0 to (l - 2) do
        begin
          diffX := (xVals[i + 1] - xVals[0]);
          diffY := (yVals[i + 1] - yVals[0]);

          newWidth := 500 + (round(abs(diffX)) * 400);
          newHeight := 500 + (round(abs(diffY)) * 400);

          // only set the size if the width or height is increasing
          if (newWidth > result.width) then
            result.setSize(newWidth, result.height);

          if (newHeight > result.height) then
            result.setSize(result.width, newHeight);

          // copy the area image to the resulting bitmap
          bmpTemp := SPS_GetArea(newAreas[i + 1], RUNESCAPE_SURFACE);
          bmpTemp.fastDrawTransparent(startPoint.x + (diffX * 400 + 1),
                                      startPoint.y + (diffY * 400 + 1), result);
          bmpTemp.free();
        end;

        //result.saveToFile('C:/Simba/test.bmp');
      except
        Writeln('SPS_MergeAreas ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
      end;

      if (SPS_Debug) then
        writeln('SPS_MergeAreas: Merged areas in '+toStr(getSystemTime - t)+' ms.');
    end;

    // Author: Coh3n
    // Returns an SPS area of lowest x and y value. Used for calculating the
    // player's correct position
    function SPS_GetTopLeftCoords(areas: TStringArray): string;
    var
      tpa: TPointArray;
    begin
      tpa := SPS_TPAFromAreas(areas);

      if (length(tpa) <= 0) then
      begin
        result := '0_0';
        exit;
      end;

      sortTPAByX(tpa, true);
      result := toStr(tpa[0].x);

      sortTPAByY(tpa, true);
      result := result + '_'+toStr(tpa[0].y);

      //writeln('SPS_GetTopLeftCoords: '+result);
    end;

    // Author: marpis & SRL Community
    function SPS_GetMyPos(): TPoint;
    var
      Minimap: TMufasaBitmap;
      SmallMap: T3DIntegerArray;
      a, t, FoundMatches: integer;
      P: TPoint;
      Searches: extended;
    begin
      Result := Point(-1, -1);

      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;


      if (SPS_Tolerance < 1.0) then
        SPS_Tolerance := 600.0;

      if (SPS_MatchesPercent = 0.0) then
        SPS_MatchesPercent := 0.35;

      a := round(rs_GetCompassAngleDegrees);

      if (SPS_AnyAngle) and (inRange(a, 10, 350)) then
        Minimap := SPS_RotateMinimap()
      else begin
        if (inRange(a, 10, 350)) then
          if (SPS_ClickNorth) then
            ClickNorth(SRL_ANGLE_HIGH)
          else
            MakeCompass('N');

        Minimap := SPS_GatherMinimap();
      end;

      t := getSystemTime();
      SPS_FilterMinimap(Minimap);
      //DrawBitmapDebugImg(Minimap.Index);
      //DisplayDebugImgWindow(150, 150);

      {$IFDEF SIMBAMAJOR990}
      SetLength(SmallMap, 0); // Using this instead of SmallMap := [];
      SPS_BitmapToMap(Minimap, SPS_Accuracy, SmallMap);
      {$ELSE}
      SmallMap := [];
      SmallMap := SPS_BitmapToMap(Minimap, SPS_Accuracy);
      {$ENDIF}

      FoundMatches := SPS_FindMapInMap(P.x, P.y, SPS_AreaMaps, SmallMap, SPS_Tolerance);
      Searches := ((Minimap.Width / SPS_Accuracy) * (Minimap.Height / SPS_Accuracy));
    {
      writeln('fx: '+toStr(p.x)+' ~ on area: '+toStr(P.X * SPS_Accuracy + (Minimap.Width / 2)));
      writeln('fy: '+toStr(p.y)+' ~ on area: '+toStr(P.Y * SPS_Accuracy + (Minimap.Width / 2)));
      writeln('matches: '+toStr(foundMatches));
      writeln('searches: '+toStr(searches));
      writeln('percent: '+toStr(FoundMatches / Searches));
    }

      if ((FoundMatches / Searches) > SPS_MatchesPercent) then
        Result := SPS_LocalToGlobal(SPS_GetTopLeftCoords(SPS_Areas), // the top left of the total area
                                    P.x * SPS_Accuracy + (Minimap.Width / 2),
                                    P.y * SPS_Accuracy + (Minimap.Width / 2));

      Minimap.Free;

      t := (GetSystemTime - t);
      if (SPS_Debug) then
        Writeln('SPS_GetMyPos: Finished in '+ToStr(t)+' ms. Result = '+ToStr(Result));
    end;

    // Author: marpis
    // Finds position P in minimap by checking your own location
    function SPS_PosToMM(P: TPoint): TPoint;
    var
      MyPos: TPoint;
    begin

      Result := Point(-1, -1);
      MyPos := SPS_GetMyPos;

      if (Distance(MyPos.X, MyPos.Y, P.X, P.Y) < 75) then
        Result := RotatePoint(Point(964 + P.X - MyPos.X, 104 + P.Y - MyPos.Y), 0-RL_GetCompassAngleRadians, 964, 104);
    end;

    // Author: marpis
    // Walks to position, P.
    function SPS_WalkToPos(P: TPoint): boolean;
    var
      MM: TPoint;
    begin

      MM := SPS_PosToMM(P);

      if (MM.X > 0) then
      begin
        if (SPS_MultiMouse) then
          MultiMouse(MM.X, MM.Y, 25, 3, false)
        else
          Mouse(MM.X, MM.Y, 0, 0, mouse_Left);

        if WaitFunc(@IsMoving, 1, 3000 + random(500)) then
          while IsMoving do
            Flag;

        Result := True;
      end;
    end;

    // Author: marpis
    // Returns true if the point "Pt" is on the minimap
    function SPS_PosOnMM(Pt: TPoint): Boolean;
    var
      p: TPoint;
    begin
      p := SPS_PosToMM(Pt);
      Result := rs_OnMinimap(p.x, p.y);
    end;

    // Author: marpis & Coh3n
    // Walks the path "Path"; always walks to the furthest point possible
    function SPS_WalkPath(Path: TPointArray): boolean;
    var
      I, H, T, D, Fails: integer;
      P, MM, MMF: TPoint;
    begin
      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;

      H := High(Path);
      T := GetSystemTime + 20000 + Random(5000);
      Fails := 0;

      while (not Result) and (GetSystemTime < T) and (Fails < 5) do
      begin

        RunEnergy(20);
        P := SPS_GetMyPos();

        for I := H downto 0 do
        begin
          MM := RotatePoint(Point(964 + Path[I].X - P.X, 104 + Path[I].Y - P.Y),
                            0-RL_GetCompassAngleRadians, 964, 104);

          if MM = MMF then
            Inc(Fails);

          D := Distance(MM.X, MM.Y, MMCX, MMCY);

          if (D < 10) then
            break
          else
            if (D < 70) then
            begin
              if (SPS_MultiMouse) then
                MultiMouse(MM.X, MM.Y, 25, 3, false)
              else
                Mouse(MM.X, MM.Y, 5, 5, mouse_Left);

              MMF := MM;
              FFlag(5 + (Integer(I <> H) * 15));

              T := getSystemTime + 20000 + Random(1000);
                Break;
            end;
        end;

        Result := (I = H);
      end;
    end;

    // Walks blindly from the player's current position to the point T
    function SPS_BlindWalk(P: TPoint): Boolean;
    var
      Tries: Integer;
      M: TPoint;
      ctrlPoints: TPointArray;
    begin
      if (not SPS_IsSetup) then
      begin
        writeln('SPS ERROR: SPS_Setup was never called');
        exit;
      end;

      repeat

        M := SPS_GetMyPos();

        if (M.X = -1) then
          Continue;

        if (Length(ctrlPoints) = 0) then
          ctrlPoints := TPABetweenPoints(Point(M.X, M.Y), Point(P.X, P.Y), 20 + Random(15), 10);

        Inc(Tries);
        if (Tries > 20) then
          Exit;

        Result := SPS_WalkPath(ctrlPoints);
      until(Result);
    end;

    // Author: Coh3n
    // Sets up SPS; needs to be called if you want to switch RS surfaces
    function SPS_Setup(surface: integer; areas: TStringArray): boolean;
    var
      t: integer;
      tmp: TMufasaBitmap;
    begin
      t := getSystemTime;

      setLength(SPS_AreaMaps, 0);
      setLength(SPS_Areas, 0);

      SPS_MultiMouse := true;
      SPS_Accuracy := 4;

      if (length(areas) > 0) then
      begin
        if (surface = RUNESCAPE_SURFACE) then
          tmp := SPS_MergeAreas(areas) // combine the SPS areas into 1; makes for a more accurate read
        else
          if (surface = RUNESCAPE_OTHER) then
            if (length(areas) = 1) then
              tmp := SPS_GetArea(areas[0], surface)
            else begin
              writeln('SPS_Setup(): Invalid dungeon areas. You can only select one!');
              exit;
            end;

        SPS_IsSetup := true;
        result := true;

        {$IFDEF SIMBAMAJOR990}
        SPS_BitmapToMap(tmp, SPS_Accuracy, SPS_AreaMaps);
        {$ELSE}
        SPS_AreaMaps := SPS_BitmapToMap(tmp, SPS_Accuracy);
        {$ENDIF}

        if (surface = RUNESCAPE_SURFACE) then
          SPS_Areas := SPS_SortAreas(areas)
        else
          if (surface = RUNESCAPE_OTHER) then
            SPS_Areas := areas;

        tmp.free();

      end else
        writeln('SPS_Setup(): ERROR: SPS areas are not set!');

      t := (getSystemTime - t);

      if (SPS_Debug) and (result) then
        writeln('[SPS] SPS_Setup() took '+toStr(t)+' ms. Areas: '+toStr(SPS_Areas));
    end;

  19. #19
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    ...
    Can you show me the script your trying to run?

  20. #20
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    Can you show me the script your trying to run?
    This was just for testing the path, to see if it worked

    Simba Code:
    Program TestPath;
    {$i srl/srl.Simba}
    {$I RL_SPS.Simba}

    var

      testpath: tpointarray;


    begin
      testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
      SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
      SPS_WalkPath(testpath);
    end.

  21. #21
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Twinki View Post
    This was just for testing the path, to see if it worked

    Simba Code:
    Program TestPath;
    {$i srl/srl.Simba}
    {$I RL_SPS.Simba}

    var

      testpath: tpointarray;


    begin
      testpath := [Point(107, 114), Point(125, 112), Point(143, 109)];
      SPS_Setup(runescape_other, ['SPS_RageScapeBank']);
      SPS_WalkPath(testpath);
    end.
    Try

    Simba Code:
    SPS_MatchesPercent := 0.45;
      SPS_Tolerance := 500.000;

  22. #22
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    Try

    Simba Code:
    SPS_MatchesPercent := 0.45;
      SPS_Tolerance := 500.000;
    Nope

  23. #23
    Join Date
    May 2011
    Posts
    24
    Mentioned
    0 Post(s)
    Quoted
    3 Post(s)

    Default

    FilterTPAsbetween unknown identifier. I feel so clueless... tried to google filterin them but no luck

    Simba Code:
    function rsps_uptext:string;
    var
      TPA: tpointarray;
      ATPA: t2dpointarray;
    begin
      FindColorsTolerance(TPA, 13883407, 43, 14, 69, 23, 7);
      if (length(TPA) > 1) then
      begin
        ATPA := splitTPAEx(TPA, 1, 10);
        FilterTPAsbetween(ATPA, 1, 10);
        sortATPAFromFirstPointX(ATPA, point(0, 0));
        result:= StrToInt(getTextATPA(ATPA, 5, 'UpChars07'));
      end;
    end;
    Ah I guess I don't have the version with that function. trying it with this
    https://github.com/MerlijnWajer/Simba
    Last edited by I am new; 09-26-2013 at 11:15 PM.

  24. #24
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by I am new View Post
    FilterTPAsbetween unknown identifier. I feel so clueless... tried to google filterin them but no luck

    Simba Code:
    function rsps_uptext:string;
    var
      TPA: tpointarray;
      ATPA: t2dpointarray;
    begin
      FindColorsTolerance(TPA, 13883407, 43, 14, 69, 23, 7);
      if (length(TPA) > 1) then
      begin
        ATPA := splitTPAEx(TPA, 1, 10);
        FilterTPAsbetween(ATPA, 1, 10);
        sortATPAFromFirstPointX(ATPA, point(0, 0));
        result:= StrToInt(getTextATPA(ATPA, 5, 'UpChars07'));
      end;
    end;
    Ah I guess I don't have the version with that function. trying it with this
    https://github.com/MerlijnWajer/Simba
    woops remove that part

  25. #25
    Join Date
    Dec 2011
    Posts
    445
    Mentioned
    26 Post(s)
    Quoted
    256 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    Try

    Simba Code:
    SPS_MatchesPercent := 0.45;
      SPS_Tolerance := 500.000;
    Didn't fix it...
    Wow nothing seems to work... Tried SPS_RotateMinimap and it doesn't work either

Page 1 of 2 12 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
  •