SRL Archive - Discussions and Debates

Mouse moving testing


Gu3st...

2012-06-20 22:05:11

So I've messed around with a new kind of mouse moving procedures.

I tried to keep the code neat and tidy, but the code started being messy when I was 95% finished and I had to add WindMouse to the code to generate a new point, so I just didn't care about tidyness after that point..

The main idea, anyways, is to have an array of "TMouseData" which holds this information:
  1. Point in space
  2. How long to wait before ilterating to the next point
  3. What buttons to hold down at this point

Fairly simple and pretty basic stuff, I know, but doing it like this makes it much easier to add stuff such as "Fitt's Law" and so on.

Here's the (messy) code I produced:
const
mouseRight = mouse_Right; // 0
mouseLeft = mouse_Left; // 1
mouseMiddle = mouse_Middle;// 2
mouseMove = 3; // 3

var
MouseSpeed : Integer;

type
TMouseData = record
P : TPoint;
Time : Integer; //0..2
ButtonDown : array [mouseRight..mouseMiddle] of Boolean;
end;
TMouseDataArray = array of TMouseData;


//I found these procedures to be kind of useless... Just kept them for historical reasons... or something..

{procedure setTime(var MDA : TMouseDataArray; const _mouseSpeed : Integer);
var
I : Integer;
begin
for I := 0 to High(MDA) do
MDA[I].Time := Round((Max(Random(Round(100/_mouseSpeed*3)), 5) * 1.0) * 1.5) + Random(Round(I div 5));
end;

procedure setButtonDown(var MDA : TMouseDataArray; const mouseIndexes : array [mouse_Right..mouse_Middle] of TIntegerArray);
var
J, I : Integer;
begin
for J := mouseRight to mouseMiddle do
for I := 0 to High(MDA) do
if InIntArray(mouseIndexes[J], I) then
MDA[I].ButtonDown[J] := True
else
MDA[I].ButtonDown[J] := False;
end;}

procedure setPath(var MDA : TMouseDataArray; const objectTPA : TPointArray; const _mouseAction, _mouseSpeed : Integer);
var
sP, mP : TPoint;
tmpTPA : TPointArray;
tmpBox : TBox;
tmpW, tmpH, I, J, H : Integer;
xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended;
randSpeed: Extended;

//Taken from WindMouse
var
veloX, veloY, windX, windY, veloMag, dist, randomDist, lastDist, step: extended;
lastX, lastY: integer;
sqrt2, sqrt3, sqrt5: extended;
begin
GetMousePos(sP.X, sP.Y);
xs := sP.X;
ys := sP.Y;

tmpBox := GetTPABounds(tmpTPA);
tmpW := tmpBox.X2 - tmpBox.X1;
tmpH := tmpBox.Y2 - tmpBox.Y1;

tmpTPA := CopyTPA(objectTPA);
mP := MiddleTPA(tmpTPA);
SortTPAFrom(tmpTPA, sP);

mP := Point((tmpTPA[0].X + mP.X) div 2, (tmpTPA[0].Y + mP.Y) div 2);
xe := mP.X;
ye := mP.Y;

