SRL Archive - OSR Help

Concurrent object tracking/mouse movement


Goobs

2015-03-25 13:55:55

Hey everyone, I've ran into a bit of a pain in the ass while writing a fighting script.

The monsters I am fighting aren't aggressive, so fighting them requires me to click on them to start the fight. However, these lil bastards are really fast, and like to move around a lot.

I've trimmed the fat off of the TPA finder, but in the time it takes for the mouse to get to where the monster was located at the find, the monster moves. So the mouse goes where it was, the tries to refind it. This makes it skip along following the monster without actually clicking it. Once the monster stops or something else happens, it can click them, but it's not ideal for me.

Now, I put concurrent in the title, and I do know that you can't do concurrence in Simba (that I know of). If you call KeyDown(), you can do something while it is simulating the keypress. In this sense it is sort of concurrent. I want to know if you can do something similar with the mouse. Instead of making it be a loop of TPAFinder -> Mouse, I want it to find the initial TPA, start moving the mouse toward the monster, and every 50 or so ms it would be calling the TPA finder again, altering it's final goal if the monster moved position. This way, the mouse doesn't stop moving until it is right on top of the monster.

Is this possible? Or is there a simpler way to go about this? I've been writing scripts for years but I haven't really done anything with fighter scripts.

bg5

2015-03-25 14:14:14

I have been working on similar problem,with reflection, in last week. I need a function, which can pick up item, while character is running. I've made this:


mouseSpeed := 50;
// initial position of the mouse is MS center
while MyGuy.IsMoving do
begin
P := self.GetMSPoint(); // P is the point of item
GetMousePos(mx,my);
if Distance(mx,my,P.x,P.y) > 20 then // when distance between current mouse pos and item pos is > 20 then move mouse for half a distance to item
begin
Reflect.Mouse.Move(Point( mx+(P.x-mx)div 2 , my+(P.y-my)div 2 ), 1 , 1);
end else
begin
Reflect.Mouse.Move( P,0,0,Mouse_Right);
if Reflect.Text.ChooseOption(self.GetName,50) then
begin
Result := TRUE;
break;
end;
end;
end; // repeat

I can not really say it works good. It has like 50% accuracy, in 50% of cases it either missclicks right button or character stops running before mouse can rich the item. I think what we really need is to place destination updating function inside a humanMouse(). I haven't tried it yet because mouse function looks quite complicated for me :P

The Mayor

2015-03-25 14:15:50

You increased your mouse speed?

KeepBotting

2015-03-25 16:32:56

I wrote some stuff on this before, it's at the bottom of this post: https://villavu.com/forum/showthread.php?t=111254&p=1321917#post1321917

A combination of the "less looping" idea from my post, and The Mayor's suggestion of increasing mouse speed (solely whilst running the fighting routine) would probably alleviate your problem.

Having a routine that alternates calls between TPA finding and mouse movements would be cool and probably accomplish the same thing. But I feel like it'd be way more trouble than it's worth.

Multithreading, and thus, concurrent operations just aren't possible because neither Lape nor PascalScript are thread safe.

A workaround would be to create several scripts and have them include each other … using sockets or file I/O, you could have the separate scripts "talk" to each other and exchange data.
These "slave" scripts would then report back to the "master" script (or the server if you're using sockets) to perform the required operation ingame.

bg5

2015-03-25 17:09:24

From: KeepBotting
…

Multithreading is not needed, if detecting function is fast enough. However it's nice idea, when detector does a lot of complicated calculations, and it is possible https://villavu.com/forum/showthread.php?t=107221&highlight=tabsharemem ,I just don't know if you can share same smart client between two tabs.

3Garrett3

2015-03-25 17:26:57

If you're using reflection, you could probably use clickMouse (I think that's built into Simba right?). Obscurity uses it for his OGL stuff AFAIK and he hasn't gotten bans from it. In the days of touchscreens, they can't ban you for not moving the mouse before clicking. The only benefit of mouse moving is to check uptext before clicking. With reflection you already know the uptext is correct before hovering, so you could just right click the MS coordinates and choose the right MOB from the list.

bg5

2015-03-25 18:53:01

From: 3Garrett3
..


I really prefer to use humanlike mouse, I'm overcareful :redface: Moreover such mouse function would have many applications.

Goobs

2015-03-25 19:14:47

I suppose I should be more clear about this question - I'm writing this all in color using Aerolib, in OSR =P

bg5

2015-03-25 22:55:38

@Probably Glitched

Check this out:
https://villavu.com/forum/showthread.php?t=112444&p=1336025#post1336025

damn, I'm tired now

tls

2015-03-25 23:10:59

From: bg5
@Probably Glitched

Check this out:
https://villavu.com/forum/showthread.php?t=112444&p=1336025#post1336025

