Results 1 to 22 of 22

Thread: RatKiller: A Making of

  1. #1
    Join Date
    Aug 2008
    Location
    London, UK
    Posts
    456
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default RatKiller: A Making of

    RatKiller: A Making of


    Over the years that I have been a part of this community, I have learned a great deal from the tutorial section. In fact, I owe this community a lot. I recently made the decision to quit my degree that I have been studying for 2 years and reapply for Computer Science. This community gave me the chance to hone my skills, and gave me confidence that I am suitable for such a course.

    I am going to be making a tutorial as a proof of concept of my recently released MMToMS, to show it’s usefulness, but hopefully showing you a few hints and tips along the way.

    This was originally intended to be a step by step tutorial, but I got carried away with the script. I personally feel it’s the details which make a script, so I’d like to explain my way of thinking in this ‘Making of’.

    I’ve purposely decided to leave things that are generic out in order to focus on the more exciting parts.

    OK, let’s jump in.

    Simba Code:
    type
      MSObject = record
        Col, Tol, TPADist, MinCount: Integer;
        Hue, Sat: Extended;
        Uptext: TStringArray;
        MMDot: String;
      end;

    var
      Rat, Bones: MSObject;
      BonesDTM: Integer;

    I like to define my variables before anything else. It sets the tone for the rest of the code, means less rewriting later, and it also helps to avoid repeating yourself.

    As I had decided that I was going to make a Rat Fighting script that picks up and buries bones, a suitable way to define this data was immediately clear. All the script needs is two Main Screen objects, I knew I was going to use a typical TPA Objectfinding method with some added features. So I created a ‘MSObject’ record with common variables between the two objects and defined global variables ‘Rat’ and ‘Bones’ to have this Type.

    I also needed a way to find Bones once they were in the inventory in order to bury them. I chose to use a DTM, since there was only one, but in a larger script would probably look into BlackLists.

    I will explain ‘MSObject.MMDot’ further on, but take note that it’s defined here as it’s important.

    Simba Code:
    procedure LoadObjects;
    begin
      with Rat do
      begin
        Col := 4408390;
        Tol := 10;
        TPADist := 10;
        Hue := 1.39;
        Sat := 0.16;
        UpText := ['ack Gian'];
        MMDot := 'yellow';
        MinCount := 50;
      end;

      with Bones do
      begin
        Col := 12501714;
        Tol := 19;
        TPADist := 5;
        Hue := 0.23;
        Sat := 0.96;
        UpText := ['ones'];
        MMDot := 'red';
        MinCount := 40;
      end;

      BonesDTM := DTMFromString('mrAAAAHic42BgYGhlYmBoBuJaIG5kgvD7gbgOyp/EyMAwC4hnAPE0IO4B4qlQuhOIp/T2Ak1hwon/A0l+PJiRAIYBAMm8C/Y=');
    end;

    This procedure just declares the values of our variables. I used AutoColorAid to calculate appropriate CTS Speed Modifiers.

    Now is probably a good time to give an overview of the method I used to find my objects. I will go into further detail after each block of code.

    ‘MMtoMSTile()’ is found in my include (3DProjection.simba) which is attached at the end of this tutorial. It calculates in 3D the Main Screen tile co-ordinates based on the compass angle. You can input a Mini Map co-ordinate and it will out put the co-ordinate of the tile in the Main Screen.

    Another useful function, which is included in the include, is ‘GetMMDotsOnMS2’. This returns a TPointArray of all the tile co-ordinates of a specified Mini Map dot type, i.e. NPC = yellow, Ground Item = red.

    We will use the information from these dots to significantly increase the accuracy and efficiency of our Object Finding. The real power of this is that you can use tiny minimum count checks, because by using the minimap, you know the object is there. This means that even if an object is covered by a tree, it will generally find it.

    Simba Code:
    function FindMSObjects(var Coords: TPointArray; Obj: MSObject): Boolean;
    var
      cts, Len, i, c: Integer;
      TPA: TPointArray;
      ATPA: TPointArrayArray;
    begin
      cts := GetColorToleranceSpeed;
      ColorToleranceSpeed(2);
      SetColorSpeed2Modifiers(Obj.Hue, Obj.Sat);

      Result := False;

      c:= 0;
      if FindColorsTolerance(TPA, Obj.Col, MSX1, MSY1, MSX2, MSY2, Obj.Tol) then
      begin
        Result := True;
        ATPA := SplitTPA(TPA, Obj.TPADist);
        Len := Length(ATPA);
        SetLength(Coords, Len);
        for i := 0 to Len-1 do
        begin
          if Length(ATPA[i]) > Obj.MinCount then
          begin
            //SMART_DrawBoxEx(False, GetTPABounds(ATPA[i]), clAqua);
            Coords[c] := MiddleTPA(ATPA[i]);
            Inc(c);
          end;
        end;
      end;
      SetLength(Coords, c)
      ColorToleranceSpeed(cts);
      SetColorSpeed2Modifiers(0.2, 0.2);
    end;

    The above is pretty traditional TPA Object finding, it it returning a TPointArray with all the occurrences of an object. It uses the information provided by ACA earlier to do this.

    Simba Code:
    function FindMSObjectsByDot(var Coords: TPointArray; Obj: MSObject): Boolean;
    var
      BoxArr: TBoxArray;
      Len, Len2, i, j, c: Integer;
      TPA, TPA2: TPointArray;
    begin
      TPA := GetMMDotsOnMS2(Obj.MMDot, False);
      Len := Length(TPA);
      SetLength(BoxArr, Len);

      for i := 0 to Len-1 do
        BoxArr[i] := MakeBox(TPA[i].x-70, TPA[i].y-70, TPA[i].x+70, TPA[i].y+70);

      if FindMSObjects(TPA2, Obj) then
      begin

        Len2 := Length(TPA2);
        SetLength(Coords, Len2);

        c := 0;
        for i := 0 to Len2-1 do
          for j := 0 to Len-1 do
            if PointInBox(TPA2[i], BoxArr[j]) then
            begin
              Coords[c] := TPA2[i];
              Inc(c);

              Break;
            end;
        SetLength(Coords, c);
        Result := (c > 0);
      end;

    end;

    This is where it differs slightly, it is checking if the colour aproximated Object Points coincide with the 3D projected from Mini Map Co-ords. It does this by creating a box around each projected point and checking if any of the colour points are inside it.



    Simba Code:
    function InBadBox(p: TPoint): Boolean;
    var
      i, Len: Integer;
      badboxarray: TBoxArray;
    begin
      Result := False;
      BadBoxArray := FindAllHPBars(MSCX, MSCY, MSX1, MSY1, MSX2, MSY2);

      Len := Length(badboxarray);
      for i := 0 to Len-1 do
        if PointInBox(p, MakeBox(BadBoxArray[i].X1, BadBoxArray[i].Y1, BadBoxArray[i].X2, BadBoxArray[i].Y2+60)) then
        begin
          Result := True;
          Break;
        end;
    end;
           
    function InRatFight: Boolean;
    var
      aps: Integer;
    begin
      aps := AveragePixelShift(MakeBox(MSCX-10, MSCY-25, MSCX+15, MSCY+15), 50, 2000);
      Result := (aps > 100);
    end;

    function KillRat: Boolean;
    var
      TPA: TPointArray;
      i, Len, x, y, a, b: Integer;
    begin
      Result := False;
      if FindMSObjectsByDot(TPA, Rat) then
      begin
        Len := Length(TPA);
        SortTPAFrom(TPA, Point(MMCX, MMCY));
        for i := 0 to Len-1 do
        begin
          if inBadBox(TPA[i]) then
            Continue;
          MMouse(TPA[i].x, TPA[i].y, 3, 3);
          if WaitUpTextMulti(Rat.UpText, 300) then
          begin
            GetMousePos(x, y);
            Mouse(x, y, 0, 0, True);
            if FindColorTolerance(a, b, 65278 {YellowWalkingCross}, x, y, x+1, y+1, 5) then
            begin
              WriteLn('MISSED');
              Exit;
            end;
            if GetColor(x, y) = 65278 then
            FFlag(2);
            Wait(500);
            repeat
              Antiban;
            until (not InRatFight) or (not srl_InFight)
            Result := True;
            Break;
          end;
        end;
      end;

    end;

    There are a few details here that aren’t generally talked about in the tutorials I have seen.

    ‘KillRat’ is a procedure in which we need to use our previously made object finding routine, move the mouse to the object and test for the desired uptext. If this test is positive then we click to attack the rat. We then can perform various antiban routines whilst in the fight.

    I realised that the Object Finder would sometimes find a rat that was already in combat, so I created the function InBadBox, which checks if the point is in a ‘Bad box’ which are generated from any HP bars that are on the screen.

    I noticed that sometimes, due to the rats moving around pretty rapidly, it would miss. This isn’t much as of a problem, personally when I’m playing legit I sometimes miss too. What is a problem, is that it continues to wait until the player has stopped moving and enters the InFight loop. This look really unatural so I thought about how I could tell immediately whether it had missed the rat or not and avoid this unnecessary delay.

    What I ended up doing was a simple check on the mouse co-ordinates for the cross that your cursor makes when clicking somewhere. If you click the object it is red, if you don’t it is yellow. Simple but effective. If the color is yellow, it Exits the procedure and the main loop immediately causes it to look for the next rat.



    Another cool thing I used which I haven’t taken advantage of before is SRL’s animation procedures. It was incredibly easy to set up. I just made it do a few WriteLn’s telling me what the average pixel shift was while it was in a fight, and while it was not, giving me the information I needed to do a reliable check. I also used SRL’s ‘srl_InFight’ as a back up, which checks for the players health bar. This would handle anytime I was under a tree.


    Simba Code:
    procedure PickUpBones;
    var
      TPA: TPointArray;
      i, Len, x, y, c: Integer;
    begin
      for c := 0 to Random(5) + 1 do
        if FindMSObjectsByDot(TPA, Bones) then
        begin
          Len := Length(TPA);
          SortTPAFrom(TPA, Point(MMCX, MMCY));
          for i := 0 to Len-1 do
          begin
            MMouse(TPA[i].x, TPA[i].y, 3, 3);
            if WaitUpTextMulti(['Take'], 100) then
            begin
              GetMousePos(x, y);
              Mouse(x, y, 0, 0, False);
              if WaitOptionMulti(Bones.UpText, 300) then
              begin
                FFlag(2);
                Wait(500);
                if i = Len-1 then
                  Exit;
                Break;
              end;
            end;
          end;
        end;

    end;

    This works very similarly to KillRat, taking advantage of the minimap dots.


    Simba Code:
    function WeightedChoice(Weights: TIntegerArray): Integer;
    var
      i, Len, t, r: Integer;
      Totals: TIntegerArray;
    begin
      Len := Length(Weights);
      SetLength(Totals, Len);

      t := 0

      for i := 0 to Len-1 do
      begin
        IncEx(t, Weights[i]);
        Totals[i] := t;
      end;

      r := Random(t);
      for i := 0 to Len-1 do
        if r < Totals[i] then
        begin
          Result := i;
          Break;
        end;
    end;

    procedure MainLoop;
    begin
      repeat
        if KillRat then
        begin
          SMART_ClearCanvas;
          if InvFull then
            ClickAllItems('dtm', BonesDTM, '', 400+ random(200), []);
          if WeightedChoice([3, 7]) = 0 then
            PickUpBones;

        end;
        SMART_ClearCanvas;
      until(not LoggedIn)
    end;

    Very standard main loop here. One thing I like is the use of ‘WeightedChoice’. It gives you complete control over the probability that something will happen. It’s use would probably be shown better in an anti ban routine. In this script I wanted to mimic myself, I don’t pick up bones after every kill. I tend to pick up quite randomly, but I still prefer the actual killing

    Simba Code:
    begin
      MouseSpeed := 15;
      Smart_Server := 1;
      Smart_Members := False;
      Smart_Signed := True;
      Smart_SuperDetail := False;
      SetupSRL;
      SMART_ClearCanvas;
      LoadObjects;
      MainLoop;
    end.

    Last thing, MouseSpeed is something that you should think about. It completely depends on the task at hand and you should try to thing about what it would be if you were playing legit. For this script I chose a fast MouseSpeed because my targets are mobile.

    I have attached the complete script and include to this post. Try it if you like, it is very fast and fun to watch. I may add Multiplayer and AntiBan at some point to release. I haven't decided yet.

    And that is it, I hope you enjoyed reading this and you found something that might be useful. Please check out my MMtoMSTile functions as well!

    The End.
    Attached Files Attached Files
    Last edited by ReadySteadyGo; 01-31-2012 at 07:19 AM.

  2. #2
    Join Date
    Oct 2008
    Location
    C:\Simba\Includes\
    Posts
    7,566
    Mentioned
    19 Post(s)
    Quoted
    180 Post(s)

    Default

    Very nice tutorial man! Love the MMtoMS tile!
    Away for awhile, life is keeping me busy. | Want to get my attention in a thread? @Kyle Undefined; me.
    { MSI Phoenix || SRL Stats Sigs || Paste || Scripts || Quotes || Graphics }

    When posting a bug, please post debug! Help us, help you!

    I would love to change the world, but they won't give me the source code. || To be the best, you've got to beat the rest. || Logic never changes, just the syntax.
    If you PM me with a stupid question or one listed in FAQ, or about a script that is not mine, I will NOT respond.


    SRL is a Library of routines made by the SRL community written for the Program Simba. We produce Scripts for the game Runescape.


  3. #3
    Join Date
    Aug 2008
    Location
    London, UK
    Posts
    456
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    Thank you Kyle! I was getting worried that my explanations might be badly written

  4. #4
    Join Date
    Oct 2008
    Location
    C:\Simba\Includes\
    Posts
    7,566
    Mentioned
    19 Post(s)
    Quoted
    180 Post(s)

    Default

    Ha, it's simple really Don't have a use for it now, but maybe one day I'll use it
    Away for awhile, life is keeping me busy. | Want to get my attention in a thread? @Kyle Undefined; me.
    { MSI Phoenix || SRL Stats Sigs || Paste || Scripts || Quotes || Graphics }

    When posting a bug, please post debug! Help us, help you!

    I would love to change the world, but they won't give me the source code. || To be the best, you've got to beat the rest. || Logic never changes, just the syntax.
    If you PM me with a stupid question or one listed in FAQ, or about a script that is not mine, I will NOT respond.


    SRL is a Library of routines made by the SRL community written for the Program Simba. We produce Scripts for the game Runescape.


  5. #5
    Join Date
    Nov 2011
    Location
    Jozi, South Africa
    Posts
    249
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Smile

    Thank you for your time and effort. I really enjoyed working through your tutorial, and matching your explanations to the code.

    I think you have a great idea here with "The Making Of" series. I am pretty sure that others will pick up on this as well. Well done!
    Ciao
    NM

  6. #6
    Join Date
    Aug 2008
    Location
    London, UK
    Posts
    456
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    Thank you NickMystre and you're very welcome! I hope other people do similar tutorials as well. It's good fun reading peoples methods and ideas.

  7. #7
    Join Date
    Dec 2008
    Posts
    160
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Wow I really like this tutorial you explain things very well and I like your style to it seems a smidge different than the other tutorials ha
    My Soul Wars Scipt Proggress:[100%....]
    Probably won't release though I like it for myself

  8. #8
    Join Date
    May 2007
    Location
    Some where fun.
    Posts
    2,891
    Mentioned
    1 Post(s)
    Quoted
    5 Post(s)

    Default

    Awesome tutorial man!

  9. #9
    Join Date
    Aug 2008
    Location
    London, UK
    Posts
    456
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    Glad people are enjoying it

  10. #10
    Join Date
    Mar 2012
    Location
    Canada
    Posts
    870
    Mentioned
    1 Post(s)
    Quoted
    5 Post(s)

    Default

    This is awesome, I need to try this in one of my next script.
    My scripts:
    Advanced Barb Agility Course(outdated), MonkeyThieverV0.11, MahoganyTableV0.4(outdated)
    Questions? I bet that for 98% of those, you'll find answer HERE

  11. #11
    Join Date
    Nov 2010
    Posts
    86
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    You mind if I use the MMtoMS and related functions in my script(Credits stated)? Really nice idea. The post was very well structured and just as informative. Nice one

    Luke

  12. #12
    Join Date
    Nov 2011
    Location
    England
    Posts
    3,072
    Mentioned
    296 Post(s)
    Quoted
    1094 Post(s)

    Default

    MMtoMS looks sweet Great tutorial.

  13. #13
    Join Date
    Aug 2008
    Location
    London, UK
    Posts
    456
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    Quote Originally Posted by Zota View Post
    You mind if I use the MMtoMS and related functions in my script(Credits stated)? Really nice idea. The post was very well structured and just as informative. Nice one

    Luke
    Yes absolutely, please go ahead, I would like to see this used by people.

    Glad people are enjoying this tutorial.

  14. #14
    Join Date
    Nov 2010
    Posts
    86
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    hey man.

    I had problems with my script. Mainly with it kept trying to attack other peoples monster and for example - It'd kill a monster, and try find drop. But a lot of the time it'd find bones/gold/whatever that wasn't from your monster. So rather than waiting for the drop where the monster died, it'd look at a previous drop pile.

    Not sure how to fix that.. I really need to look into how to use Tpoints/array properly.


    Luke

  15. #15
    Join Date
    Oct 2011
    Posts
    434
    Mentioned
    0 Post(s)
    Quoted
    8 Post(s)

    Default

    This is a very useful tutorial. At the moment I'm learning scripting and this tutorial is really profitable for me as I can see the code and what it does and also get ideas for scripts.

    Thank you so much it's really helpful
    Last edited by alexes; 03-29-2012 at 04:54 PM.

  16. #16
    Join Date
    Aug 2008
    Location
    London, UK
    Posts
    456
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    Quote Originally Posted by Zota View Post
    hey man.

    I had problems with my script. Mainly with it kept trying to attack other peoples monster and for example - It'd kill a monster, and try find drop. But a lot of the time it'd find bones/gold/whatever that wasn't from your monster. So rather than waiting for the drop where the monster died, it'd look at a previous drop pile.

    Not sure how to fix that.. I really need to look into how to use Tpoints/array properly.


    Luke
    Hi Luke, I'm not really sure if you're asking a question. Can you ask me what you'd like to know exactly? This tutorial actually deals with the problem of attacking other peoples monsters.


    Quote Originally Posted by alexes View Post
    This is a very useful tutorial. At the moment I'm learning scripting and this tutorial is really profitable for me as I can see the code and what it does and also get ideas for scripts.

    Thank you so much it's really helpful
    You're very welcome alexes.

  17. #17
    Join Date
    Jan 2012
    Posts
    319
    Mentioned
    0 Post(s)
    Quoted
    2 Post(s)

    Default

    This is an awesome function to work with. I made a ghoul killer with it. Do you mind if I release it?
    -My Scripts-
    Dude'sFighters
    Dude'sBonfires
    Donations help with scripting Paypal!

  18. #18
    Join Date
    Aug 2008
    Location
    London, UK
    Posts
    456
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    Quote Originally Posted by dude1994 View Post
    This is an awesome function to work with. I made a ghoul killer with it. Do you mind if I release it?
    Of course not, please do!

  19. #19
    Join Date
    Jun 2007
    Posts
    117
    Mentioned
    0 Post(s)
    Quoted
    16 Post(s)

    Default

    Wow this is a great tutorial! Well done, I learned a few things that i may use in the future thanks! I never knew about the yellow and red walking crosses those will definitely become useful!

    Ps: Good Luck with your studies

  20. #20
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

  21. #21
    Join Date
    Nov 2011
    Location
    England
    Posts
    3,072
    Mentioned
    296 Post(s)
    Quoted
    1094 Post(s)

    Default



    Hmm

  22. #22
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

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
  •