0
votes

I'm trying to create hotkeys to simulate input buffering in an online game I'm playing which doesn't natively support input buffering, meaning mashing a spell key so that it goes off after the previous spell is finished casting is the best method to manually do.

With the help of a hotkey I can loop the key press with minimal delay by holding down my key so that it sends the instant I'm done casting the previous spell.

However creating multiple hotkeys for each button I have bound on my keyboard to a spell seems tedious and I'm not sure how to condense these hotkeys into one using an array of defined keys (ie. 1 through 6, and F1 through F6)

An example snippet of my code so far with only 3 keys taken into account:

$5::
{
    Loop
    {
        Loop, 5
        {
            Send, 5
            Sleep, 1
        }
        GetKeyState, state, 5
        if state = U
            break
    }
    return
}

$2::
{
    Loop
    {
        Loop, 5
        {
            Send, 2
            Sleep, 1
        }
        GetKeyState, state, 2
        if state = U
            break
    }
    return
}

$F2::
{
    Loop
    {
        Loop, 5
        {
            Send, {F2}
            Sleep, 1
        }
        GetKeyState, state, F2
        if state = U
            break
    }
    return
}

I'm trying to condense it to something like this, if possible:

hotkeys := [5, 2, F2]
hotkeyCount := hotkeys.MaxIndex()
curKey := 1

Loop, hotkeyCount
{
    hotkeyIndex := hotkeys[curKey]
    $%hotkeyIndex%::
    {
        Loop
        {
            Loop, 5
            {
                Send, {%hotkeyIndex%}
                Sleep, 1
            }
            GetKeyState, state, %hotkeyIndex%
            if state = U
                break
        }
        return
    }
    curKey := curKey + 1
}
1

1 Answers

1
votes

Create a FIFO stack that will safe the preset actions and call them when they are ready.

Array functions contains the functions: Function_a, Function_b, Function_c, that are triggered with their respective hotkeys, a, b, c. The hotkeys don't call the functions directly, but add their numerical index the to the stack stack.

The timer check, retrieves the numerical index from the stack, then the function from the array functions at that index is called. When the function returns, the next index is retrieved if there is any. Only one functions is running at a time.

SetBatchLines, -1

global stack := Object()
global stack_head = 0
global stack_tail = 0
global functions := [Func("Function_a"),Func("Function_b"),Func("Function_c")]

SetTimer, check , 25

return

check:
    if( stack_head > stack_tail )
    {
        i := stack[stack_tail]
        functions[i]()
        stack_tail++
    }
return  

Function_a()
{
    tooltip, Function_a running...
    Sleep, 1000
    tooltip, 
    return
}

Function_b()
{
    tooltip, Function_b running...
    Sleep, 1000
    tooltip,
    return
}

Function_c()
{
    tooltip, Function_c running...
    Sleep, 1000
    return
}

a::
    stack[stack_head] := 1
    stack_head++
return

s::
    stack[stack_head] := 2
    stack_head++
return

d::
    stack[stack_head] := 3
    stack_head++
return

This enables concurrent running of the functions, that can do whatever you want, while at the same time hotkeys can add actions (functions indexes) to the stack, which will be called in order they were added one at a time.


I have edited you example to make it functional:

$a::
$s::
$d::
$1::

key := A_ThisHotkey
key :=Trim(key,"$")
Loop
{
    Loop, 5
    {
        SendInput, %key%
        Sleep, 1
    }
    state := GetKeyState(key , "P" )
    if state = 0
    {
        break
    }
}

return