damn, I'm tired now


Why don't you just pass a function? https://github.com/smithtrenton/OSR-Reflection/blob/master/api/players.simba#L16

Or create a structure called TMouseTarget that has a function that returns a new point and pass the target. In fact that would be a new thing for the next SRL. The mouse structure wouldn't just get used for specific points, but would get passed a target that could have dynamic location, and everything that is clicked in the include would extend this structure(override the getPoint function so that it returns the right point).
/ramble

bg5

2015-03-25 23:26:55

From: tls
Why don't you just pass a function? https://github.com/smithtrenton/OSR-Reflection/blob/master/api/players.simba#L16


function TPlayerApi.getPlayers(filter: function(var p: TPlayer): Boolean): TPlayerArray;
Honestly no idea what this function does and how is it relevant to OP.

From: tls

Or create a structure called TMouseTarget that has a function that returns a new point and pass the target. In fact that would be a new thing for the next SRL. The mouse structure wouldn't just get used for specific points, but would get passed a target that could have dynamic location, and everything that is clicked in the include would extend this structure(override the getPoint function so that it returns the right point).
/ramble


Because it was just an example of using VariantInvoke(). I can't image what are you talking about without some code or pseudocode as example :P

tls

2015-03-25 23:37:35

From: bg5
function TPlayerApi.getPlayers(filter: function(var p: TPlayer): Boolean): TPlayerArray;
Honestly no idea what this function does and how is it relevant to OP.



Because it was just an example of using VariantInvoke().


It is relevant to your idea of getting a new point.
Use:

function dynamicMouse(getPoint: function: TPoint);
That would be the global mousing function.
Then you just pass @FindTreeTPoint as the parameter and it would update the point for you.

bg5

2015-03-25 23:47:37

From: tls
It is relevant to your idea of getting a new point.
Use:

function dynamicMouse(getPoint: function: TPoint);
That would be the global mousing function.
Then you just pass @FindTreeTPoint as the parameter and it would update the point for you.


This way you can't pass functions with arguments like @FindTreeTPoint(YEW_TREE)
and you can't pass methods like TreeFinder.FindTreeTPoint.

@edit
and I don't see any possibility to go around it, like I did with VariantInvoke() in my tutorial.

Flight

2015-03-26 01:15:58

From: bg5
This way you can't pass functions with arguments like @FindTreeTPoint(YEW_TREE)
and you can't pass methods like TreeFinder.FindTreeTPoint.

@edit
and I don't see any possibility to go around it, like I did with VariantInvoke() in my tutorial.


Sexy. I'll look into this tomorrow, I really like the idea!

Goobs

2015-03-26 09:46:17

From: bg5
@Probably Glitched

Check this out:
https://villavu.com/forum/showthread.php?t=112444&p=1336025#post1336025

damn, I'm tired now



var res_Wrap_TReflectGroundItem_GetMSPoint : TPoint;
function Wrap_TReflectGroundItem_GetMSPoint(adr_self, adr_result : integer) : integer;
begin
TPoint(Pointer(adr_result)^) := TReflectGroundItem(Pointer(adr_self)^).GetMSPoint();
Result := adr_result;
end;

How would I do this part for a TPA finder? Let's make it simple and give it the following definition:

TPAFinder(Colors: TIntegerArray; Search: TBox): TPoint;

Scratch the uptext searching - that would obviously have to be done after it reaches the goal.

bg5

2015-03-26 12:15:15

From: Probably Glitched
…


program new;

function TPAFinder(Colors: TIntegerArray; Search: TBox): TPoint;
begin
writeln(Colors);
writeln(Search);
Result := Point(random(123),random(456));

end;
var
res_Wrap_TPAFinder : TPoint;
colors_Wrap_TPAFinder : TIntegerArray; // not really needed if var already exists
search_Wrap_TPAFinder : TBox; // not really needed if var already exists

function Wrap_TPAFinder(adr_res, adr_colors, adr_search: integer) : integer;
begin
TPoint(Pointer(adr_res)^) := TPAFinder( TIntegerArray(Pointer(adr_colors)^),TBox(Pointer(adr_search)^) );
Result := adr_res;
end;

procedure test (FuncToInvoke : string; args :TVariantArray; howmany : integer);
var i,ap : integer;
p : TPoint;
begin
for i := 0 to howmany-1 do
begin
ap := VariantInvoke(FuncToInvoke,args);
p := TPoint(Pointer(ap)^);
writeln(p);
end
end;
begin
colors_Wrap_TPAFinder := [1,2,3,4,5,6,7,7];
search_Wrap_TPAFinder := IntToBox(123,324,5654,76);
test('Wrap_TPAFinder',[integer(@res_Wrap_TPAFinder),integer(@colors_Wrap_TPAFinder),integer(@search_Wrap_TPAFinder)],3);
end.

