Help writing a parry script

Ask gaming related questions (AHK v1.1 and older)
Raiden96
Posts: 38
Joined: 23 Oct 2021, 07:03

Help writing a parry script

Post by Raiden96 » 02 Sep 2022, 10:46

As the title says, i'm trying to write a parry script for the surge 2.

Code: Select all

surge2 = ahk_exe TheSurge2.exe

F2::
Suspend, Toggle
Soundbeep, 300, 500
Return

#If WinActive(surge2) && A_IsSuspended
F2::
Suspend, Off
Soundbeep, 700, 300
Return

#If WinActive(surge2)

While GetKeyState("F", "P")
W::
While GetKeyState("W", "P")
MouseMove, 0, -50, 10, R
Return

S::
While GetKeyState("W", "P")
MouseMove, 0, -50, 10, R
Return

A::
While GetKeyState("W", "P")
MouseMove, 0, -50, 10, R
Return

D::
While GetKeyState("W", "P")
MouseMove, 0, -50, 10, R
Return
Return
[Mod edit: Changed quote-tags to [code][/code] tags.]

The way parrying in this game works is by holding down the block key (F) then moving the mouse in the direction of the attack at the last fraction of second to parry it. I just want to use the WASD instead of the mouse because it's painful and annoying and i figured the best way to achieve this is by having WASD take the role of the mouse in this instance since it would be easier.
Also, once i let go of the block key (F) i want to be able to use the WASD for normal movement.

As long as i hold down F i want to be able to hold down W A S or D for instance 5 times and have the mouse move to the specified location 5 times and not enter an infinite loop after i let go of the key which happens to be the case right now.

Thanks in advance!

Raiden96
Posts: 38
Joined: 23 Oct 2021, 07:03

Re: Help writing a parry script

Post by Raiden96 » 04 Sep 2022, 10:11

Anyone?

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Help writing a parry script

Post by t3h m00kz » 07 Sep 2022, 01:39

try this

Code: Select all

GLOBAL isHoldingF := "0"	;The player is holding the F key

F5:: ;F5 to reload script
	send {F5}
	reload
	return

*$~F:: ;F pressed
	isHoldingF := "1"
	return
*$~F Up:: ;F released
	isHoldingF := "0"
	return

*$~W::
*$~S::
*$~A::
*$~D::				;for W, A, S, and D,
	if isHoldingF{	;if the player is holding F,
		goSub Parry	;go to the Parry subroutine label
		}
	return

Parry: ;Parry subroutine
	{
	MouseMove, 0, -50, 10, R
	return
	}

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Help writing a parry script

Post by t3h m00kz » 07 Sep 2022, 02:07

Alternatively, if you need the WASD keys suppressed while you're holding F, try this.

Code: Select all

GLOBAL isHoldingF := "0"	;The player is holding the F key

F5:: ;F5 to reload script
	send {F5}
	reload
	return

*$~F:: ;F pressed
	isHoldingF := "1"
	return
*$~F Up:: ;F released
	isHoldingF := "0"
	return

$W::
	if isHoldingF{
		goSub Parry
		}
	else if !isHoldingF{
		send {w}
		}
	return

$S::
	if isHoldingF{
		goSub Parry
		}
	else if !isHoldingF{
		send {s}
		}
	return

$A::
	if isHoldingF{
		goSub Parry
		}
	else if !isHoldingF{
		send {a}
		}
	return

$D::
	if isHoldingF{
		goSub Parry
		}
	else if !isHoldingF{
		send {d}
		}
	return

Parry: ;Parry subroutine
	{
	MouseMove, 0, -50, 10, R
	return
	}

Raiden96
Posts: 38
Joined: 23 Oct 2021, 07:03

Re: Help writing a parry script

Post by Raiden96 » 07 Sep 2022, 03:02

Thanks for your input! I really appreciate it. After my work hours are over i'll give them a try and let you know how it went.

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Help writing a parry script

Post by t3h m00kz » 07 Sep 2022, 08:16

On second thought, after re-reading your request, I think I realized what you want. You want something that'll spam parry while you're holding down the directional buttons, correct?

if so, I built this up a bit to be a bit fancier, and to do what I THINK you're wanting.

Tested it briefly on my end and it works pretty flawlessly. I've added notes on what I'm doing. You generally want to use subroutine labels where you can in place of While and KeyWait, otherwise you risk locking up your script because lmao threading.

