Face Character Towards Mouse

Ask gaming related questions (AHK v1.1 and older)
lp230889
Posts: 16
Joined: 06 May 2016, 05:49

Face Character Towards Mouse

14 Dec 2017, 06:45

Hi

I need a little help with this part of my code, it works but not as well as i'd like.
It seems to get confused which way to face the close to the center the mouse gets.

Code: Select all

	global charCenterX := 965
	global charCenterY := 458
	
	AreaSpell(spell)
	{
		workingArea := 300
		deadZone := 50
		MouseGetPos, nowX, nowY

		;Top Left
		if (nowY < (charCenterY - deadZone)  && (nowX > (charCenterX - workingArea))  && (nowX < (charCenterX + workingArea)) )
		{
			Send +{Up}
			RandomSleep(50,100)
			Send, % spell
		}
		else if (nowX < (charCenterX - deadZone) && (nowY > (charCenterY - workingArea))  && (nowY < (charCenterY + workingArea)) )
		{
			Send +{Left}
			RandomSleep(50,100)
			Send, % spell
		}
	
		;BottomRight
		if (nowY > (charCenterY + deadZone) && (nowX > (charCenterX - workingArea))  && (nowX < (charCenterX + workingArea)) )
		{
			Send +{Down}
			RandomSleep(50,100)
			Send, % spell
		}
		else if (nowX > (charCenterX + deadZone) && (nowY > (charCenterY - workingArea))  && (nowY < (charCenterY + workingArea)) )
		{
			Send +{Right}
			RandomSleep(50,100)
			Send, % spell
		}
	}
Example:
Attachments
example.png
example.png (3.69 KiB) Viewed 788 times
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Face Character Towards Mouse

14 Dec 2017, 08:17

I can't test your code. But I can give a tip: (might not help though)

I would make the code more readable to humans. The interpreter will not struggle because of it, it is fine either way.
The maintainer of the code will struggle more to understand one way than the other way.

E.g.: I changed the longest line to something like this:

Code: Select all

		if ( nowY < charCenterY - deadZone    )
        && ( nowX > charCenterX - workingArea )
        && ( nowX < charCenterX + workingArea )
		{
                ; blah blah
		}
I then noticed your code does not handle all cases.
Maybe if you handle all cases it would be fixed? I have no idea. Your code is not testable for me.
lp230889
Posts: 16
Joined: 06 May 2016, 05:49

Re: Face Character Towards Mouse

14 Dec 2017, 09:03

Hi thanks for advice, i'll keep it in mind.

I fixed the code on my own using angles instead, works great now

Code: Select all

	AreaSpell(spell)
	{
		MouseGetPos, nowX, nowY		
		mouseAngle := dllcall("msvcrt\atan2","Double",nowY - charCenterY, "Double",nowX - charCenterX, "CDECL Double") * 360 / (3.1415925635 * 2)
		
		if (mouseAngle < 0)
		{
			mouseAngle += 360
		}
		if (mouseAngle >= 45 && mouseAngle <= 135)
		{
			Send +{Down}
			RandomSleep(50,100)
			Send, % spell
		}
		else if (mouseAngle >= 135 && mouseAngle <= 225)
		{
			Send +{Left}
			RandomSleep(50,100)
			Send, % spell
		}
		else if  (mouseAngle >= 225 && mouseAngle <= 305)
		{
			Send +{Up}
			RandomSleep(50,100)
			Send, % spell
		}
		else if (mouseAngle >= 305 && mouseAngle <= 359)
		|| (mouseAngle >= 01 &&  mouseAngle <= 25)
		{
			Send +{Right}
			RandomSleep(50,100)
			Send, % spell
		}
	}
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Face Character Towards Mouse

15 Dec 2017, 09:44

When working with angles like this, esp if you want it to wrap around, you can get sneaky.

Round(angle / 90) will give you a "Cardinal" (Pure North, South, East or West). It still wraps around, but it is a simple check you need to make anyway.
Also, it appears as if the game is isometric display or something, but in that case, just shift the angle around before you make your wrap-around adjustments, and then you will be dealing with cardinals, again making it easier.