with TrackMMouse

 TrackMMouse(TRUE,'Wrap_TPAFinder',
[integer(@res_Wrap_TPAFinder),integer(@colors_Wrap_TPAFinder),integer(@search_Wrap_TPAFinder)], 100);

Goobs

2015-03-26 12:45:34

From: bg5
program new;

function TPAFinder(Colors: TIntegerArray; Search: TBox): TPoint;
begin
writeln(Colors);
writeln(Search);
Result := Point(random(123),random(456));

end;
var
res_Wrap_TPAFinder : TPoint;
colors_Wrap_TPAFinder : TIntegerArray; // not really needed if var already exists
search_Wrap_TPAFinder : TBox; // not really needed if var already exists

function Wrap_TPAFinder(adr_res, adr_colors, adr_search: integer) : integer;
begin
TPoint(Pointer(adr_res)^) := TPAFinder( TIntegerArray(Pointer(adr_colors)^),TBox(Pointer(adr_search)^) );
Result := adr_res;
end;

procedure test (FuncToInvoke : string; args :TVariantArray; howmany : integer);
var i,ap : integer;
p : TPoint;
begin
for i := 0 to howmany-1 do
begin
ap := VariantInvoke(FuncToInvoke,args);
p := TPoint(Pointer(ap)^);
writeln(p);
end
end;
begin
colors_Wrap_TPAFinder := [1,2,3,4,5,6,7,7];
search_Wrap_TPAFinder := IntToBox(123,324,5654,76);
test('Wrap_TPAFinder',[integer(@res_Wrap_TPAFinder),integer(@colors_Wrap_TPAFinder),integer(@search_Wrap_TPAFinder)],3);
end.

with TrackMMouse

 TrackMMouse(TRUE,'Wrap_TPAFinder',
[integer(@res_Wrap_TPAFinder),integer(@colors_Wrap_TPAFinder),integer(@search_Wrap_TPAFinder)], 100);


Okay, I got it to compile, but it gave me an access violation in windTrackingMouse at the first instance of

  Pe := TPoint(Pointer(ap)^); // *    

Goobs

2015-03-26 12:52:34

If I replace that line with a call to TPAFinder and remove the invoke call above it, it seems to work fine! O.o

bg5

2015-03-26 13:15:50

From: Probably Glitched
If I replace that line with a call to TPAFinder and remove the invoke call above it, it seems to work fine! O.o


So it gives access violation at first instance of invoke, but not at second?

Goobs

2015-03-26 14:43:01

From: bg5
So it gives access violation at first instance of invoke, but not at second?


It never gets past the first one =P

bg5

2015-03-26 14:54:39

From: Probably Glitched
It never gets past the first one =P


can I see your code?

Goobs

2015-03-26 16:13:39

From: bg5
can I see your code?



function TPAFinder2(Colores: TIntegerArray; var Search: TBox): TPoint; forward;
procedure AntiBan; forward;
function inFight: boolean; forward;
function TPAFinder(Colors: TIntegerArray; TheUpText: TStringArray; distawnce: Integer; var midx, midy: integer; Boxy: TBox; Verifying: Boolean): Boolean; forward;

{*******************************************************************************
Procedure windTrackingMouse();
By: Flight & bg5
Description (Flight): Mouse movement based on distance to determine speed. Default slowed
speed at 20% from destination, if Double is set to true then slowed
speed also starts at origin and ends 80% to destination.

Description (bg5): Variation of Flight's brakeWindMouse from aerolib. Calls function
(returning address to TPoint) every refreshingDelay seconds to update destination.
That function must be wrapped properly!
All changes are marked with //*
*******************************************************************************}
Procedure windTrackingMouse(xs, ys, gravity, wind, minWait, maxWait,
targetArea: extended; double: boolean;
funcRetTPointAdr:string; args:TVariantArray; refreshingDelay :integer ); //*
var
T,rD : Timer; //*
xe, ye , ap :integer; //*
Pe :TPoint; //*
veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,D: extended;
lastX,lastY,MSP,W,TDist: integer;
sqrt2,sqrt3,sqrt5,PDist,maxStep,dModA,dModB,nModA,nModB: extended;
Search: TBox;
begin
//ap := VariantInvoke(funcRetTPointAdr,args); // *
Search := MSBOX;
writeln(tostr(ap));
Pe := TPAFinder2(wrlds, Search);
xe := Pe.X; //*
if(xe = 0) then
Exit;
ye := Pe.y; //*
rD.start(); //*

MSP := MouseSpeed;
sqrt2:= sqrt(2);
sqrt3:= sqrt(3);
sqrt5:= sqrt(5);

TDist := Distance(Round(xs), Round(ys), Round(xe), Round(ye));
if (TDist < 1) then
TDist := 1;

