Sign in to follow this  
Followers 0
Leighwyn

MouseMove when the cursor can't move?

19 posts in this topic

Thanks in advance if anyone can sort this out for me...it's been a major hiccup in my progress of writing a game script.

Here is the action I would love to automate:

Click-hold the right mouse button anywhere on the screen, drag right or left a certain amount, release mouse button.

Sounds simple, I know. I would just use the MouseClickDrag() function and be done. The problem I'm encountering is that while holding down that mouse button, the game prevents the cursor from moving.

For example, if I were to place the mouse cursor over some static feature of the game GUI, click-hold the RMB, drag my physical mouse 3 inches, release RMB...my cursor would still be shown exactly where it was before, however my view would have moved in relation to how far I physically moved my mouse.

Because of this sticky mouse cursor, autoit completely freaks out and won't stop me from rotating.

Assuming there is no other means to rotate your view within the game, that this mouse command were the only way, is there ANY means of working around that that someone here might know of?

I remain hopeful only because the game obviously knows my mouse is moving, but I'm not sure AutoIt has a function (at least transparent enough for me to be able to find it) that can tell.

Thanks again!

Share this post


Link to post
Share on other sites



Hi,

I's suggest to remember the current mouse position using MouseGetPos. After trying the drag&drop, compare the old and the new position :rolleyes:

best regards

Marc


It's my job to comfort the disturbed and to disturb the comfortable.

Share this post


Link to post
Share on other sites

Hi,

I's suggest to remember the current mouse position using MouseGetPos. After trying the drag&drop, compare the old and the new position :rolleyes:

best regards

Marc

Hi Marc, thanks for the reply.

I thought the same thing as you and have previously tried that. However, the old and new positions are exactly the same because the pointer coordinates havent changed at all :rambo:

I verified this by first being in another windows program, placing my cursor over a specific spot of that window, alt-tabbing into the game, holding the mouse button down and physically moving my mouse, then alt tabbing back into the first program before lifting the button. The cursor will still be in the exact same spot it was to start with!!

Very frustrating. Anyone else have thoughts?

Thanks.

Share this post


Link to post
Share on other sites

I guess this is a 3D game right?

I'm not totally sure how it works, but I know that the 2D mouse movements available in autoit(X, Y) translates to the games 3D environment.

Most 3D games locks your mouse pointer to the center of the 3D area(usually the game window height & length / 2)...

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I guess this is a 3D game right?

I'm not totally sure how it works, but I know that the 2D mouse movements available in autoit(X, Y) translates to the games 3D environment.

Most 3D games locks your mouse pointer to the center of the 3D area(usually the game window height & length / 2)...

Wow thanks FreeFry, that simple reply might actually be what enables me to continue! Based off your suggestion, I recorded a log of mouse coordinates for this simple series of events:
  • Place mouse cursor anywhere
  • Begin recording
  • Right click and hold, but do not move mouse
  • Release right mouse button
And the result is exactly as you had anticipated...My coord goes from ~(300,300) then immediately jumps to (840,525) [im at 1680x1050], then immediately returns to (300,300). The cursor is actually hidden while holding down the button, so I had no idea of this behavior. Thanks!

Originally, I had wanted to do something like..

$pos = MouseGetPos()
MouseClickDrag("right",$pos[0],$pos[1],$pos[0]+20,$pos[1])

to rotate the screen however much those 20 pixels of mouse movement would give me.

With your enlightenment, my attempt will be to see if I can use this for the same effect:

MouseClick("right", 840-20 , 525)

or maybe

MouseMove(840-820, 525)
MouseDown("right")
sleep(500)
MouseUp("right")

depending on if the first doesn't allow the game to capture the "click-drag" behavior.

Now my work day will be interminable as I really want to get home to try this! :">

If it works, FreeFry will get my gold star.

Edited by Leighwyn

Share this post


Link to post
Share on other sites

Good luck mate. :rolleyes:

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Wow thanks FreeFry, that simple reply might actually be what enables me to continue! Based off your suggestion, I recorded a log of mouse coordinates for this simple series of events:

  • Place mouse cursor anywhere
  • Begin recording
  • Right click and hold, but do not move mouse
  • Release right mouse button
And the result is exactly as you had anticipated...My coord goes from ~(300,300) then immediately jumps to (840,525) [im at 1680x1050], then immediately returns to (300,300). The cursor is actually hidden while holding down the button, so I had no idea of this behavior. Thanks!

Originally, I had wanted to do something like..

