1. ## Mousing Moving Objects

I've been experimenting around with the mousing procedure we all use. I've modified it to update the position of the point its mousing at while its moving there, allowing me to fairly accurately mouse moving objects.

Before I continue, all credit for this post goes to @Flight and @BenLand100 as they wrote humanwindMouse and I just modified/bastardized it.

Anyway, here is a video of the code doing things. This video has incredibly low quality, you might need to fullscreen it to see what is actually happening.

Obviously, the air altar isn't moving, i'm just playing with the camera so relative to you its moving. I couldn't find an object that moves around fast enough to show off what this can actually do. But hopefully you get the picture.

Here is all the code used in the video.

This is the modified HumanWindMouse. I pass it a procedure to update the TPoint and I changed a few things in it as well.
Simba Code:
procedure Mmoving(xs, ys, gravity, wind, minwait, maxwait, targetArea : Extended; updateP : procedure(var p : TPoint));var  veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,D: extended;  lastX,lastY,MSP,W,TDist: integer;  pointi : TPoint;  T : LongWord;  sqrt2,sqrt3,sqrt5,maxStep,rCnc: extended;begin  MSP  := mouseSpeed;  sqrt2:= sqrt(2);  sqrt3:= sqrt(3);  sqrt5:= sqrt(5);  updateP(pointI);  if PointI.x = -1 then    exit;  TDist := distance(round(xs), round(ys), pointI.x, pointI.y);  t := getSystemTime() + 10000;  repeat    if (getSystemTime() > t) then      break;    updateP(pointI);    if PointI.x = -1 then      exit;    dist:= hypot(xs - pointI.x, ys - pointI.y);    wind:= minE(wind, dist);    if (dist < 1) then      dist := 1;    D := (round((round(TDist)*0.3))/7);    if (D > 25) then      D := 25;    if (D < 5) then      D := 5;    rCnc := random(6);    if (rCnc = 1) then      D := randomRange(2,3);    if (D <= round(dist)) then      maxStep := D    else      maxStep := round(dist);    if dist >= targetArea then    begin      windX:= windX / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;      windY:= windY / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;    end else    begin      windX:= windX / sqrt2;      windY:= windY / sqrt2;    end;    veloX:= veloX + windX;    veloY:= veloY + windY;    veloX:= veloX + gravity * (PointI.x - xs) / dist;    veloY:= veloY + gravity * (PointI.y - ys) / dist;    if (hypot(veloX, veloY) > maxStep) then    begin      randomDist:= maxStep / 2.0 + random(round(maxStep) div 2);      veloMag:= sqrt(veloX * veloX + veloY * veloY);      veloX:= (veloX / veloMag) * randomDist;      veloY:= (veloY / veloMag) * randomDist;    end;    lastX:= round(xs);    lastY:= round(ys);    xs:= xs + veloX;    ys:= ys + veloY;    if (lastX <> round(xs)) or (lastY <> round(ys)) then      moveMouse(round(xs), round(ys));    W := (random((round(100/MSP)))*6);    if (W < 5) then      W := 5;    W := round(W*0.9);    wait(W);    lastdist:= dist;  until(hypot(xs - PointI.x, ys - PointI.y) < 3);  mouseSpeed := MSP;end;

I also made a procedure to make using the above procedure easier. (just like we do with the actual humanWindMouse)

Simba Code:
procedure mMovingObject(button: integer;  updateP : procedure(var p : TPoint));var  randSpeed: extended;  x,y,ms: integer;begin  if (button = MOUSE_NONE) then    exit;  ms := mouseSpeed;  randSpeed := (random(mouseSpeed) / 2.0 + mouseSpeed) / 10.0;  getMousePos(x,y);  Mmoving(x, y, MOUSE_HUMAN, 5, 10.0/randSpeed, 15.0/randSpeed, 10.0*randSpeed, @updateP);  mouseSpeed := ms;  fastClick(button);end;

And then the procedure that gives the TPoint for the air altar.

