From 8b224ef13ee18253f2862e63ebc1c4e3149b5f6b Mon Sep 17 00:00:00 2001 From: Rohesie Date: Sun, 20 Sep 2020 19:01:21 -0300 Subject: [PATCH] Refactors the keys_held rolling buffer (#53773) * rolling key rip * category * comment * oops --- code/__DEFINES/admin.dm | 2 +- code/controllers/subsystem/input.dm | 3 ++- code/modules/client/client_defines.dm | 10 ++++++++++ code/modules/client/verbs/reset_held_keys.dm | 11 +++++++++++ code/modules/keybindings/bindings_client.dm | 14 ++++++-------- code/modules/keybindings/setup.dm | 19 +++---------------- tgstation.dme | 1 + 7 files changed, 34 insertions(+), 26 deletions(-) create mode 100644 code/modules/client/verbs/reset_held_keys.dm diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 2121a6bfa88..9aa0dd4d818 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -126,7 +126,7 @@ #define MAX_KEYS_PER_KEYBIND 3 ///Max amount of keypress messages per second over two seconds before client is autokicked #define MAX_KEYPRESS_AUTOKICK 50 -///Length of held key rolling buffer +///Length of held key buffer #define HELD_KEY_BUFFER_LENGTH 15 #define STICKYBAN_DB_CACHE_TIME 10 SECONDS diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index 3edd60fbdfa..2aab7e4825c 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -27,7 +27,8 @@ SUBSYSTEM_DEF(input) "M" = "me", "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", "Tab" = "\".winset \\\"input.focus=true?map.focus=true input.background-color=[COLOR_INPUT_DISABLED]:input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", - "Escape" = "\".winset \\\"input.text=\\\"\\\"\\\"\"") + "Escape" = "Reset-Held-Keys", + ) // Badmins just wanna have fun ♪ /datum/controller/subsystem/input/proc/refresh_client_macro_sets() diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 1f3aff51697..cce17df3ccc 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -192,3 +192,13 @@ /// rate limiting for the crew manifest var/crew_manifest_delay + /// A buffer of currently held keys. + var/list/keys_held = list() + /* + ** These next two vars are to apply movement for keypresses and releases made while move delayed. + ** Because discarding that input makes the game less responsive. + */ + /// On next move, add this dir to the move that would otherwise be done + var/next_move_dir_add + /// On next move, subtract this dir from the move that would otherwise be done + var/next_move_dir_sub diff --git a/code/modules/client/verbs/reset_held_keys.dm b/code/modules/client/verbs/reset_held_keys.dm new file mode 100644 index 00000000000..44973d2283a --- /dev/null +++ b/code/modules/client/verbs/reset_held_keys.dm @@ -0,0 +1,11 @@ +/** + * Manually clears any held keys, in case due to lag or other undefined behavior a key gets stuck. + * + * Hardcoded to the ESC key. + */ +/client/verb/reset_held_keys() + set name = "Reset Held Keys" + set hidden = TRUE + + for(var/key in keys_held) + keyUp(key) diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index c31ae03317c..ee86615a2c4 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -41,11 +41,11 @@ winset(src, null, "input.focus=true ; input.text=[url_encode(_key)]") return - //offset by 1 because the buffer address is 0 indexed because the math was simpler - keys_held[current_key_address + 1] = _key + if(length(keys_held) >= HELD_KEY_BUFFER_LENGTH && !keys_held[_key]) + keyUp(keys_held[1]) //We are going over the number of possible held keys, so let's remove the first one. + //the time a key was pressed isn't actually used anywhere (as of 2019-9-10) but this allows easier access usage/checking keys_held[_key] = world.time - current_key_address = ((current_key_address + 1) % HELD_KEY_BUFFER_LENGTH) var/movement = movement_keys[_key] if(!(next_move_dir_sub & movement) && !movement_locked) next_move_dir_add |= movement @@ -75,11 +75,9 @@ set instant = TRUE set hidden = TRUE - //Can't just do a remove because it would alter the length of the rolling buffer, instead search for the key then null it out if it exists - for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) - if(keys_held[i] == _key) - keys_held[i] = null - break + if(!keys_held[_key]) + return + keys_held -= _key var/movement = movement_keys[_key] if(!(next_move_dir_add & movement)) next_move_dir_sub |= movement diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm index 78e06132311..48cc41b6eef 100644 --- a/code/modules/keybindings/setup.dm +++ b/code/modules/keybindings/setup.dm @@ -1,15 +1,3 @@ -/client - /// A rolling buffer of any keys held currently - var/list/keys_held = list() - ///used to keep track of the current rolling buffer position - var/current_key_address = 0 - /// These next two vars are to apply movement for keypresses and releases made while move delayed. - /// Because discarding that input makes the game less responsive. - /// On next move, add this dir to the move that would otherwise be done - var/next_move_dir_add - /// On next move, subtract this dir from the move that would otherwise be done - var/next_move_dir_sub - // Set a client's focus to an object and override these procs on that object to let it handle keypresses /datum/proc/key_down(key, client/user) // Called when a key is pressed down initially @@ -33,10 +21,9 @@ /client/proc/set_macros() set waitfor = FALSE - //Reset and populate the rolling buffer - keys_held.Cut() - for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) - keys_held += null + //Reset the buffer + for(var/key in keys_held) + keyUp(key) erase_all_macros() diff --git a/tgstation.dme b/tgstation.dme index 003811c838a..a0fed469dca 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1743,6 +1743,7 @@ #include "code\modules\client\verbs\etips.dm" #include "code\modules\client\verbs\ooc.dm" #include "code\modules\client\verbs\ping.dm" +#include "code\modules\client\verbs\reset_held_keys.dm" #include "code\modules\client\verbs\suicide.dm" #include "code\modules\client\verbs\who.dm" #include "code\modules\clothing\chameleon.dm"