Customizable Hotkeys

Customizable Hotkeys is a low-level system designed to create triggers that fire on a button-press for which the hotkey can be fully customized by players. It is not designed to change the hotkeys of unit abilities, but the hotkeys of custom systems in maps such as WASD controls. It allows you to create a UI where the player can change his or her hotkeys similar to how it is done in any modern video game. A basic template for how to create such a UI is included in the Test Map.

A full-blown UI system might come in the future.


How it works

Let's say we want to create a WASD movement system that allows the players to change the hotkeys if they so choose.

First, create four triggers with CustomizableHotkeys.CreateTrigger.
Lua:
CustomizableHotkeys.CreateTrigger("MoveUp", OSKEY_W, 0, OnMoveUpKeyPressed, OnMoveUpKeyReleased)
CustomizableHotkeys.CreateTrigger("MoveDown", OSKEY_S, 0, OnMoveDownKeyPressed, OnMoveDownKeyReleased)
CustomizableHotkeys.CreateTrigger("MoveLeft", OSKEY_A, 0, OnMoveLeftKeyPressed, OnMoveLeftKeyReleased)
CustomizableHotkeys.CreateTrigger("MoveRight", OSKEY_D, 0, OnMoveRightKeyPressed, OnMoveRightKeyReleased)

Within the callback functions, we simply toggle the state of a global variable that tracks whether the key is currently pressed by the respective player. This function behaves like a regular trigger callback:
Lua:
function OnMoveUpkeyPressed()
    local player = GetTriggerPlayer()
    MoveUpKeyPressed[player] = true
end

If we want to enable the players to customize those hotkeys, we could create buttons such as the one in the Test Map. When the player clicks on one of the buttons, the key listener should be enabled for that player:
Lua:
function OnCustomizerButtonMoveUpClick()
    local player = GetTriggerPlayer()

    --Prevent the player's character from moving while waiting for the key to be pressed.
    MoveUpKeyPressed[player] = false
    MoveDownKeyPressed[player] = false
    MoveLeftKeyPressed[player] = false
    MoveRightKeyPressed[player] = false

    CustomizableHotkeys.EnableAll(false, player)
    CustomizableHotkeys.Listen("MoveUp", player, OnHotkeyCustomized)
end

Now the move triggers have been disabled and the key listener enabled. The player can now press any button and the callback function will be invoked:
Lua:
function OnHotkeyCustomized(whichPlayer, hotkeyString, overwritten, wasInvalid)
    BlzFrameSetText(HotkeyCustomizerFrame, hotkeyString)
    CustomizableHotkeys.EnableAll(true, whichPlayer)
end
This changes the text of the frame to the new hotkey so that the player gets a visual confirmation that the hotkey has been changed. Then, it enables the movement system again. We can now insert error messages and handlers for the cases when the player overwrites another hotkey or the pressed key was invalid.


Installation

Copy the CustomizableHotkeys script into your map. Make sure you have TotalInitialization installed and located at the top of your map script.
Contents

CustomizableHotkeys (Map)

CustomizableHotkeys (Binary)

Reviews
Wrda
---Enables or disables all registered triggers for the specified player or for all players if not specified. ---@param enable boolean ---@param whichPlayer? player EnableAll = function(enable, whichPlayer) local...

Wrda

Spell Reviewer
Level 28
Joined
Nov 18, 2012
Messages
2,010
Lua:
---Enables or disables all registered triggers for the specified player or for all players if not specified.
        ---@param enable boolean
        ---@param whichPlayer? player
        EnableAll = function(enable, whichPlayer)
            local orderedTriggers = {}
            for name, __ in pairs(triggerDataFromName) do
                orderedTriggers[#orderedTriggers + 1] = name
            end
            table.sort(orderedTriggers)

            for __, name in ipairs(orderedTriggers) do
                CustomizableHotkeys.EnableTrigger(name, enable, whichPlayer)
            end
        end,

Doesn't do for all players as it says it the comments.

A good system ready-to-use facilitating keyboard events.

Approved
 
Last edited:
Fixed an issue that could affect triggers that should track whether a button is pressed. A player could press the hotkey and while it is being pressed hold a metakey or stop holding that metakey. Now the release trigger won't fire because the metakey has changed.

How it is handled now is that, if both an onKeyDown and an onKeyUp function is provided, it is assumed that you want to track whether the hotkey is pressed and the release event will fire regardless of the current metakey.
 
Top