Simba Code:
procedure findAltar(var p : TPoint);var  TPA : TPointARray;  x,y : integer;begin  findColorsSpiralTolerance(x,y,TPA,13480323,mainscreen.getBounds(),7,colorSetting(2, 0.45, 0.85));  if (Length(TPA) < 1) then  begin    p.x := -1;  end;  p := middleTPA(TPA);end;

And the program.

Simba Code:
begin  SetupSRL();  mMovingObject(MOUSE_RIGHT,@findAltar);end.

This is just the bare stuff, there is absolutely no failsafes in this, it just assumes the altar is in vision. It doesn't check mouseover text or really anything. To use this in a script, it would have to be modified to be able to deal with failure.

So yeah, I think this has potential for use in some things. Especially when its just an object with a very unique color.

2. Oh, wow. This is cool. Rep+, will use for sure.

3. awesome!

4. SRL Junior Member
Join Date
Oct 2014
Posts
32
Mentioned
0 Post(s)
Quoted
23 Post(s)
this is a very very nice idea, I will be using it ...I was too lazy to make it myself

5. SRL Member
Join Date
Jun 2014
Location
Lithuania
Posts
475
Mentioned
27 Post(s)
Quoted
200 Post(s)
Very nice. After work going to try it out. If it works then biggest flaw in my opinion which getting banned was not finding or failing toomuch on moving objects while going to waka tree and fairy rings would be fixed. Also in some ocassions drags finding, but made it way faster using mmtoms to generate search boxes for drag i want to get, so now not picking random or closes tpa in screen but mostly closest drag in space.

6. SRL Junior Member
Join Date
Oct 2014
Posts
32
Mentioned
0 Post(s)
Quoted
23 Post(s)
is it possible to pass parameters like this?

for example:
mMovingObject(MOUSE_RIGHT,@findAltar(p));

I get errors..

7. Originally Posted by Zef Style
is it possible to pass parameters like this?

for example:
mMovingObject(MOUSE_RIGHT,@findAltar(p));

I get errors..
No.

8. Originally Posted by Zef Style
is it possible to pass parameters like this?

for example:
mMovingObject(MOUSE_RIGHT,@findAltar(p));

I get errors..
I don't think so - you should be passing a function that outputs the TPoint 'p' so there's no need for you to pass the param to the function that you're already passing to mMovingObject()

E: Ninja'd by slacky

9. SRL Junior Member
Join Date
Oct 2014
Posts
32
Mentioned
0 Post(s)
Quoted
23 Post(s)
I would like to be able to pass it the first found coords of the object, then have the @find function search for that object in a box that updates while the mouse moves..instead of searching the entire screen..

10. Originally Posted by Zef Style
I would like to be able to pass it the first found coords of the object, then have the @find function search for that object in a box that updates while the mouse moves..instead of searching the entire screen..
You could do that internally in mMovingObject(), no? Add a new parameter, 'bounds' or similiar, it'd be a TBox. You'd have to search the whole screen first, but then update the TBox continually with the new bounds and search in there.

11. SRL Junior Member
Join Date
Oct 2014
Posts
32
Mentioned
0 Post(s)
Quoted
23 Post(s)
Originally Posted by KeepBotting
You could do that internally in mMovingObject(), no? Add a new parameter, 'bounds' or similiar, it'd be a TBox. You'd have to search the whole screen first, but then update the TBox continually with the new bounds and search in there.
that will not work mMovingObject just passes the @find to windmouse, the only way to do it would be to put it into the custom wind mouse..however, that would be quite inconvenient to have say 2-3 custom wind mouse functions in one script..haha

12. You have to be careful, your find() procedure could use quite some time (in terms of a mouse wait) which would change how the mouse is handled. A regular mouse wait uses something like 5-16ms, if you add another 16ms on that you're adding alot more wait time between the mouse steps.

I was also doing something like this but with multithreading to find my moving NPC.