$pos = MouseGetPos()
MouseClickDrag("right",$pos[0],$pos[1],$pos[0]+20,$pos[1])

to rotate the screen however much those 20 pixels of mouse movement would give me.

With your enlightenment, my attempt will be to see if I can use this for the same effect:

MouseClick("right", 840-20 , 525)

or maybe

MouseMove(840-820, 525)
MouseDown("right")
sleep(500)
MouseUp("right")

depending on if the first doesn't allow the game to capture the "click-drag" behavior.

Now my work day will be interminable as I really want to get home to try this! :">

If it works, FreeFry will get my gold star.

Ok, so now you have my curiosity up... Did this work for you, or are you still experimenting? :rolleyes:

Edited by izy

Share this post


Link to post
Share on other sites

Ok, so now you have my curiosity up... Did this work for you, or are you still experimenting? :rolleyes:

It absolutely did! Basically, I had a simple function to initialize where the "mouse cursor black hole" was:

Func RotInit()
    MouseDown("right")
    sleep(100)
    Global $rotCenter = MouseGetPos()
    MouseUp("right")
EndFuncoÝ÷ Ø Ý"Ø^ëvØZ¶"Ö¬¶¢+bjZh{_¢¹²rXÚÚmz¶­ìjëh×6Func Rotate($delta, $speed)
    MouseClickDrag("right",$rotCenter[0],$rotCenter[1],$rotCenter[0]+$delta,$rotCenter[1], $speed)
EndFuncoÝ÷ اr[yÖ¬¥ç¥ªÚë^­·jëz÷§¶.aË^râªç9×hzÉè·
+#HÔËahZ´jvò¶­È§¶ jg­æ¦¢éíÊ«¢Ö­z+0eÊ)Ýz§uéí¡øhÁö¬·*.®j.±é¨½ë"¶+(}÷µç[Ê0b¶j/zÅ¡jÖ©¥æ«²Ú!j^­«­¢+]¢)ඬ¶.¬¶­¶}÷¶Ê¶¬ªê-¬yË«²Û§$^ªê-j·¬¶)e¦·¬z{ZØ­ßÛj,µø اØ^¦éeJÊ'$v¶ Â+aj÷«Éö¬¶Ê^yÖ§vØ^ÚòÜ"¶¦¹Èl®Ê^yÖî¶ë¶¬jg¯j[~ôߧ^Ö²¢ì"X·¥v÷Þ­éí­ë.Û½éð)^ºÈ§§(ȬµéíÓ~¬¥ç½©nzØb0z·¬¶)e^­«^)èX§yªðéâµÆ¦zÚ-êÞ«b¢{!Þ·Múuémi©Ý®Z¶*'jj.Ò-êÞ~Þuç"uçm¢Ö¤y«®'¬¡ú赫b¢v§W¦y«.­éÛjÇ¡÷æ¢ø§Ø^¬y©ò«yúèKh×M)¥±©Ýv§ª®iÚÚ¶'Ûh¶jÖ´÷ßk²«­çoj[Á«-êÞ²émJ²r^iËnjYr$²Ê&zØb bëaÉèÁ«­¢+ÙÕ¹I½ÑÑ ÀÌØí¹Ý¤(ÀÌØíÕÉÉôÕÁÑ
½µÁÍÌ ¤íQ¡µ¡ÌȵѽÀµÙ¥Ü½µÁÍ̽¸Íɸ°Ñ¡¥Ìչѥ½¸¥ÌÍ¥¹Ñ¼­¹½Üݡɹ½ÉÑ ¥ÌÁ½Í¥Ñ¥½¹¹±Õ±ÑÉͽ¸Ñ¡Ð¸(¡½½Ì¡ÉÝ¡½ÍÁÕÉÁ½Í¥ÌѼ±Õ±ÑÑ¡ÅÕ¥­ÍÐ¥ÉÑ¥½¸¹µ½Õ¹ÐѼÑÉÙ°¸½ÈáµÁ±°¥$ݹÐѼ¼É½´ÄÀÉÌѼÌÔÀÉÌ°¤Ý½Õ±ÁÉÈ¥ÐѼ¼ÈÀÉ̽չÑɱ½­Ý¥Í°¹½ÐÌÐÀÉ̱½­Ý¥Í¤((¡½½Ì¡ÉѼ½¹ÙÉÐÑ¡Ðɥɹ¥¹Ñ¼¸µ½Õ¹Ð½Á¥á±Ì°ÕÍ¥¹Ñ¡ÉÉÍÍ¥½¸ÁÉÙ¥½ÕͱäÙ±½Á¤(I½ÑÑ ÀÌØíÉÉÍÍ¥½¹½ÕÑÁÕаÀÌØíÍÁå½Õ¥å½ÕÉÉÉÍÍ¥½¹Ð¤)¹Õ¹

The thing still has a mild bit of variability to it, maybe +-2 degrees at maximum. But I can work with that.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Do you really need two functions to do that rotation thing?

Anyways, a question:

Does the mouse pointer move in-game when you hold down your right mouse button or something?

Or what else does:

Func RotInit()
    MouseDown("right")
    sleep(100)
    Global $rotCenter = MouseGetPos()
    MouseUp("right")
EndFuncoÝ÷ Ø:-«m+Þv¬ZºÚ"µÍ[H  ÌÍÜÝÙ[È]ÜÙØÜÝ]ÚYH[H[Ý[ÛÚ[HÛØ[
BÌÍÜÝÙ[H[ÝÙQÙ]ÜÊ
HÈÚ][ÝHYYÈ]HHÛØ[XX

Edit:

If you do not need that special function to 'initialize' the 'rotation variable', then I'd prefer to have only the Rotate() or RotateDeg() function by itself and use a local variable to get the mouse coords. :rolleyes:

Edited by FreeFry

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

It absolutely did! Basically, I had a simple function to initialize where the "mouse cursor black hole" was:

...code here...

The thing still has a mild bit of variability to it, maybe +-2 degrees at maximum. But I can work with that.

Nice work... I am assuming that you are playing with an "application" that has some inherent latency causing mouse movement dropouts or frame stutter (or something similar) yielding some variance in the results for a given operation which a human would easily compensate for, but which can greatly challenge a script / code. Any deviance from what was expected or coded for can pose a number of potential failure points and therefore it would require coding to recognize and compensate in such instances in order to produce somewhat predictable results thereby maintaining reasonable accuracy of automation. If you are able to successfully navigate from point A to point B covering anything more that a very short distance, that would be a nice bit of coding... :rolleyes: Perhaps when you are able to get a sample subset working you could share any workarounds to such challenges in this thread (or wherever appropriate).

I am curious about something you mentioned: So the app is graphic in nature and has a compass display that you are using to determine direction. If I may ask, what tool or set of tools are you using to evaluate the 2D compass graphic to make your determination on how much to rotate? I see very limited native graphic functions within Autoit, so I am assuming that you are using something that you are perhaps calling (i.e. a com or dll, etc...).

Again, thanks for sharing...

izy

Edited by izy

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Do you really need two functions to do that rotation thing?

Anyways, a question:

Does the mouse pointer move in-game when you hold down your right mouse button or something?

Or what else does:

Func RotInit()
    MouseDown("right")
    sleep(100)
    Global $rotCenter = MouseGetPos()
    MouseUp("right")
EndFuncƒoÝŠ÷ Ø:-…«m†+–‰Þv‡¬ž‹ZºÚ"µÍ‘[H   ˆÌÍŽÜ›ÝÙ[ˆÈ]ÜÙˆØÜšÝ]ÚYH[žH[˜Ý[ÛŠÚ[™HÛؘ[
B‚‰ˆÌÍŽÜ›ÝÙ[ˆH[ÝÙQÙ]ÜÊ
HÈÚ™]™ˆ[ÝH™YYÈ]HHÛؘ[˜šXX›

Edit:

If you do not need that special function to 'initialize' the 'rotation variable', then I'd prefer to have only the Rotate() or RotateDeg() function by itself and use a local variable to get the mouse coords. :rolleyes:

Yeah, it's a bit quirky but the way it works is (I've verified this by doing some MouseGetPos logging) no matter where your mouse cursor is appearing on-screen, the minute you click or hold down the right mouse button, the cursor will disappear from view, and the new position of this invisible cursor will be at the center of your screen resolution. The reason I have the small initialize function is to determine what this point is that the mouse always gets sucked to when you hold down the right button, because that point HAS to be where I start the drag operation or things go absolutely crazy (thousands of degree rotations, out of plane rotations that make me stare into the ground, etc.). Note that as soon as you let go of the mouse button, the cursor will be back to where you initially had it.

So as I have it working, the game will load, it'll hold down the mouse button for a second and record the point that it teleports to, and then use that point as the starting point of all the later click-drag rotation operations.

As far as your second question about whether to have separate functions or not, I can't really answer that except to say that I've got no programming training at all, so I'm not well versed in proper technique or etiquette. I just keep things in small chunks so that things are clearer for me what's going on. It's easier on my eyes to see a step that says Rotate($pixels, $speed) than to see MouseClickDrag("right",$rotCenter[0],$rotCenter[1],$rotCenter[0]+$delta,$rotCenter[1], $speed) heh.

Edited by Leighwyn

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Nice work... I am assuming that you are playing with an "application" that has some inherent latency causing mouse movement dropouts or frame stutter (or something similar) yielding some variance in the results for a given operation which a human would easily compensate for, but which can greatly challenge a script / code. Any deviance from what was expected or coded for can pose a number of potential failure points and therefore it would require coding to recognize and compensate in such instances in order to produce somewhat predictable results thereby maintaining reasonable accuracy of automation. If you are able to successfully navigate from point A to point B covering anything more that a very short distance, that would be a nice bit of coding... :x Perhaps when you are able to get a sample subset working you could share any workarounds to such challenges in this thread (or wherever appropriate).

I am curious about something you mentioned: So the app is graphic in nature and has a compass display that you are using to determine direction. If I may ask, what tool or set of tools are you using to evaluate the 2D compass graphic to make your determination on how much to rotate? I see very limited native graphic functions within Autoit, so I am assuming that you are using something that you are perhaps calling (i.e. a com or dll, etc...).

Again, thanks for sharing...

izy

The compass reader was a lot of code, I partnered up with a friend and fellow player of the game to help me out on it since he's an employed programmer and I'm more of a hobbyist/puzzle lover (that's the only reason I write these things, it's like an abstract puzzle to solve with a lot of satisfaction when things work well).

The first bit of code has the user define where the compass center is (it's marked on-screen so it first attempts to find it using a pixelgetcolor but if that fails, it provides a GUI with U D L R buttons so you can manually home in on it.

The second part has code to calculate coordinates which describe an aliased circle of radius R and center as defined above (I think it resulted in around 500 points total with the radius I required).

the third is a short function to calculate euclidian distance between two colors represented in hex, which is used below.

The compass has markings for the letters N S E W, and the area surrounding the N mark has a slightly more "goldish" tone to it than the other three, so the fourth part exploits this fact. It queries for pixel colors at every point of the circle, and uses the distance function mentioned above between those colors and the "goldish" color. These get stored in an array.

Part #5 (remember my reply to FireFly where I mentioned I like to keep my functions many in number and tiny in scope? lol) looks in this array of distances, and averages the index values of any entry that is within a specified tolerance. This average value is then assumed to be where North is on the compass.

It's then a simple ratio based off how many total values are in the array, and what the average index was, to calculate what degree North is sitting at.

so the updateCircle() function looks at the current colors of the circle of points, does the distance and tolerance check to find out at what degree north is, and returns the result. It's all not that very intensive for the PC to do. The update takes an imperceptible amount of time, at least on a machine not running Vista. The PixelGetColor() function is FUBAR with Vista Aero enabled and causes this to go from imperceptible time, to 15 seconds required. Which obviously doesn't work :rambo:

The most complicated code for the whole operation is what my friend wrote to calculate a pixelated circle's coordinates, but the hardest part was identifying a unique feature that could let AutoIt do its thing.

About your question of latency error elimination, I've done some thought on the matter earlier in this project. Honestly, as things are now my code can perform a sequence that runs a full 3.5 minutes and has at least 10 separate rotation calls, but never fails an attempt at doing what it's meant to do. For that reason, I probably won't incorporate anything into it in terms of a feedback mechanism or periodic correction. What I would have used, though, was the fact that while the result of a rotation is somewhat random (+-2 degrees), the compass reader is 100% accurate. What this means is even if I told it to rotate to 320 degrees and it didn't quite make it there, I know exactly how far off I am. If, once facing 320 degrees, I wanted it to "run forward for 20 seconds" and instead it runs for 20 seconds at 317 degrees, you would at least know exactly where it should have gone and exactly where it went. It's just some simple math to calculate what vector you should take (and for how long) to get back on track.

The other alternative is to incorporate a feedback loop into the function...something that commands a rotation, checks where it ended up, commands a new rotation for the delta amount, etc. until within acceptable tolerance. I'm not sure this would work in my specific application because it would require very small degree rotations, and those themselves are pretty noisy for this game/script.

As a final note, I'm not too sure that the randomness experienced in this particular game is due to unavoidable act-of-god lags or frame drops. It almost feels purposefully included to thwart these kinds of scripts. There actually is a keyboard command to rotate, but a single quick press of the button can result in anywhere from a fraction of a degree in rotation to 10 or even 20 degrees of it. Holding and then releasing the key also is a random result due to what I'd called "rotation momentum", where your character doesn't simply come to a halt when you let go, but slowly trails off to nothing over the course of maybe half a second. The amount of time that this happens for is ALSO random. These reasons are exactly why I wouldn't even consider keyboard control an option for rotating.

I wouldn't mind posting some code in the other forum here from the guts of the compass reader, but I'd have to ask permission from the other guy in my duo, and it probably would be a modified version of it in case of the random chance that there are some company spies on the forum :rolleyes:

Edited by Leighwyn

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

The compass reader was a lot of code, I partnered up with a friend and fellow player of the game to help me out on it since he's an employed programmer and I'm more of a hobbyist/puzzle lover (that's the only reason I write these things, it's like an abstract puzzle to solve with a lot of satisfaction when things work well).

....

I wouldn't mind posting some code in the other forum here from the guts of the compass reader, but I'd have to ask permission from the other guy in my duo, and it probably would be a modified version of it in case of the random chance that there are some company spies on the forum :rolleyes:

Nice description, sounds like you have some time invested in tinkering with this to get it working. I have really just started tinkering with some automation of an application that I would like to be able to control. I have some things working, but others I have just been collecting ideas and going through the proof of concept stage. I got inspired by this discussion, and have been able to implement the click-drag to spin the rotation, but now I need to be able to determine the orientation and match it up to a desired direction. You description sounds much like what I had anticipated being a good approach, but obviously you are much further along (working prototype / tweak and tune stage) compared to where I am (proof of concept for individual functionality requirements).

If the other half of your dynamic duo agrees, I would greatly appreciate being able to review your code, even if it is only the base functions and a skeletal driving routine. If you prefer, you could email me directly instead of posting in a public forum, but either would be more then expected actually. Even if it does not work out to share more then what you have already posted, I really appreciate the detail description of the process and your quick response to questions...

Cheers,

izy

Edited by izy

Share this post


Link to post
Share on other sites

btw. (this question should have come earlier) what game is this you're talking about?

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

btw. (this question should have come earlier) what game is this you're talking about?

Oops, I didn't realize I kept referring to it without ever actually stating it! It's for Guild Wars. I've been playing the game to the point that it's not really interesting to me anymore, and this is a way for me to revitalize my interest in the game. It's professed as a grind-free game, but there ARE still grind elements that have been introduced and this script is meant to perform one of them. I rarely interact with the game community or economy, so whatever personal gain I make from its use doesn't morally bother me :rolleyes: It's really just a hobbyist side project in the vein of "This seems like a really tough problem, I wonder if I could do it?".

Edited by Leighwyn

Share this post


Link to post
Share on other sites

Hehe yes, sorry, I just wondered if it was something that I could try out, but as I don't believe in paying a constant money to be able to play a game, I can not.

I hope you can overcome that 'balance' issue, and get it working as perfectly as possible. Good Luck :rolleyes:

Share this post


Link to post
Share on other sites

Hehe yes, sorry, I just wondered if it was something that I could try out, but as I don't believe in paying a constant money to be able to play a game, I can not.

I hope you can overcome that 'balance' issue, and get it working as perfectly as possible. Good Luck :rolleyes:

guild wars is actually free to play once you pay your sunk cost by buying the game, no monthly fee at all :-)

I agree with you in not wanting to pay monthly for a game, so I've never played any other online RPG besides the diablo series. As for the script, it's running almost perfectly but I do have a few kinks that need ironing. Thanks again for your advice :rambo: 90% effective is much better than 0% and unfinished!

Share this post


Link to post
Share on other sites

Oh, I didn't know that. :rolleyes: Maybe I'll have a try at that game. :rambo:

Share this post


Link to post
Share on other sites

Oops, I didn't realize I kept referring to it without ever actually stating it! It's for Guild Wars. I've been playing the game to the point that it's not really interesting to me anymore, and this is a way for me to revitalize my interest in the game. It's professed as a grind-free game, but there ARE still grind elements that have been introduced and this script is meant to perform one of them. I rarely interact with the game community or economy, so whatever personal gain I make from its use doesn't morally bother me :whistle: It's really just a hobbyist side project in the vein of "This seems like a really tough problem, I wonder if I could do it?".

Still curious if you might be able to share some more of this code. I am very interested in how you implemented the process of determining direction from the compass and then moving in a given direction for a predictable distance.

Cheer,

izy

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0