Beginner looking for assistance with key spam script.

Ask gaming related questions (AHK v1.1 and older)
Jethred
Posts: 1
Joined: 17 Feb 2018, 04:19

Beginner looking for assistance with key spam script.

17 Feb 2018, 04:38

Hello,

I'm a complete scripting newbie, and I am trying to use AHK to improve my experience playing MMO games. Spamming abilities constantly (which is pretty much required in the particular game I play) is pretty hard on my hands so I'd like to see if AHK can do the spamming for me. There are several topics on this scattered throughout various message boards, and I found a script that I like very much, courtesy of Angrybear: Link

However, I need to make a few modifications to it, and this is where I'm stuck. After hours of trying, I haven't been very successful, and I was wondering if one of you could help me out.

Here is what I have currently:

Code: Select all

keys = 1,2,3,4,5,6,7,8,9,0,-,=,~^4,~^5,~^6 ; key-names/scan-codes to accelarate
Loop Parse, keys, `,
Hotkey *%A_LoopField%, KEY
Return

KEY:
StringTrimLeft key, A_ThisHotKey, 1
t := 0.1 ; initial delay [seconds]
Loop {
SendInput {BLIND}{%key%}
KeyWait %key%, T%t%
If ErrorLevel = 0
Break
t := 0.1 ; delay *= 1, while delay > 0.2
}
Note: I don't want ^4, ^5, ^6 to repeat, hence the additions to the keys list up top

I would like to change the script as such:
When a modifier key is pressed or released, the repeating is interupted and nothing happens until I press one of the keys listed on top.

This change would allow me to avoid accidental inputs when using an ability that is bound to the ctrl, shift, or alt layer.
(Currently, if I use an ability that's on the Shift+3 keybind, and I release Shift slightly earlier than 3, I will also queue up the ability on the 3 keybind -
while it isn't an impossible problem to navigate, but one I'd very much like to avoid.)

Any ideas?

EDIT: I was able to get what I wanted with a different script. It's pretty clunky though; I can't have it spam very fast without glitching, so I'm still interested in a more elegant way to do this.

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

; Simple key spam script by Winsane @ ownedcore, edited by Jethred. 
; Toggle on and off with numlock.

~Pause::Suspend, Toggle

~Shift up::
{
KeyWait 1
KeyWait 2
KeyWait 3
KeyWait 4
KeyWait 5
KeyWait 6
KeyWait 7
KeyWait 8
KeyWait 9
KeyWait 0
KeyWait -
KeyWait = 
}

~Shift::
{
KeyWait 1
KeyWait 2
KeyWait 3
KeyWait 4
KeyWait 5
KeyWait 6
KeyWait 7
KeyWait 8
KeyWait 9
KeyWait 0
KeyWait -
KeyWait = 
}

~Ctrl up::
{
KeyWait 1
KeyWait 2
KeyWait 3
KeyWait 4
KeyWait 5
KeyWait 6
KeyWait 7
KeyWait 8
KeyWait 9
KeyWait 0
KeyWait -
KeyWait = 
}

~Ctrl::
{
KeyWait 1
KeyWait 2
KeyWait 3
KeyWait 4
KeyWait 5
KeyWait 6
KeyWait 7
KeyWait 8
KeyWait 9
KeyWait 0
KeyWait -
KeyWait = 
}

~Alt up::
{
KeyWait 1
KeyWait 2
KeyWait 3
KeyWait 4
KeyWait 5
KeyWait 6
KeyWait 7
KeyWait 8
KeyWait 9
KeyWait 0
KeyWait -
KeyWait = 
}

~Alt::
{
KeyWait 1
KeyWait 2
KeyWait 3
KeyWait 4
KeyWait 5
KeyWait 6
KeyWait 7
KeyWait 8
KeyWait 9
KeyWait 0
KeyWait -
KeyWait = 
}

~^4::KeyWait 4

~^5::KeyWait 5

~^6::KeyWait 6

*1::
Loop
{
GetKeyState, state, 1, p
if state = U
break
; Otherwise:
Send, {BLIND}{1}
Sleep, 100
}

*2::
Loop
{
GetKeyState, state, 2, p
if state = U
break
; Otherwise:
Send, {BLIND}{2}
Sleep, 100
}

*3::
Loop
{
GetKeyState, state, 3, p
if state = U
break
; Otherwise:
Send, {BLIND}{3}
Sleep, 100
}

*4::
Loop
{
GetKeyState, state, 4, p
if state = U
break
; Otherwise:
Send, {BLIND}{4}
Sleep, 100
}

*5::
Loop
{
GetKeyState, state, 5, p
if state = U
break
; Otherwise:
Send, {BLIND}{5}
Sleep, 100
}

*6::
Loop
{
GetKeyState, state, 6, p
if state = U
break
; Otherwise:
Send, {BLIND}{6}
Sleep, 100
}

*7::
Loop
{
GetKeyState, state, 7, p
if state = U
break
; Otherwise:
Send, {BLIND}{7}
Sleep, 100
}

*8::
Loop
{
GetKeyState, state, 8, p
if state = U
break
; Otherwise:
Send, {BLIND}{8}
Sleep, 100
}

*9::
Loop
{
GetKeyState, state, 9, p
if state = U
break
; Otherwise:
Send, {BLIND}{9}
Sleep, 100
}

*0::
Loop
{
GetKeyState, state, 0, p
if state = U
break
; Otherwise:
Send, {BLIND}{0}
Sleep, 100
}

*-::
Loop
{
GetKeyState, state, -, p
if state = U
break
; Otherwise:
Send, {BLIND}{-}
Sleep, 100
}

*=::
Loop
{
GetKeyState, state, =, p
if state = U
break
; Otherwise:
Send, {BLIND}{=}
Sleep, 100
}
EDIT2: Problem resolved after much, much trial and error. I had to add timers to avoid key state issues with the gamepad I use. I think this is a superior keys spammer, feel free to use and modify the code however you want.

Code: Select all

#NoEnv
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
ListLines Off
Process, Priority, , H
SetBatchLines, -1
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
SendMode Input

SetTimer, WatchAxis, 5
SetTimer, WatchJoy5, 5
keys = 1,2,3,4,5,6,7,8,9,0,= ; key-names/scan-codes to accelarate
Loop Parse, keys, `,
Hotkey *%A_LoopField%, KEY
return