13. SRL Member
Join Date
Jun 2014
Location
Lithuania
Posts
475
Mentioned
27 Post(s)
Quoted
200 Post(s)
Originally Posted by Olly
You have to be careful, your find() procedure could use quite some time (in terms of a mouse wait) which would change how the mouse is handled. A regular mouse wait uses something like 5-16ms, if you add another 16ms on that you're adding alot more wait time between the mouse steps.

I was also doing something like this but with multithreading to find my moving NPC.
What you exzactly mean of multithreading? used something like sharetabs plugin in one to track object in another update mouse pos? I really need to make something like this to catch non unique object while running and rotating camera at once..

14. SRL Junior Member
Join Date
Apr 2015
Posts
40
Mentioned
0 Post(s)
Quoted
20 Post(s)
I am very baffled with this script. It works great for one findcolor but not another. I used for Great Demons
Simba Code:
findColorsSpiralTolerance(x,y,TPA,3237839,mainscreen.getBounds(),23,colorSetting(2, 0.14, 1.65));
and this for a NPC in falador
Simba Code:
findColorsSpiralTolerance(x,y,TPA,4832693,mainscreen.getBounds(),9,colorSetting(2, 0.17, 1.65));
The findcolorspiral worked fine 100% of the time in falador but the other will not work. Made like 10 new ones on other monsters in the area, none of them would work. It would slowly move to a random spot on the screen and right click. All I am trying to do right now is for it to find what it is I am looking for and right click. This script is great for the falador NPC because it follows as they move. Can someone please help me figure out how to get this to work in other areas? I used same character and script but once I changed the numbers it stopped working for the alternative object. I have been trying to get some kind of debug or info as to why it just moves to a random spot and clicks but have not been able to get anything.

edit: i figured out the problem. This creates a TPoint which is good for one object, when there are multiple it gets confused. I changed it to ATPA to seperate all the points and works pretty well now.