Code: Select all

global isHoldingF		:= "0"							;The player is holding the F key
global parryType		:= "None"						;The parry to execute
global framesPerSecond	:= "60"							;Game's FPS
global gameTick			:= ((1/framesPerSecond)*1000)	;One gametick / frame
global useTestBeep		:= "1"							;Enable test beeps

tick(t:="1"){							;Tick function.
	ticks := gameTick*t					;Set "Ticks" value to GameTicks times passed tick count value.
	return ticks						;Return the "Ticks value."
	}

testBeep(freq:="0", duration:="0"){		;Test beep function.
	if useTestBeep{						;If useTestBeeps variable is 1,
		Soundbeep, freq, duration		;Play a beep based on the passed frequency/duration values.
		}
	return
	}

F5::									;F5 press.
	send {F5}							;Sent vanilla F5 keystroke.
	reload								;Reload the script.
	return

*$~F::									;F press. (*$~ prefix)
	testBeep(1800, 15)					;Play the F Pressed beep.
	isHoldingF := "1"					;Set "IsHoldingF" check to true.
	return
*$~F Up::								;F release. (*$~ prefix)
	testBeep(900, 30)					;Play the F Released beep.
	isHoldingF := "0"					;Set "IsHoldingF" check to false.
	return

$W::									;W press. ($ prefix)
	if isHoldingF{						;If F is held,
		ParryType := "Up"				;Set parry type to "Up",
		goSub Parry						;Go to the parry subroutine.
		}
	else if !isHoldingF{				;Otherwise, if F is NOT held,
		send {w}						;Send vanilla "W" keystroke.
		}
	return

$A::
	if isHoldingF{						;A press. ($ prefix)
		parryType := "Left"             ;If F is held,
		goSub Parry                     ;Set parry type to "Left",
		}                               ;Go to the parry subroutine.
	else if !isHoldingF{                
		send {a}                        ;Otherwise, if F is NOT held,
		}                               ;Send vanilla "A" keystroke.
	return

$S::									;S press. ($ prefix)
	if isHoldingF{                      ;If F is held,
		parryType := "Down"             ;Set parry type to "Down",
		goSub Parry                     ;Go to the parry subroutine.
		}                               
	else if !isHoldingF{                ;Otherwise, if F is NOT held,
		send {s}                        ;Send vanilla "S" keystroke.
		}
	return

$D::									;D press. ($ prefix)
	if isHoldingF{                      ;If F is held,
		parryType := "Right"            ;Set parry type to "Right",
		goSub Parry                     ;Go to the parry subroutine.
		}                               
	else if !isHoldingF{                ;Otherwise, if F is NOT held,
		send {d}                        ;Send vanilla "D" keystroke.
		}
	return

$W up::
$S up::
$A up::
$D up::									;For W, S, A, and D releases,
	if isHoldingF{						;If F is held,
		testBeep(220, 30)				;Play key release beep.
		}
	parryType := "None"					;Unset the ParryType value.
	return

Parry:									;Parry subroutine
	{
	setTimer, Parry, off				;Disable the subroutine loop,
	if isHoldingF{						;If F is held,
		switch parryType{				;Look at the current ParryType value
			case "Up":					;For up,
				moveMouse(0, -50, 5)	;Move mouse up
			case "Down":				;For down,
				moveMouse(0, 50, 5)		;Move mouse down
			case "Left":				;For left,
				moveMouse(-50, 0, 5)	;Move mouse left
			case "Right":				;For right,
				moveMouse(50, 0, 5)		;Move mouse right
			case "None":				;For none,
				testBeep(300, 30)		;Play exit beep,
				setTimer, Parry, off	;Disable the loop
			default:					;Fallback,
				testBeep(150, 45)		;Play error beep,
				setTimer, Parry, off	;Disable the loop
			}
		}
	return
	}

moveMouse(X:="0",Y:="0",Duration:="0"){	;Move mouse function.
	testBeep(600, 15)					;Play mouse move beep,
	MouseMove, X, Y, Duration, R		;Move the mouse based on passed X/Y/Duration values,
	setTimer, Parry, % tick(2)			;Return to Parry subroutine in 2 ticks.
	return
	}