// Taken from MMouse
randSpeed:= (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
if randSpeed = 0.0 then randSpeed := 0.1;
gravity := 9.0;
wind := 3.0;
minWait := 10.0/randSpeed;
maxWait := 15.0/randSpeed;
maxStep := 10.0*randSpeed;
targetArea := 10.0*randSpeed;

//Taken from WindMouse
sqrt2 := sqrt(2);
sqrt3 := sqrt(3);
sqrt5 := sqrt(5);

while hypot(xs - xe, ys - ye) > 1 do
begin
//Taken from WindMouse
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, 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;
if (maxStep < 3) then
begin
maxStep:= random(3) + 3.0;
end else
begin
maxStep:= maxStep / sqrt5;
end;
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;
step:= hypot(xs - lastX, ys - lastY);
lastdist:= dist;

setLength(MDA, Length(MDA)+1);
I := High(MDA);
MDA[I].P := Point(Round(xs), Round(ys));
MDA[I].Time := Round((Max(Random(Round(100/_mouseSpeed*3)), 5) * 1.0) * 1.5) + Random(Round(I div 5));

end;

// This could be tidyier, but meh!!
// This part basically resets the ButtonDown attributes, then sets the ones at the end of the path to true
// So in other words; it will start clicking 2 steps before arriving at the final point.
H := High(MDA);
for I := 0 to H do
begin
for J := mouseRight to mouseMiddle do
MDA[I].ButtonDown[J] := False;
if InRange(mouseAction, mouseRight, mouseMiddle) then
if I > H-2 then // click 2 mouse steps before arriving
MDA[I].ButtonDown[mouseAction] := True;
end;
end;

// It shouldn't even function with Lape yet, but heey, why not add it in..?
{$IFDEF Lape}
procedure TMouseData.Perform();
{$ELSE}
procedure TMouseDataPerform(var MD : TMouseData);
{$ENDIF}
var
tmpI : Integer;
tmpB : Boolean;
begin

{$IFNDEF Lape}
with MD do
begin
{$ENDIF}

MoveMouse(P.X, P.Y);
for tmpI := 0 to High(ButtonDown) do
begin
IsMouseButtonDown(tmpI); // Free the buffer. (Is this still needed? I've always done it from SCAR 3.15b and upwards)
tmpB := IsMouseButtonDown(tmpI);
if ButtonDown[tmpI] then
begin
if not tmpB then // If ButtonDown says so, and it isn't down, MAKE IT SO.
HoldMouse(P.X, P.Y, tmpI);
end else
if tmpB then // Error! Mouse button down, when it shouldn't be; UN-DO :O :O
ReleaseMouse(P.X, P.Y, tmpI);

end;
Wait(Time);

{$IFNDEF Lape}
end;
{$ENDIF}

end;

procedure MouseTPA(const objectTPA : TPointArray; const _mouseAction, _mouseSpeed : Integer);
var
MDA : TMouseDataArray;
I : Integer;
begin
setPath(MDA, objectTPA, _mouseAction);
setTime(MDA, _mouseSpeed);

for I := 0 to High(MDA) do
{$IFDEF Lape}
MDA[I].Perform();
{$ELSE}
TMouseDataPerform(MDA[I]);
{$ENDIF}

if InRange(_mouseAction, mouseRight, mouseMiddle) then
ReleaseMouse(0, 0, _mouseAction); // Release the button in the end
end;

procedure MouseBox(const Box : TBox; const _mouseAction, _mouseSpeed : Integer);
begin
MouseTPA(TPAFromBox(Box), _mouseAction, _mouseSpeed);
end;

procedure Mouse(mousex, mousey, ranx, rany: Integer; button: integer);
begin
MouseTPA([Point(mousex+random(ranx), mousey+random(rany))], button, MouseSpeed);
end;

procedure MMouse(mousex, mousey, ranx, rany: Integer);
begin
MouseTPA([Point(mousex+random(ranx), mousey+random(rany))], mouseMove, MouseSpeed);
end;

begin
MouseSpeed := 13;
Mouse(0, 0, 0, 0, mouseLeft);
end.

Bear in mind that I didn't use much time on this, so this is just a rough sketch of the idea, but I hope you get my point.. :p

This means that we can (in theory) click several places in one consecutive stroke with the mouse, or drag items "on the fly" (Starting position at mainscreen, start moving the mouse towards item1, start holding down the mouse at item1 and continue moving the mouse (this will be done without stopping moving the mouse at item1) towards item2, then release mouse)

Abu

2012-06-21 07:49:33

This looks very interesting.

So basically, I could create a series of mouse movements within this one function? Such as clicking a spell, clicking item, clicking a spell and then a different item?

Also, which function is the one from there which actually does the above?

Mark

2012-06-21 08:12:06

Could also be useful with new update like using it to arrange action bar with the drag an drop

Gu3st...

2012-06-21 08:38:44

Yes, that's the advantage of this way of doing it, rather than 1. Move, 2. Click.

Theoretically, you could keep the mouse moving throughout the whole script if you wanted to.

Setting it up to do so is kinda hard at the moment, but I thought of making it so that you can define the path and if where you want to click just like before, but then setting the time it waits before moving to the next step in a separate procedure, ultimately "cropping" several "MMouse(blah)" into one unison movement

The code above is pretty messy, and was made in the middle of the night.. I'll re-do the code when I get him from work in about 6 hours.

I could do something like
"procedure AddToMouse();
begin
blah;
end;"

and

"procedure PerformMouse();
begin
blah;
end;"

Where the movement performing code would be
"AddToMouse(X, Y, rX, rY, holdmouse_Left);
AddToMouse(X, Y, rX, rY, releasemouse_Left);" or whatever

Kyle Undefined

2012-06-21 13:19:38

Hmm, this seems rather interesting. Awesome work!

Gu3st...

2012-06-21 15:16:07

From: Kyle Undefined
Hmm, this seems rather interesting. Awesome work!
Lol, it's nothing :P really, it is nothing

Going to start working on it again now