15. SRL Junior Member
Join Date
Aug 2012
Posts
188
Mentioned
9 Post(s)
Quoted
71 Post(s)
Edit: How do I speed up the mouse? I've set mousespeed to 150 and its still very slow getting to the npc, which is a problem if I'm running towards it (the mouse almost doesn't move if I run at the right angle).

Thank you so much! This is how I implemented the code, I'm about to test it:
Simba Code:
begin  findColorsSpiralTolerance(x, y, TPA1, 13819881, mainscreen.getBounds(), 6, colorSetting(2, 0.72, 1.56));  findColorsSpiralTolerance(x, y, TPA2, 3158310, mainscreen.getBounds(), 5, colorSetting(2, 9.94, 1.06));  // Combine and sort color TPAs  TPA1.combine(TPA2);  ATPA := TPAtoATPAEx(TPA1, 8, 14);  ATPA.filterBetween(1, 40);  SortATPAFromFirstPoint(ATPA, Point(175, 0));  p := ATPA[0].getMiddle();  if (length(ATPA) < 1) then    p.x := -1;end;

16. Originally Posted by swaggle_pants
Edit: How do I speed up the mouse? I've set mousespeed to 150 and its still very slow getting to the npc, which is a problem if I'm running towards it (the mouse almost doesn't move if I run at the right angle).

Thank you so much! This is how I implemented the code, I'm about to test it:
Simba Code:
begin  findColorsSpiralTolerance(x, y, TPA1, 13819881, mainscreen.getBounds(), 6, colorSetting(2, 0.72, 1.56));  findColorsSpiralTolerance(x, y, TPA2, 3158310, mainscreen.getBounds(), 5, colorSetting(2, 9.94, 1.06));  // Combine and sort color TPAs  TPA1.combine(TPA2);  ATPA := TPAtoATPAEx(TPA1, 8, 14);  ATPA.filterBetween(1, 40);  SortATPAFromFirstPoint(ATPA, Point(175, 0));  p := ATPA[0].getMiddle();  if (length(ATPA) < 1) then    p.x := -1;end;
You'd have to fiddle with the code in the mMovingObject procedure.

17. Originally Posted by swaggle_pants
Edit: How do I speed up the mouse? I've set mousespeed to 150 and its still very slow getting to the npc,
The SRL mouse functions _brakeWindMouse and _humanWindMouse use the mouseSpeed setting but the logic is such that it hits a limit somewhere around 30 and goes no faster. Both functions have a wait in them:
Simba Code:
wait(W);

If you cut that wait in half you will find you can set it much higher:

Simba Code:
wait(round(W/2));

You can copy them into your script and add the override keyword so it uses your version:

Simba Code:
procedure _humanWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, targetArea: extended);  override;

18. Registered User
Join Date
Dec 2015
Posts
10
Mentioned
0 Post(s)
Quoted
2 Post(s)
this is neat!

19. Registered User
Join Date
Dec 2008
Posts
10
Mentioned
0 Post(s)
Quoted
1 Post(s)
Great work! It always excites me to see things like this being developed

20. Awesome idea and coding! I love this. This would be very helpful for NPC's who walk around. Rep+ for you. I wish I had thought of this

21. I've found that integrating these in a record to be very efficient in terms of script lines. It needed a little tinkering with the code. Instead of having the tpoint procedure be an input in the function itself, I just had it update the tpoint through "pointI := self.getPoint" for example

So I don't have to write multiple functions for each npc I wanted to find. If anyone would like me to share it and explain how it works, shoot me a PM.

This snippet has really really improved my scripts. So thank you!

22. I know this is an old thread, but I've been fiddling around with some of this as I was looking into ways on mousing a moving target, and this thread is very aptly relevant aha -

Anyways, I've modified the code to be a little more generic (the basic groundwork has been laid to find any object) through the use of records (as @fady mentioned), and turning the procedure into a function that returns a TPoint.

This is still largely a draft, but I just want to get out there what I've been working on.

Here's the test record I've been using:

Simba Code:
type  TFinderObj = record    ColorData: TColorData;    Size: integer;    OverText: TStringArray;  end;

For the actual findObj function I've laid out, it's main weakness is the fact that it does return the point that which is the middle of literally every match of the color, the TPA - without further filtering that may be useful on a per-use instance. I do have a 'Size' record variable that I thought could be used for this, but I'm still trying to figure out the best method. Not sure if I want to use toATPA or cluster on the TPA, and then sort the results from the player or something - or maybe just return the whole TPA array and loop through as is a pretty standard method, but that still seems unnecessary. Maybe just set x and y to the player coordinates for the SpiralTolerance call... Â¯\_(?)_/Â¯

Anyways, here's what my findObj function looks like:

Simba Code:
function findObj(objData: TFinderObj; searchArea: TBox): TPoint;var  ATPA: T2DPointArray;  TPA: TPointARray;  x, y: integer;  t: TTimeMarker;  p: TPoint;begin  t.reset(); t.start();  repeat    if (t.getTime() > 2500) then      exit(Point(-1, -1));    findColorsSpiralTolerance(x, y, TPA, objData.ColorData.color, searchArea, objData.ColorData.tolerance, objData.ColorData.settings);  until length(TPA) >= 1;  if length(TPA) >= 1 then    p := middleTPA(TPA);  result := p;end;

- this will be used in conjunction with a slightly modified iteration of Camel's modification on _humanWindMouse which now is a function that returns a boolean on whether or not it's reached it's destination:

Simba Code:
function mMoving(xs, ys, gravity, wind, minwait, maxwait, targetArea: Extended; objData: TFinderObj; searchArea: TBox): boolean;var  veloX, veloY, windX, windY, veloMag, dist, randomDist, D: extended;  lastX, lastY, MSP, W, TDist: integer;  pointI: TPoint;  T: LongWord;  sqrt2, sqrt3, sqrt5, maxStep, rCnc: extended;begin  MSP  := mouseSpeed;  sqrt2:= sqrt(2);  sqrt3:= sqrt(3);  sqrt5:= sqrt(5);  pointI := findObj(objData, searchArea);  if PointI.X = -1 then    exit;  TDist := distance(round(xs), round(ys), pointI.x, pointI.y);  t := getSystemTime() + 10000;  repeat    if (getSystemTime() > t) then      break;    pointI := findObj(objData, searchArea);    if PointI.X = -1 then      exit;    dist:= hypot(xs - pointI.x, ys - pointI.y);    wind:= minE(wind, dist);    if (dist < 1) then      dist := 1;    D := (round((round(TDist)*0.3))/7);    if (D > 25) then      D := 25;    if (D < 5) then      D := 5;    rCnc := random(6);    if (rCnc = 1) then      D := randomRange(2,3);    if (D <= round(dist)) then      maxStep := D    else      maxStep := round(dist);    if dist >= targetArea then    begin      windX:= windX / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;      windY:= windY / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;    end else    begin      windX:= windX / sqrt2;      windY:= windY / sqrt2;    end;    veloX:= veloX + windX;    veloY:= veloY + windY;    veloX:= veloX + gravity * (PointI.x - xs) / dist;    veloY:= veloY + gravity * (PointI.y - ys) / dist;    if (hypot(veloX, veloY) > maxStep) then    begin      randomDist:= maxStep / 2.0 + random(round(maxStep) div 2);      veloMag:= sqrt(veloX * veloX + veloY * veloY);      veloX:= (veloX / veloMag) * randomDist;      veloY:= (veloY / veloMag) * randomDist;    end;    lastX:= round(xs);    lastY:= round(ys);    xs:= xs + veloX;    ys:= ys + veloY;    if (lastX <> round(xs)) or (lastY <> round(ys)) then      moveMouse(round(xs), round(ys));    W := (random((round(100/MSP)))*6);    if (W < 5) then      W := 5;    W := round(W*0.9);    wait(W);  until(hypot(xs - PointI.x, ys - PointI.y) < 3);  if (hypot(xs - PointI.x, ys - PointI.y) < 3) then    exit(true);  mouseSpeed := MSP;end;

... which of course is used through a wrapper function which returns that result:

Simba Code:
function mMovingObject(objData: TFinderObj; searchArea: TBox; button: integer): boolean;var  randSpeed: extended;  x, y, ms: integer;begin  if (button = MOUSE_NONE) then    exit;  ms := mouseSpeed;  randSpeed := (random(mouseSpeed) / 2.0 + mouseSpeed) / 10.0;  getMousePos(x,y);  if mMoving(x, y, MOUSE_HUMAN, 5, 10.0/randSpeed, 15.0/randSpeed, 10.0*randSpeed, objData, searchArea) then    begin      fastClick(button);      exit(true);    end;  mouseSpeed := ms;end;

And then when used all together to find, say, the Prifddinas bonfire (data pulled from my Bonfirer for ease), we get a use case that looks something like:

Simba Code:
var  bonfire: TFinderObj;begin  setupSRL();  with bonfire do  begin    ColorData := [2712485, 3, [2, [0.06, 0.25]]];    Size := 20;    OverText := ['onfire', 'Bonf'];  end;  if (mMovingObject(bonfire, mainScreen.getBounds(), MOUSE_MOVE)) then    if (isMouseOverText(bonfire.OverText, 1000)) then      writeLn('We found the bonfire!');end.

Of course, this is still a draft in trying to get it to work in as many situations as possible, and probably some adjustments could be made to on what makes these functions return true and stuff - but I think this is a good start!

Very cool stuff!

Also, if you want to stay up to date with or contribute to this development, feel free to visit the GitHub.
Last edited by Lama; 08-01-2018 at 02:56 PM.

23. Originally Posted by Olly
You have to be careful, your find() procedure could use quite some time (in terms of a mouse wait) which would change how the mouse is handled. A regular mouse wait uses something like 5-16ms, if you add another 16ms on that you're adding alot more wait time between the mouse steps.

I was also doing something like this but with multithreading to find my moving NPC.
Is multi-threading possible with SIMBA (for OSRS)(without a plugin)

Or are you just complaining?