Raiden96
Posts: 38
Joined: 23 Oct 2021, 07:03

Re: Help writing a parry script

Post by Raiden96 » 07 Sep 2022, 10:11

t3h m00kz wrote:
07 Sep 2022, 01:39
try this

Code: Select all

GLOBAL isHoldingF := "0"	;The player is holding the F key

F5:: ;F5 to reload script
	send {F5}
	reload
	return

*$~F:: ;F pressed
	isHoldingF := "1"
	return
*$~F Up:: ;F released
	isHoldingF := "0"
	return

*$~W::
*$~S::
*$~A::
*$~D::				;for W, A, S, and D,
	if isHoldingF{	;if the player is holding F,
		goSub Parry	;go to the Parry subroutine label
		}
	return

Parry: ;Parry subroutine
	{
	MouseMove, 0, -50, 10, R
	return
	}
This one is closer to what i want. Except that i could do with a switch so i can actually parry in the direction of the attack. But sadly, i'm not proficient with autohotkey.

Code: Select all

MouseMove, -50, 0, 10, R - left - A
MouseMove, 0, 50, 10, R - down - S
MouseMove, 50, 0, 10, R - right - D
MouseMove, 0, -50, 10, R -up - W
These are the coordinates i want assigned to each to each key while holding the block key (F).
I apologize for forgetting to properly change the coordinates for each direction in the original script i posted.

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Help writing a parry script

Post by t3h m00kz » 07 Sep 2022, 11:05

all good, that last script revision I posted should cover that. I figured it was directional, give it a try

Raiden96
Posts: 38
Joined: 23 Oct 2021, 07:03

Re: Help writing a parry script

Post by Raiden96 » 07 Sep 2022, 11:30

t3h m00kz wrote:
07 Sep 2022, 11:05
all good, that last script revision I posted should cover that. I figured it was directional, give it a try
Thanks a lot! I think we're getting close. For some reason, i can't move while script is running. I don't understand why. Also what's the point of F5 (script reloading)?

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Help writing a parry script

Post by t3h m00kz » 07 Sep 2022, 18:10

F5 is a failsafe to restart the entire script in case i get stuck in an infinite loop. I include it in every script I build.

If you can't move at all, that's an issue. But if you can't move while holding F, that's because I built it to suppress the WASD keys while F is held, based on this part of your request:

"Also, once i let go of the block key (F) i want to be able to use the WASD for normal movement"

I've unsuppressed the keys here. The difference is the *$~ hotkey prefixes, which allow the keypress to both go through as well as send the Parry command

Code: Select all

global isHoldingF		:= "0"							;The player is holding the F key
global parryType		:= "None"						;The parry to execute
global framesPerSecond	:= "60"							;Game's FPS
global gameTick			:= ((1/framesPerSecond)*1000)	;One gametick / frame
global useTestBeep		:= "1"							;Enable test beeps

tick(t:="1"){							;Tick function.
	ticks := gameTick*t					;Set "Ticks" value to GameTicks times passed tick count value.
	return ticks						;Return the "Ticks value."
	}

testBeep(freq:="0", duration:="0"){		;Test beep function.
	if useTestBeep{						;If useTestBeeps variable is 1,
		Soundbeep, freq, duration		;Play a beep based on the passed frequency/duration values.
		}
	return
	}

F5::									;F5 press.
	send {F5}							;Sent vanilla F5 keystroke.
	reload								;Reload the script.
	return

*$~F::									;F press. (*$~ prefix)
	testBeep(1800, 15)					;Play the F Pressed beep.
	isHoldingF := "1"					;Set "IsHoldingF" check to true.
	return
*$~F Up::								;F release. (*$~ prefix)
	testBeep(900, 30)					;Play the F Released beep.
	isHoldingF := "0"					;Set "IsHoldingF" check to false.
	return

*$~W::									;W press. (*$~ prefix)
	if isHoldingF{						;If F is held,
		ParryType := "Up"				;Set parry type to "Up",
		goSub Parry						;Go to the parry subroutine.
		}
	return

*$~A::									;A press. (*$~ prefix)
	if isHoldingF{						;If F is held,
		parryType := "Left"             ;Set parry type to "Left",
		goSub Parry                     ;Go to the parry subroutine.
		}
	return