for example:

Code: Select all

#SingleInstance force
Gui, Add, Edit, xm w100 vdummyAngle gAngleChanged
Gui, Add, Text, xm w100 vOutput
Gui, Show, x0 y0
return

GuiClose:
	ExitApp

AngleChanged:
	Gui, Submit, NoHide
	AreaSpell()
	return

AreaSpell(){
	;MouseGetPos, nowX, nowY		
	;mouseAngle := dllcall("msvcrt\atan2","Double",nowY - charCenterY, "Double",nowX - charCenterX, "CDECL Double") * 360 / (3.1415925635 * 2)
	global dummyAngle
	mouseAngle := dummyAngle + 90 ; Rotate angle round so we are dealing with cardinals not diagonals
	if (mouseAngle < 0)	; Handle negative wrap-around
	{
		mouseAngle += 360
	}
	mouseAngle := Round(mouseAngle / 90) + 1 ; Reduce angle down to one of 4 cardinals 1...4
	if (mouseAngle > 4)	; Handle positive wrap-around
	{
		mouseAngle -= 4
	}
	; Check angle
	if (mouseAngle = 1)
	{
		SetOutput("UP")
	}
	else if (mouseAngle = 2)
	{
		SetOutput("RIGHT")
	}
	else if  (mouseAngle = 3)
	{
		SetOutput("DOWN")
	}
	else if (mouseAngle = 4)
	{
		SetOutput("LEFT")
	}
	else
	{
		SetOutput("NONE")
	}
}

SetOutput(value){
	global Output
	GuiControl, , Output, % value
}
Also, note that if you can reduce the angle down to integers, you can then also avoid if/else blocks by using an array of functions:

Code: Select all

Funcs := [Func("DoThingOne"), Func("DoThingTwo")]
whichFunc := 1
paramToPass := 999
; Call the first function with the parameter 999
Funcs[whichFunc].Call(paramToPass)
return

DoThingOne(param){
	msgbox %A_ThisFunc% called with param %param%
}

DoThingTwo(param){
	msgbox %A_ThisFunc% called with param %param%
}
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Face Character Towards Mouse

15 Dec 2017, 09:54

Or, if all your directions do basically the same thing, but with parameters, you could do like this:

Code: Select all

#SingleInstance force
; Build array of "Bound Functions" (Functions with parameters pre-supplied)
Funcs := [Func("DoAction").Bind("+{Up}", 50, 100, 1), Func("DoAction").Bind("+{Right}", 50, 100, 2)
	, Func("DoAction").Bind("+{Down}", 50, 100, 3), Func("DoAction").Bind("+{Left}", 50, 100, 4)]
Gui, Add, Edit, xm w100 vdummyAngle gAngleChanged
Gui, Add, Text, xm w100 vOutput
Gui, Show, x0 y0
return

GuiClose:
	ExitApp

AngleChanged:
	Gui, Submit, NoHide
	AreaSpell()
	return

AreaSpell(){
	;MouseGetPos, nowX, nowY		
	;mouseAngle := dllcall("msvcrt\atan2","Double",nowY - charCenterY, "Double",nowX - charCenterX, "CDECL Double") * 360 / (3.1415925635 * 2)
	global dummyAngle, Funcs
	mouseAngle := dummyAngle + 90 ; Rotate angle round so we are dealing with cardinals not diagonals
	if (mouseAngle < 0)	; Handle negative wrap-around
	{
		mouseAngle += 360
	}
	mouseAngle := Round(mouseAngle / 90) + 1 ; Reduce angle down to one of 4 cardinals 1...4
	if (mouseAngle > 4)	; Handle positive wrap-around
	{
		mouseAngle -= 4
	}
	Funcs[mouseAngle].Call()
}

DoAction(keys, sleepMin, SleepMax, spell){
	Send % keys
	RandomSleep(sleepMin, SleepMax)
	Send, % spell
}

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 62 guests