diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm
index bc3f6cf51b..8c4fba367d 100644
--- a/code/controllers/subsystem/input.dm
+++ b/code/controllers/subsystem/input.dm
@@ -6,6 +6,12 @@ SUBSYSTEM_DEF(input)
priority = FIRE_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
+ /// KEEP THIS UP TO DATE!
+ var/static/list/all_macrosets = list(
+ SKIN_MACROSET_HOTKEYS,
+ SKIN_MACROSET_CLASSIC_HOTKEYS,
+ SKIN_MACROSET_CLASSIC_INPUT
+ )
/// Classic mode input focused macro set. Manually set because we can't define ANY or ANY+UP for classic.
var/static/list/macroset_classic_input
/// Classic mode map focused macro set. Manually set because it needs to be clientside and go to macroset_classic_input.
@@ -51,11 +57,6 @@ SUBSYSTEM_DEF(input)
// let's play the ascii game of A to Z (UPPERCASE)
for(var/i in 65 to 90)
classic_ctrl_override_keys += ascii2text(i)
- // let's play the game of clientside bind overrides!
- classic_ctrl_override_keys -= list("T", "O", "M", "L")
- macroset_classic_input["Ctrl+T"] = "say"
- macroset_classic_input["Ctrl+O"] = "ooc"
- macroset_classic_input["Ctrl+L"] = "looc"
// let's play the list iteration game x2
for(var/key in classic_ctrl_override_keys)
// make sure to double double quote to ensure things are treated as a key combo instead of addition/semicolon logic.
@@ -67,20 +68,6 @@ SUBSYSTEM_DEF(input)
// FINALLY, WE CAN DO SOMETHING MORE NORMAL FOR THE SNOWFLAKE-BUT-LESS KEYSET.
- // HAHA - SIKE. Because of BYOND weirdness (tl;dr not specifically binding this way results in potentially duplicate chatboxes when
- // conflicts occur with something like say indicator vs say), we're going to snowflake this anyways
- var/list/hard_binds = list(
- "O" = "ooc",
- "T" = "say",
- "L" = "looc",
- "M" = "me"
- )
- var/list/hard_bind_anti_collision = list()
- var/list/anti_collision_modifiers = list("Ctrl", "Alt", "Shift", "Ctrl+Alt", "Ctrl+Shift", "Alt+Shift", "Ctrl+Alt+Shift")
- for(var/key in hard_binds)
- for(var/modifier in anti_collision_modifiers)
- hard_bind_anti_collision["[modifier]+[key]"] = ".NONSENSICAL_VERB_THAT_DOES_NOTHING"
-
macroset_classic_hotkey = list(
"Any" = "\"KeyDown \[\[*\]\]\"",
"Any+UP" = "\"KeyUp \[\[*\]\]\"",
@@ -89,9 +76,6 @@ SUBSYSTEM_DEF(input)
"Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"",
)
- macroset_classic_hotkey |= hard_binds
- macroset_classic_hotkey |= hard_bind_anti_collision
-
// And finally, the modern set.
macroset_hotkey = list(
"Any" = "\"KeyDown \[\[*\]\]\"",
@@ -101,16 +85,12 @@ SUBSYSTEM_DEF(input)
"Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"",
)
- macroset_hotkey |= hard_binds
- macroset_hotkey |= hard_bind_anti_collision
-
// Badmins just wanna have fun ♪
/datum/controller/subsystem/input/proc/refresh_client_macro_sets()
var/list/clients = GLOB.clients
for(var/i in 1 to clients.len)
var/client/user = clients[i]
- user.set_macros()
- user.update_movement_keys()
+ user.full_macro_assert()
/datum/controller/subsystem/input/fire()
var/list/clients = GLOB.clients // Let's sing the list cache song
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index 53ab7f7abb..b71521121b 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -89,6 +89,8 @@
var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen.
+ /// Last time they used fix macros
+ var/last_macro_fix = 0
/// Keys currently held
var/list/keys_held = list()
/// These next two vars are to apply movement for keypresses and releases made while move delayed.
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index c581e402a6..267ee3a5e1 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -269,7 +269,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
prefs = new /datum/preferences(src)
GLOB.preferences_datums[ckey] = prefs
- addtimer(CALLBACK(src, .proc/ensure_keys_set), 10) //prevents possible race conditions
+ addtimer(CALLBACK(src, .proc/ensure_keys_set, prefs), 10) //prevents possible race conditions
prefs.last_ip = address //these are gonna be used for banning
prefs.last_id = computer_id //these are gonna be used for banning
@@ -443,7 +443,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.")
-
//This is down here because of the browse() calls in tooltip/New()
if(!tooltips)
tooltips = new /datum/tooltip(src)
@@ -475,11 +474,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
fit_viewport()
Master.UpdateTickRate()
-/client/proc/ensure_keys_set()
- if(SSinput.initialized)
- set_macros()
- update_movement_keys(prefs)
-
//////////////
//DISCONNECT//
//////////////
@@ -937,23 +931,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
y = clamp(y+change, min,max)
view_size.setDefault("[x]x[y]")
-/client/proc/update_movement_keys(datum/preferences/direct_prefs)
- var/datum/preferences/D = prefs || direct_prefs
- if(!D?.key_bindings)
- return
- movement_keys = list()
- for(var/key in D.key_bindings)
- for(var/kb_name in D.key_bindings[key])
- switch(kb_name)
- if("North")
- movement_keys[key] = NORTH
- if("East")
- movement_keys[key] = EAST
- if("West")
- movement_keys[key] = WEST
- if("South")
- movement_keys[key] = SOUTH
-
/client/proc/change_view(new_size)
if (isnull(new_size))
CRASH("change_view called without argument.")
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 0d01c4c343..80f3a8365c 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -53,7 +53,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
/// List with a key string associated to a list of keybindings. Unlike key_bindings, this one operates on raw key, allowing for binding a key that triggers regardless of if a modifier is depressed as long as the raw key is sent.
var/list/modless_key_bindings = list()
-
var/tgui_fancy = TRUE
var/tgui_lock = TRUE
var/windowflashing = TRUE
@@ -219,7 +218,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//we couldn't load character data so just randomize the character appearance + name
random_character() //let's create a random character then - rather than a fat, bald and naked man.
key_bindings = deepCopyList(GLOB.hotkey_keybinding_list_by_key) // give them default keybinds and update their movement keys
- C?.update_movement_keys(src)
+ C?.ensure_keys_set(src)
real_name = pref_species.random_name(gender,1)
if(!loaded_preferences_successfully)
save_preferences()
@@ -952,7 +951,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/list/default_keys = hotkeys ? kb.hotkey_keys : kb.classic_keys
if(LAZYLEN(default_keys))
dat += "| Default: [default_keys.Join(", ")]"
- dat += "Independent Binding: [current_independent_binding]"
+ dat += ""
+ if(!kb.special && !kb.clientside)
+ dat += "Independent Binding: [current_independent_binding]"
dat += "
"
else
var/bound_key = user_binds[kb.name][1]
@@ -965,7 +966,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/list/default_keys = hotkeys ? kb.classic_keys : kb.hotkey_keys
if(LAZYLEN(default_keys))
dat += "| Default: [default_keys.Join(", ")]"
- dat += "Independent Binding: [current_independent_binding]"
+ dat += ""
+ if(!kb.special && !kb.clientside)
+ dat += "Independent Binding: [current_independent_binding]"
dat += "
"
dat += "
"
@@ -991,7 +994,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
#undef APPEARANCE_CATEGORY_COLUMN
#undef MAX_MUTANT_ROWS
-/datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, old_key, independent = FALSE)
+/datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, old_key, independent = FALSE, special = FALSE)
var/HTML = {"