KEY:
StringTrimLeft key, A_ThisHotKey, 1
t := 0.1 ; initial delay [seconds]
ctrlkey := GetKeyState("Ctrl")
shiftkey := GetKeyState("Shift")
altkey := GetKeyState("Alt")

if shiftkey {
	while shiftkey {
		Send +{BLIND}{%key%}
		KeyWait %key%, T%t%
		If ErrorLevel = 0
		Break
		t := 0.1 ; delay *= 1, while delay > 0.2
		shiftkey := GetKeyState("Shift")
	} 
	KeyWait %key%
	return
}

else if ctrlkey {
	while ctrlkey {
		if ((GetKeyState("4", "P")) || (GetKeyState("5", "P")) || GetKeyState("6", "P")) {
			Send ^{BLIND}{%key%}
			Break
			}
		Send ^{BLIND}{%key%}
		KeyWait %key%, T%t%
		If ErrorLevel = 0
		Break
		t := 0.1 ; delay *= 1, while delay > 0.2
		ctrlkey := GetKeyState("Ctrl")
	}	 
	KeyWait %key%
	return
}

else if altkey {
	while altkey {
		Send !{BLIND}{%key%}
		KeyWait %key%, T%t%
		If ErrorLevel = 0
		Break
		t := 0.1 ; delay *= 1, while delay > 0.2
		altkey := GetKeyState("Alt")
		} 
	KeyWait %key%
	return
}

else if not (shiftkey || altkey || ctrlkey) {
	while not (shiftkey || altkey || ctrlkey) {
		Send {BLIND}{%key%}
		KeyWait %key%, T%t%
		If ErrorLevel = 0
		Break
		t := 0.1 ; delay *= 1, while delay > 0.2
		shiftkey := GetKeyState("Shift")
		ctrlkey := GetKeyState("Ctrl")
		altkey := GetKeyState("Alt")
	}

		KeyWait %key%
		return
}
return


WatchAxis:
GetKeyState, POV, JoyPOV ; Get position of the POV control.
GetKeyState,  zaxis, JoyZ
KeyToHoldDownPrev = %KeyToHoldDown%  ; Prev now holds the key that was down before (if any).

; Some joysticks might have a smooth/continous POV rather than one in fixed increments.
; To support them all, use a range:
if POV < 0   ; No angle to report
    KeyToHoldDown =
else if  POV between 0 and 4501 
	KeyToHoldDown = Alt
else if POV >31499
	KeyToHoldDown = Alt
else                               
    KeyToHoldDown =
if zaxis = 100
	KeyToHoldDown = Shift 
if KeyToHoldDown = %KeyToHoldDownPrev%  ; The correct key is already down (or no key is needed).
    return  ; Do nothing.

; Otherwise, release the previous key and press down the new key:
SetKeyDelay -1  ; Avoid delays between keystrokes.
if KeyToHoldDownPrev   ; There is a previous key to release.
    Send, {%KeyToHoldDownPrev% up}  ; Release it.
if KeyToHoldDown   ; There is a key to press down.
    Send, {%KeyToHoldDown% down}  ; Press it down.
return


WatchJoy5:
GetKeyState, joy5, joy5
KeyToHoldDownPrev2 = %KeyToHoldDown2%  ; Prev now holds the key that was down before (if any).

if joy5 = U   ; No angle to report
    KeyToHoldDown2 =
else
	KeyToHoldDown2 = Ctrl
if KeyToHoldDown2 = %KeyToHoldDownPrev2%  ; The correct key is already down (or no key is needed).
    return  ; Do nothing.

; Otherwise, release the previous key and press down the new key:
SetKeyDelay -1  ; Avoid delays between keystrokes.
if KeyToHoldDownPrev2   ; There is a previous key to release.
    Send, {%KeyToHoldDownPrev2% up}  ; Release it.
if KeyToHoldDown2   ; There is a key to press down.
    Send, {%KeyToHoldDown2% down}  ; Press it down.
return


Note: the timers are necessary for this code to work without issues. While I used them as a way to incorporate my input scheme, they should also be used on the keyboard keys should you be using them.

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 64 guests