Results 1 to 8 of 8

Thread: [OSR][AeroLib][OSBuddy] Item Overlay Location Finder/Looter

  1. #1
    Join Date
    Dec 2011
    Posts
    193
    Mentioned
    5 Post(s)
    Quoted
    51 Post(s)

    Default [OSR][AeroLib][OSBuddy] Item Overlay Location Finder/Looter

    Description:
    OSBuddy, a popular client for OSRS, has a feature which will paint ground items onto the screen in the form of a text overlay. This function will search for any overlay text matching the specified text. If found it'll return the on-screen coordinates of the item (not the text) for easy looting.

    Features:
    • Finds and returns specified item location
    • Will return the correct location of the item even if it's in a stack of items, no matter it's location in the stack:

      (searching for any of these items texts would return the coordinates for the item pile below them).


    Useful For:
    • Adding item finding & looting to a non-reflection script.
    • Those who don't want to use SMART
    • Those who want to take advantage of reflection in the safest form possible.


    Requirements:
    • AeroLib
    • OSBuddy
    • OSBuddy Item Overlay feature set to 'on' AND go into the feature settings and change font to 'Runescape'


    Limitations:
    • Will not be able to match text that is overlayed with other text. For example when a large amount of items are spread across a small space the text will often overlap.
    • Will not be able to correctly get the X coordinate if another item text is within a couple pixels to the right of your item on the same X plane.
    • Will not be able to correctly get the Y coordinate if another item text is within a few pixels below your item on the Y plane. It will think your item is in a stack and return the non-existent stacks location (See below for fix. Params: Stack)





    Code:
    Simba Code:
    function GetDropCoordX(Color: Integer; StartPoint: TPoint): TPoint;
    var
      MPs: TPointArray;
      MP: TPoint;
      tCol: TColEx;
      SB: TBox;
      Found: Boolean;
    begin
      SB := ToBox(StartPoint.x, StartPoint.y-1, StartPoint.x+6, StartPoint.y+7);
      tCol.create(Color, 0);
      Found := tCol.FindIn(SB, MP);

      while Found do
      begin
        tCol.FindAllIn(SB, MPs);
        SB.X1 := SB.X2;
        SB.X2 := SB.X2+6;
        Found := tCol.FindIn(SB, MP);
      end;

      SortTPAByX(MPs, False);
      MP := Point(MPs[0].x, MPs[0].y);
      MP.x := StartPoint.x+(5+((MP.x-StartPoint.x) shr 1));

      Result := MP;
    end;

    function GetDropCoordY(Color: Integer; StartPoint: TPoint): TPoint;
    var
      MPs: TPointArray;
      MP: TPoint;
      tCol: TColEx;
      SB: TBox;
      Found: Boolean;
    begin
      SB := ToBox(StartPoint.x-4, StartPoint.y-1, StartPoint.x+4, StartPoint.y);
      tCol.create(Color, 0);
      Found := tCol.FindIn(SB, MP);

      while Found do
      begin
        tCol.FindAllIn(SB, MPs);
        SB.Y1 := SB.Y2;
        SB.Y2 := SB.Y2+11;
        Found := tCol.FindIn(SB, MP);
      end;

      SortTPAByY(MPs, False);
      MP := Point(StartPoint.x, MPs[0].y+20);

      Result := MP;
    end;

    function OSB_FindItem(var ItemPoint: TPoint; ItemText: String; Area: TBox; Stack: Boolean): Boolean;
    var
      TextTPA, SearchTPA, Matches: TPointArray;
      Height: Integer;
      tCol: TColEx;
    begin
      tCol.autoCreate([16777215,16448764,16316664]);
      if not tCol.findAllIn(Area, SearchTPA) then
        Exit(False);

      TextTPA := loadTextTPA(ItemText, 'SmallChars07', Height);
      Result := FindTextTPAinTPA(Height, TextTPA, SearchTPA, Matches);

      if not Result then
        Exit;

      ItemPoint := GetDropCoordX(16777215, Matches[0]);
      case Stack of
        True : ItemPoint := GetDropCoordY(16777215, ItemPoint);
        False: ItemPoint.y += 23;
      end;
    end;

    Params:
    • ItemPoint: Function will fill this referenced variable with the TPoint of the item.
    • ItemText: Text matching the item you want to find on screen. You do not need to provide the full item name for a match, but you will need to provide the start of it. For example to find a cabbage, "Cab" will work but "bage" will not. Be wary as any items with the same chars will match. CASE SENSITIVE
    • Area: TBox of the area you want to look for the item in.
    • Stack: Tells the function if it should look to see if the item is in a stack of items. Leave this to True to start with as it's most accurate and will match perfectly fine even if the item is by itself. Set to False if the item wasn't in the location specified when Stack = True.


    Example usage:
    Like most finder functions, this function only returns the TPoint it believes the item you specified is at. It's up to the scripter to make the correct fail safes with that information to ensure smooth looting.

    A basic example with a fail safe covering the Stack paramater mentioned above:
    Simba Code:
    var
      ItemLoc: TPoint;

    begin
      InitAL;

      if OSB_FindItem(ItemLoc, 'Cabbage', AREA_MS, True) then
      begin
        accurateMMouse(ItemLoc, 0,0);
        if waitUptext('Cabbage',600) then
          FastClick(Mouse_Left)
        else
          if OSB_FindItem(ItemLoc, 'Cabbage', AREA_MS, False) then
          begin
            accurateMMouse(ItemLoc, 0,0);
            if waitUptext('Cabbage',600) then
              FastClick(Mouse_Left);
          end;
      end;
    end.

    I don't imagine this will be used by too many as I believe the number of people who match the 'useful for' section isn't that high, but it's here if anyone needs it. There's a few improvements I can make if some Simba-side issues can be resolved, if they can't I'll eventually get round to rewriting the heavy lifting function that makes the above code work.

  2. #2
    Join Date
    Dec 2011
    Posts
    193
    Mentioned
    5 Post(s)
    Quoted
    51 Post(s)

    Default

    Need help from those in the know

    Today while writing this I've had a crash course in text and the multiple ways in which Simba handles it. There were a few versions of the code above using varying methods but this was the simplest, most reliable and most importantly low on the CPU usage (considering how often a function to check for loot will be called).

    The function of choice was FindTextTPAinTPA. Now it appears this function is supposed to return a TPA of every matched point between SearchTPA and TotalTPA in the Matches param but it only matches the first index of the SearchTPA. Another very similar function FindTPAinTPA also has this same issue. The first point is enough to have the script work, but an entire match will improve accuracy to near 100% so long as the text is readable.

    I've pulled the function from source and played around with it a bit but I'm getting the same issue. It seems to perform a very odd way of matching, inverting the TPA (not the same points in reversed order, instead every point except the ones in the original TPA) and looking for non-matches as a way of matching. Although weird (I'm sure there's a reason I'm not currently foreseeing that explains it) the code looks like it should do as the params suggest and return an entire TPA of matched points.

    Any help with that is appreciated.

    Also a small issue with FindTPAinTPA: The function preview in Simba states that both SearchTPA AND TotalTPA will be passed as const, but after having my local SearchTPA augmented after passing to the function I looked at the source and only TotalTPA is const, SearchTPA while not passed by ref is changed within the function and those changes carry over back to the script.

    The following code highlights both issues mentioned:
    Simba Code:
    var
      FirstTPA, SecondTPA, ThirdTPA: TPointArray;
    begin

      FirstTPA := [ Point(10,10), Point(10,11), Point(10,12), Point(11,12), Point(12,12) ];
      SecondTPA := [ Point(11,11), Point(11,12), Point(11,13), Point(12,13), Point(13,13)];


      Writeln('First: ', FirstTPA);
      Writeln('Secon: ', SecondTPA);

      FindTPAinTPA(FirstTPA, SecondTPA, ThirdTPA);

      Writeln('First: ', FirstTPA);
      Writeln('Secon: ', SecondTPA);
      Writeln('Third: ', ThirdTPA);
    end.

    Code:
    First: [{X = 10, Y = 10}, {X = 10, Y = 11}, {X = 10, Y = 12}, {X = 11, Y = 12}, {X = 12, Y = 12}]
    Secon: [{X = 11, Y = 11}, {X = 11, Y = 12}, {X = 11, Y = 13}, {X = 12, Y = 13}, {X = 13, Y = 13}]
    First: [{X = 0, Y = 0}, {X = 0, Y = 1}, {X = 0, Y = 2}, {X = 1, Y = 2}, {X = 2, Y = 2}]
    Secon: [{X = 11, Y = 11}, {X = 11, Y = 12}, {X = 11, Y = 13}, {X = 12, Y = 13}, {X = 13, Y = 13}]
    Third: [{X = 11, Y = 11}]
    As you can see, FirstTPA has now been changed. ThirdTPA which should contain all points from SecondTPA as they all match with FirstTPA, only holds the first matched index.

    I know double posting is frowned upon but I didn't want this clogging up the bottom of the OP and being skipped over.

  3. #3
    Join Date
    Aug 2007
    Location
    Colorado
    Posts
    7,251
    Mentioned
    256 Post(s)
    Quoted
    1348 Post(s)

    Default

    Looks great Borland, very helpful indeed for those using OSSbuddy.

    Now about your TPA issue: after running a few trials myself I came to the conclusion that within the function FindTPAinTPA the two TPAs you feed it will be rearranged in order to find matches. I'm surprised the function itself doesn't right away copy the two TPAs before it begins matching TPoints to be honest. However it doesn't, so to prevent this we simply feed a copy of the two TPAs to the function so our two original remain constant. Try this instead:
    Simba Code:
    var
      FirstTPA, SecondTPA, ThirdTPA: TPointArray;
    begin

      FirstTPA := [ Point(10,10), Point(10,11), Point(10,12), Point(11,12), Point(12,12) ];
      SecondTPA := [ Point(11,11), Point(11,12), Point(11,13), Point(12,13), Point(13,13)];

      FindTPAinTPA(copyTPA(FirstTPA), copyTPA(SecondTPA), ThirdTPA);

      Writeln('First: ', FirstTPA);
      Writeln('Secon: ', SecondTPA);
      Writeln('Third: ', ThirdTPA);
    end.

    On a side note, what helped me a lot with OCR-based routines through TPA-to-Text was studying how SRL read right-click menus to extract options/text. Take a look at the function getOptions in Menu.simba (AeroLib) to see how it's done. It may give you some pointers if you're still having issues somewhere else.

    Current project:
    [AeroLib 2.1 / Scripts / R&D]


    Did you know?
    J1407b, dubbed "Saturn on steriods", has a ring system 200 times larger than Saturn's own rings.

  4. #4
    Join Date
    Jan 2012
    Location
    Sydney, Australia
    Posts
    688
    Mentioned
    11 Post(s)
    Quoted
    278 Post(s)

    Default

    Great contribution mate.

    Have considered using OSBuddy's features in my scripts but never got around to it.

    Should make an include for OSbuddy.simba for Aerolib

  5. #5
    Join Date
    Oct 2012
    Posts
    1,197
    Mentioned
    37 Post(s)
    Quoted
    567 Post(s)

    Default

    Quote Originally Posted by Dan the man View Post
    Great contribution mate.

    Have considered using OSBuddy's features in my scripts but never got around to it.

    Should make an include for OSbuddy.simba for Aerolib
    It would likely make color-only agility a lot more feasible.

  6. #6
    Join Date
    Dec 2011
    Posts
    193
    Mentioned
    5 Post(s)
    Quoted
    51 Post(s)

    Default

    Quote Originally Posted by Flight View Post
    Looks great Borland, very helpful indeed for those using OSSbuddy.

    On a side note, what helped me a lot with OCR-based routines through TPA-to-Text was studying how SRL read right-click menus to extract options/text. Take a look at the function getOptions in Menu.simba (AeroLib) to see how it's done. It may give you some pointers if you're still having issues somewhere else.
    Lol that's exactly where I looked I have a version of the function using the same brains as getOptions. It works a lot better when static but as soon as movement is involved (even NPCs and players moving while camera is still) large artifacting of characters occurred. It's perfect for getOptions as once the menu is open it's position is static and has the highest Index priority. BUT saying that, I was thinking about how to improve accuracy while at work today and one of the potential solutions is making use of Freeze to see if that can reduce the artifacts without doing regex or other hard coded replacing.





    Quote Originally Posted by Dan the man View Post
    Great contribution mate.

    Have considered using OSBuddy's features in my scripts but never got around to it.

    Should make an include for OSbuddy.simba for Aerolib
    Quote Originally Posted by acow View Post
    It would likely make color-only agility a lot more feasible.
    Been thinking about doing agility like that. It was how I originally made my Salamander script but the paint overlay OSBuddy uses isn't always accurate and will sometimes be off the trap entirely, especially if the traps orientation is opposite others in the area. Switched to good old fashioned color techniques and I'm fairly proud of how accurate that script turned out. Also I believe the agility plugin is a pro feature? Not sure I'd want a requirement of my script to be locked behind a pay wall.

    I haven't used/checked any other clients out there but I know a couple of them also have the agility overlay on them, from pictures I've seen here and there it looks as though they are painted to exact bounds.

    I still hold hope that if there isn't one available, I'll be able to do an all-color agility script when it comes time for 99. Lord knows I aint doing that by hand lmao.

  7. #7
    Join Date
    Jan 2012
    Location
    Sydney, Australia
    Posts
    688
    Mentioned
    11 Post(s)
    Quoted
    278 Post(s)

  8. #8
    Join Date
    Feb 2017
    Location
    Sauce
    Posts
    30
    Mentioned
    0 Post(s)
    Quoted
    4 Post(s)

    Default

    Agility is so terrible to train. Super repetitive with constant clicking.

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
  •