*$~S::									;S press. (*$~ prefix)
	if isHoldingF{                      ;If F is held,
		parryType := "Down"             ;Set parry type to "Down",
		goSub Parry                     ;Go to the parry subroutine.
		}                               
	return

*$~D::									;D press. (*$~ prefix)
	if isHoldingF{                      ;If F is held,
		parryType := "Right"            ;Set parry type to "Right",
		goSub Parry                     ;Go to the parry subroutine.
		}                               
	return

*$~W up::
*$~S up::
*$~A up::
*$~D up::								;For W, S, A, and D releases,
	if isHoldingF{						;If F is held,
		testBeep(220, 30)				;Play key release beep.
		}
	parryType := "None"					;Unset the ParryType value.
	return

Parry:									;Parry subroutine
	{
	setTimer, Parry, off				;Disable the subroutine loop,
	if isHoldingF{						;If F is held,
		switch parryType{				;Look at the current ParryType value
			case "Up":					;For up,
				moveMouse(0, -50, 5)	;Move mouse up
			case "Down":				;For down,
				moveMouse(0, 50, 5)		;Move mouse down
			case "Left":				;For left,
				moveMouse(-50, 0, 5)	;Move mouse left
			case "Right":				;For right,
				moveMouse(50, 0, 5)		;Move mouse right
			case "None":				;For none,
				testBeep(300, 30)		;Play exit beep,
				setTimer, Parry, off	;Disable the loop
			default:					;Fallback,
				testBeep(150, 45)		;Play error beep,
				setTimer, Parry, off	;Disable the loop
			}
		}
	return
	}

moveMouse(X:="0",Y:="0",Duration:="0"){	;Move mouse function.
	testBeep(600, 15)					;Play mouse move beep,
	MouseMove, X, Y, Duration, R		;Move the mouse based on passed X/Y/Duration values,
	setTimer, Parry, % tick(2)			;Return to Parry subroutine in 2 ticks.
	return
	}

Raiden96
Posts: 38
Joined: 23 Oct 2021, 07:03

Re: Help writing a parry script

Post by Raiden96 » 09 Sep 2022, 12:32

@t3h m00kz
I've tried the code you sent and sadly it doesn't work as intended.
1.Whether i hold or tap W it sends the first parry upwards. The subsequent ones are always down parrys for god knows what reason. Also if i hold W it gets messed up. Not to mention the character moves in the direction of pressed key which is not what i want. I want to be able to move as long as i'm not holding down F(block key).
2. Same goes for S. It sends the first one correctly then it goes parrying in reverse (uses the W parry for some reason).
3. Same thing for A and D. I can't make sense of this.

At first i thought of checking the method doing the mouse move but since autohotkey is not exactly my specialty i didn't find anything wrong with it.

Also, i'd prefer if at all possible to stand completely still while in blocking stance (F). If i press any key blocking stance i want to keep still. I also now realize that's what probably messes up the mouse move method. The character moving while parrying. If we can manage that then maybe this problem can be fixed in one go. At the very least i want cross the possibility off the list.

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Help writing a parry script

Post by t3h m00kz » 16 Sep 2022, 21:59

okay,

so you DO want keys suppressed, it sounds like.

I'm going to assume the parry direction issues may be timing, so I've also added a value you can tweak to narrow down the parry timing. Change "MouseDelay" at the very top to tweak the waits between parries.

Change the mouseDelay value if it's behaving oddly and see if that fixes things.

Code: Select all

;;;;;;;;;;;;;
;; OPTIONS ;;
;;;;;;;;;;;;;
global mouseDelay		:= "10"					;Delay between parries
global useTestBeep		:= "1"					;Enable test beeps

;;;;;;;;;;;;;;;;;;;;
;; SYSTEM GLOBALS ;;
;;;;;;;;;;;;;;;;;;;;
global isHoldingF		:= "0"					;The player is holding the F key
global parryType		:= "None"				;The parry to execute
global gameFPS			:= "60"					;Game's FPS
global gameTick			:= ((1/gameFPS)*1000)	;One gametick / frame

;;;;;;;;;;;;;;;
;; FUNCTIONS ;;
;;;;;;;;;;;;;;;
tick(t:="1"){							;; TICK FUNCTION ;;
	ticks := gameTick*t					;Set "Ticks" value to GameTicks times passed tick count value.
	return ticks						;Return the "Ticks value."
	}