dModA := 0.88;
dModB := 0.95;

if (TDist > 220) then
begin
nModA := 0.08;
nModB := 0.04;
end else if (TDist <= 220) then
begin
nModA := 0.20;
nModB := 0.10;
end;



T.start();
repeat
if (T.timeElapsed() > 10000) then
break;
if (rd.timeElapsed() > refreshingDelay) then //*
begin
//ap := VariantInvoke(funcRetTPointAdr,args); // *
Pe := TPAFinder2(wrlds, Search);
xe := Pe.X; //*
ye := Pe.y; //*
rD.start(); //*
end;


dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
if (dist < 1) then
dist := 1;
PDist := (dist/TDist);
if (PDist < 0.01) then
PDist := 0.01;

if Double then
begin
if (PDist <= dModA) then
begin
D := (Round((Round(dist)*0.3))/5);
if (D < 20) then
D := 20;

end else if (PDist > dModA) then
begin
if (PDist < dModB) then
D := RandomRange(5, 8)
else if (PDist >= dModB) then
D := RandomRange(3, 4);
end;
end;

if (PDist >= nModA) then
begin
D := (Round((Round(dist)*0.3))/5);
if (D < 20) then
D := 20;
end else if (PDist < nModA) then
begin
if (PDist >= nModB) then
D := RandomRange(5, 8)
else if (PDist < nModB) then
D := RandomRange(3, 4);
end;

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 * (xe - xs) / dist;
veloY:= veloY + gravity * (ye - 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;
if Double then
if (PDist > dModA) then
W := Round(W*2.5)
else
W := Round(W*1.2);
wait(W);
lastdist:= dist;
until(hypot(xs - xe, ys - ye) < 1)

if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
MoveMouse(Round(xe), Round(ye));

MouseSpeed := MSP;
end;

{*******************************************************************************
By: Flight & bg5
Description(Flight): Makes use of BrakeWindMouse; mouse speed decreases at 15% to
destination point. If Double is set to true then speed starts
slow and increases through the first 15% of the path.
Description (bg5): Variation of Flight's brakeMMouse from aerolib. Calls function
(returning address to TPoint) every refreshingDelay seconds to update destination.
That function must be wrapped properly!
All changes are marked with //*
*******************************************************************************}
Procedure TrackMMouse(double: Boolean; //* randomization of destination point not needed
funcRetTPointAdr:string; args:TVariantArray; refreshingDelay :integer); //*
var
randSpeed : extended;
X,Y,MS : integer;
begin
MS := MouseSpeed;
//MouseSpeed := 10;
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
getMousePos(X, Y);

windTrackingMouse(X, Y, //*
8, 3, 10.0/randSpeed, 15.0/randSpeed, 10.0*randSpeed, double,
funcRetTPointAdr,args,refreshingDelay); //*
MouseSpeed := MS;
end;

var
res_Wrap_TPAFinder2 : TPoint;
colors_Wrap_TPAFinder : TIntegerArray; // not really needed if var already exists
search_Wrap_TPAFinder : TBox; // not really needed if var already exists

function Wrap_TPAFinder(adr_res, adr_colors, adr_search: integer) : integer;
begin
TPoint(Pointer(adr_res)^) := TPAFinder2( TIntegerArray(Pointer(adr_colors)^),TBox(Pointer(adr_search)^) );
Result := adr_res;
end;

procedure test (FuncToInvoke : string; args :TVariantArray; howmany : integer);
var i,ap : integer;
p : TPoint;
begin
for i := 0 to howmany-1 do
begin
ap := VariantInvoke(FuncToInvoke,args);
p := TPoint(Pointer(ap)^);
writeln(p);
end
end;

{********************************************************************


}






function trackFight: boolean;
var
x, y, tries: Integer;
Colors: TIntegerArray;
begin
{...}

TrackMMouse(TRUE,'res_Wrap_TPAFinder2',
[integer(@res_Wrap_TPAFinder2),integer(@colors_Wrap_TPAFinder),integer(@search_Wrap_TPAFinder)], 300);
if(WaitUpText('xperimen', 10+random(10))) then
begin
GetMousePos(x, y);
Mouse(Point(x, y), 0, 0, Mouse_Left);
if didRedClick then
begin

Result := TRUE;
end;
end;
{..}

end;

Goobs

2015-03-26 16:15:11

Just imagine the Pe var being what is originally was o.O My simba crashed since then, so I can't recover what it was before

bg5

2015-03-26 16:40:54

From: Probably Glitched
Just imagine the Pe var being what is originally was o.O My simba crashed since then, so I can't recover what it was before


Where is your wrapper?

Oh, I see now, well let me check this out.

You called variable name instead of function name :D

TrackMMouse(TRUE,'res_Wrap_TPAFinder2',