testBeep(freq:="0", duration:="0"){		;; TEST BEEP FUNCTION ;;
	if useTestBeep{						;If useTestBeeps variable is 1,
		Soundbeep, freq, duration		;Play a beep based on the passed frequency/duration values.
		}
	return
	}

moveMouse(X:="0",Y:="0"){				;; MOVE MOUSE FUNCTION ;;
	testBeep(600, 15)					;Play mouse move beep,
	MouseMove, X, Y, mouseDelay, R		;Move the mouse based on passed X/Y/Duration values,
	setTimer, Parry, % tick(2)			;Return to Parry subroutine in 2 ticks.
	return
	}

Parry:									;; PARRY SUBROUTINE ;;
	{
	setTimer, Parry, off				;Disable the subroutine loop,
	if isHoldingF{						;If F is held,
		switch parryType{				;Look at the current ParryType value
			case "Up":					;For up,
				moveMouse(0, -50)		;Move mouse up
			case "Down":				;For down,
				moveMouse(0, 50)		;Move mouse down
			case "Left":				;For left,
				moveMouse(-50, 0)		;Move mouse left
			case "Right":				;For right,
				moveMouse(50, 0)		;Move mouse right
			case "None":				;For none,
				testBeep(300, 30)		;Play exit beep,
				setTimer, Parry, off	;Disable the loop
			default:					;Fallback,
				testBeep(150, 45)		;Play error beep,
				setTimer, Parry, off	;Disable the loop
			}
		}
	return
	}

;;;;;;;;;;;;;;
;; BINDINGS ;;
;;;;;;;;;;;;;;
F5::									;; F5 PRESS ;;
	send {F5}							;Sent vanilla F5 keystroke.
	reload								;Reload the script.
	return

$F::									;F PRESS ($ prefix) ;;
	if !isHoldingF{						;If "IsHoldingF" is false,
		testBeep(1800, 15)				;Play the F Pressed beep.
		isHoldingF := "1"				;Set "IsHoldingF" check to true.
		}
	return

*$~F Up::								;; F RELEASE (*$~ prefix) ;;
	testBeep(900, 30)					;Play the F Released beep.
	isHoldingF := "0"					;Set "IsHoldingF" check to false.
	return

$W::									;; W PRESS ($ prefix) ;;
	if isHoldingF{						;If F is held,
		ParryType := "Up"				;Set parry type to "Up",
		goSub Parry						;Go to the parry subroutine.
		}
	else if !isHoldingF{				;Otherwise, if F is NOT held,
		send {w}						;Send vanilla "W" keystroke.
		}
	return

$A::									;; A PRESS ($ prefix) ;;
	if isHoldingF{						;If F is held,
		parryType := "Left"				;Set parry type to "Left",
		goSub Parry						;Go to the parry subroutine.
		}
	else if !isHoldingF{				;Otherwise, if F is NOT held,
		send {a}						;Send vanilla "A" keystroke.
		}
	return

$S::									;; S PRESS ($ prefix) ;;
	if isHoldingF{						;If F is held,
		parryType := "Down"				;Set parry type to "Down",
		goSub Parry						;Go to the parry subroutine.
		}
	else if !isHoldingF{				;Otherwise, if F is NOT held,
		send {s}						;Send vanilla "S" keystroke.
		}		
	return

$D::									;; D PRESS ($ prefix) ;;
	if isHoldingF{						;If F is held,
		parryType := "Right"			;Set parry type to "Right",
		goSub Parry						;Go to the parry subroutine
		}                               
	else if !isHoldingF{				;Otherwise, if F is NOT held,
		send {d}						;Send vanilla "D" keystroke
		}
	return

*$~W up::
*$~S up::
*$~A up::
*$~D up::								;; W, S, A, D RELEASES ;;
	if isHoldingF{						;If F is held,
		testBeep(220, 30)				;Play key release beep.
		}
	parryType := "None"					;Unset the ParryType value.
	return
I've restructured things to be a bit less jarring to read.

Raiden96
Posts: 38
Joined: 23 Oct 2021, 07:03

Re: Help writing a parry script

Post by Raiden96 » 18 Sep 2022, 07:11

Thanks, I'll check it out and let you know how it went.

Post Reply

Return to “Gaming Help (v1)”