Lets go rebind things (#18166)

* SSinput Rewrite, Custom Keybindings

* hmm yes, safety

* azerty begone

* address AA and SteelSlayer

* Address the old man

* what

* CI dbconfig too

* Address TM issues

Unicode support
Better numpad support
Fix no perms message
Fix modifier screwing movement

* pre-TM tweak, nitfix

* pre TM change 2

* Display others

* MERGE ME

* unduplicates your rows

* reverts some changes, makes this work for now (not TM safe)

* fixes direction facing, removes hotkey help item

* weird keys

* TM commit revert later

* fixed asay/msay keybind

* adds ALL the emotes

* flip and spin

* makes old people happy

* and fixes admins not being able to msay

* lets borgs stow modules

* saves prefs when someone changes a keybind

* reverts skin changes and manually applies
HEAVEN HELP YOU IF YOU USE THE DM SKIN EDITOR IT BREAKS EVERYTHING

* tidies menu, unduplicates rest

* sql file pls come back

* Update SQL/updates/40-41.sql

* why did you not throw an error?!

* inits keybinds if your prefs somehow fail, i guess

* restores these spaces, i guess

* fixes local testing, i guess

* emote cooldown returns (oops)

* movement lock improvements

* Pageup does Swap Hands

* LOOC

* whisper for living mobs

* oops

* fix dsay

* fix IPC silicon emote hotkeys

* category name

* backspace only clears if input is focused

* Makes TAB and BACKSPACE rebindable

* charlie review

* define move

* yeet

* Lewcc review

* brings back legacy mode

* restores legacy mode

* tell legacy mode what is going on

* Update code/controllers/subsystem/input.dm

* Update code/controllers/subsystem/input.dm

Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>

* safeties!

* legacy mode is a pref now

* undo TM changes

* null prefs safeties

* Revert "legacy mode is a pref now"

This reverts commit b45af65139.

* revert this too thanks

Co-authored-by: mochi <shenesis@gmail.com>
Co-authored-by: dearmochi <1496804+dearmochi@users.noreply.github.com>
Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
This commit is contained in:
S34N
2022-07-13 21:34:41 +01:00
committed by GitHub
co-authored by AffectedArc07 mochi dearmochi
parent e1793d24c4
commit 3f95392c82
58 changed files with 1828 additions and 802 deletions
@@ -1070,6 +1070,125 @@
INVOKE_ASYNC(user.client, /client.proc/edit_2fa)
return // We return here to avoid focus being lost
if("keybindings")
if(!keybindings_overrides)
keybindings_overrides = list()
if(href_list["set"])
var/datum/keybinding/KB = locateUID(href_list["set"])
if(KB)
if(href_list["key"])
var/old_key = href_list["old"]
var/new_key = copytext(url_decode(href_list["key"]), 1, 16)
var/alt_mod = text2num(href_list["alt"]) ? "Alt" : ""
var/ctrl_mod = text2num(href_list["ctrl"]) ? "Ctrl" : ""
var/shift_mod = text2num(href_list["shift"]) ? "Shift" : ""
var/numpad = (text2num(href_list["numpad"]) && text2num(new_key)) ? "Numpad" : ""
var/clear = text2num(href_list["clear_key"])
if(new_key == "Unidentified") //There doesn't seem to be any any key!
capture_keybinding(user, KB, href_list["old"])
return
if(!(length_char(new_key) == 1 && text2ascii(new_key) >= 0x80)) // Don't uppercase unicode stuff
new_key = uppertext(new_key)
// Map for JS keys
var/static/list/key_map = list(
"UP" = "North",
"RIGHT" = "East",
"DOWN" = "South",
"LEFT" = "West",
"INSERT" = "Insert",
"HOME" = "Northwest",
"PAGEUP" = "Northeast",
"DEL" = "Delete",
"END" = "Southwest",
"PAGEDOWN" = "Southeast",
"SPACEBAR" = "Space",
"ALT" = "Alt",
"SHIFT" = "Shift",
"CONTROL" = "Ctrl",
"DIVIDE" = "Divide",
"MULTIPLY" = "Multiply",
"ADD" = "Add",
"SUBTRACT" = "Subtract",
"DECIMAL" = "Decimal",
"CLEAR" = "Center"
)
new_key = key_map[new_key] || new_key
var/full_key
switch(new_key)
if("ALT")
full_key = "Alt[ctrl_mod][shift_mod]"
if("CONTROL")
full_key = "[alt_mod]Ctrl[shift_mod]"
if("SHIFT")
full_key = "[alt_mod][ctrl_mod]Shift"
else
full_key = "[alt_mod][ctrl_mod][shift_mod][numpad][new_key]"
// Update overrides
var/list/key_overrides = keybindings_overrides[KB.name] || KB.keys?.Copy() || list()
var/index = key_overrides.Find(old_key)
var/changed = FALSE
if(clear) // Clear
key_overrides -= old_key
changed = TRUE
else if(old_key != full_key)
if(index) // Replace
var/cur_index = key_overrides.Find(full_key)
if(cur_index)
key_overrides[cur_index] = old_key
key_overrides[index] = full_key
changed = TRUE
else // Add
key_overrides -= (old_key || full_key) // Defaults to the new key itself, as to reorder it
key_overrides += full_key
changed = TRUE
else
changed = isnull(keybindings_overrides[KB.name]) // Sets it in the JSON
if(changed)
if(!length(key_overrides) && !length(KB.keys))
keybindings_overrides -= KB.name
else
keybindings_overrides[KB.name] = key_overrides
user << browse(null, "window=capturekeypress")
else
capture_keybinding(user, KB, href_list["old"])
return
else if(href_list["reset"])
var/datum/keybinding/KB = locateUID(href_list["reset"])
if(KB)
keybindings_overrides -= KB.name
else if(href_list["clear"])
var/datum/keybinding/KB = locateUID(href_list["clear"])
if(KB)
if(length(KB.keys))
keybindings_overrides[KB.name] = list()
else
keybindings_overrides -= KB.name
else if(href_list["all"])
var/yes = alert(user, "Really [href_list["all"]] all key bindings?", "Confirm", "Yes", "No") == "Yes"
if(yes)
switch(href_list["all"])
if("reset")
keybindings_overrides = list()
if("clear")
for(var/kb in GLOB.keybindings)
var/datum/keybinding/KB = kb
keybindings_overrides[KB.name] = list()
init_keybindings(keybindings_overrides)
save_preferences(user) //Ideally we want to save people's keybinds when they enter them
ShowChoices(user)
return 1
+95 -1
View File
@@ -117,13 +117,20 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
var/ghost_darkness_level = LIGHTING_PLANE_ALPHA_VISIBLE
/// Colourblind mode
var/colourblind_mode = COLOURBLIND_MODE_NONE
/// Active keybinds (currently useable by the mob/client)
var/list/datum/keybindings = list()
/// Keybinding overrides ("name" => ["key"...])
var/list/keybindings_overrides = null
/datum/preferences/New(client/C, datum/db_query/Q) // Process our query
parent = C
max_gear_slots = GLOB.configuration.general.base_loadout_points
parent?.set_macros()
if(!SSdbcore.IsConnected())
init_keybindings() //we want default keybinds, even if DB is not connected
return // Bail
if(istype(C))
@@ -152,6 +159,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
dat += "<a href='?_src_=prefs;preference=tab;tab=[TAB_CHAR]' [current_tab == TAB_CHAR ? "class='linkOn'" : ""]>Character Settings</a>"
dat += "<a href='?_src_=prefs;preference=tab;tab=[TAB_GAME]' [current_tab == TAB_GAME ? "class='linkOn'" : ""]>Game Preferences</a>"
dat += "<a href='?_src_=prefs;preference=tab;tab=[TAB_GEAR]' [current_tab == TAB_GEAR ? "class='linkOn'" : ""]>Loadout</a>"
dat += "<a href='?_src_=prefs;preference=tab;tab=[TAB_KEYS]' [current_tab == TAB_KEYS ? "class='linkOn'" : ""]>Key Bindings</a>"
dat += "</center>"
dat += "<HR>"
@@ -472,6 +480,50 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
. += "</td></tr>"
dat += "</table>"
if(TAB_KEYS)
dat += "<div align='center'><b>All Key Bindings:&nbsp;</b>"
dat += "<a href='?_src_=prefs;preference=keybindings;all=reset'>Reset to Default</a>&nbsp;"
dat += "<a href='?_src_=prefs;preference=keybindings;all=clear'>Clear</a><br /></div>"
dat += "<tr><td colspan=4><hr></td></tr>"
dat += "<tr><td colspan=4><div align='center'><b>Please note, some keybinds are overriden by other categories.</b></div></td></tr>"
dat += "<tr><td colspan=4><div align='center'><b>Ensure you bind all of them, or the specific one you want.</b></div></td></tr>"
dat += "<tr><td colspan=4><hr></td></tr>"
dat += "<tr><td colspan=4><div align='center'><b>Users of legacy mode can only rebind and use the following keys:</b></div></td></tr>"
dat += "<tr><td colspan=4><div align='center'><b>Arrow Keys, Function Keys, Insert, Del, Home, End, PageUp, PageDn.</b></div></td></tr>"
dat += "<table align='center' width='100%'>"
// Lookup lists to make our life easier
var/static/list/keybindings_by_cat
if(!keybindings_by_cat)
keybindings_by_cat = list()
for(var/kb in GLOB.keybindings)
var/datum/keybinding/KB = kb
keybindings_by_cat["[KB.category]"] += list(KB)
for(var/cat in GLOB.keybindings_groups)
dat += "<tr><td colspan=4><hr></td></tr>"
dat += "<tr><td colspan=3><h2>[cat]</h2></td></tr>"
for(var/kb in keybindings_by_cat["[GLOB.keybindings_groups[cat]]"])
var/datum/keybinding/KB = kb
var/override_keys = (keybindings_overrides && keybindings_overrides[KB.name])
var/list/keys = override_keys || KB.keys
var/keys_buttons = ""
for(var/key in keys)
var/disp_key = key
if(override_keys)
disp_key = "<b>[disp_key]</b>"
keys_buttons += "<a href='?_src_=prefs;preference=keybindings;set=[KB.UID()];old=[url_encode(key)];'>[disp_key]</a>&nbsp;"
dat += "<tr>"
dat += "<td style='width: 25%'>[KB.name]</td>"
dat += "<td style='width: 45%'>[keys_buttons][(length(keys) < 5) ? "<a href='?_src_=prefs;preference=keybindings;set=[KB.UID()];'><span class='good'>+</span></a></td>" : "</td>"]"
dat += "<td style='width: 20%'><a href='?_src_=prefs;preference=keybindings;reset=[KB.UID()]'>Reset to Default</a> <a href='?_src_=prefs;preference=keybindings;clear=[KB.UID()]'>Clear</a></td>"
dat += "</tr>"
dat += "<tr><td colspan=4><br></td></tr>"
dat += "</table>"
dat += "<hr><center>"
if(!IsGuestKey(user.key))
dat += "<a href='?_src_=prefs;preference=load'>Undo</a> - "
@@ -595,9 +647,51 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
added_cost = 0
else
type_blacklist += G.main_typepath
if((total_cost + added_cost) > max_gear_slots)
continue // If the final cost is too high, don't add the item.
active_character.loadout_gear += G.type
total_cost += added_cost
return total_cost
/datum/preferences/proc/init_keybindings(overrides, raw)
if(raw)
try
overrides = json_decode(raw)
catch
overrides = list()
keybindings = list()
keybindings_overrides = overrides
for(var/kb in GLOB.keybindings)
var/datum/keybinding/KB = kb
var/list/keys = (overrides && overrides[KB.name]) || KB.keys
for(var/key in keys)
LAZYADD(keybindings[key], kb)
parent?.update_active_keybindings()
return keybindings
/datum/preferences/proc/capture_keybinding(mob/user, datum/keybinding/KB, old)
var/HTML = {"
<div id='focus' style="outline: 0;" tabindex=0>Keybinding: [KB.name]<br><br><b>Press any key to change<br>Press ESC to clear</b></div>
<script>
var deedDone = false;
document.onkeyup = function(e) {
if(deedDone){ return; }
var alt = e.altKey ? 1 : 0;
var ctrl = e.ctrlKey ? 1 : 0;
var shift = e.shiftKey ? 1 : 0;
var numpad = (95 < e.keyCode && e.keyCode < 112) ? 1 : 0;
var escPressed = e.keyCode == 27 ? 1 : 0;
var url = 'byond://?_src_=prefs;preference=keybindings;set=[KB.UID()];old=[url_encode(old)];clear_key='+escPressed+';key='+encodeURIComponent(e.key)+';alt='+alt+';ctrl='+ctrl+';shift='+shift+';numpad='+numpad+';key_code='+e.keyCode;
window.location=url;
deedDone = true;
}
document.getElementById('focus').focus();
</script>
"}
winshow(user, "capturekeypress", TRUE)
var/datum/browser/popup = new(user, "capturekeypress", "<div align='center'>Keybindings</div>", 350, 300)
popup.set_content(HTML)
popup.open(FALSE)
onclose(user, "capturekeypress", src)
@@ -25,6 +25,7 @@
screentip_color = query.item[19]
ghost_darkness_level = query.item[20]
colourblind_mode = query.item[21]
keybindings = init_keybindings(raw = query.item[22])
//Sanitize
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
@@ -78,7 +79,8 @@
screentip_mode=:screentip_mode,
screentip_color=:screentip_color,
ghost_darkness_level=:ghost_darkness_level,
colourblind_mode=:colourblind_mode
colourblind_mode=:colourblind_mode,
keybindings=:keybindings
WHERE ckey=:ckey"}, list(
// OH GOD THE PARAMETERS
"ooccolour" = ooccolor,
@@ -101,6 +103,7 @@
"screentip_color" = screentip_color,
"ghost_darkness_level" = ghost_darkness_level,
"colourblind_mode" = colourblind_mode,
"keybindings" = json_encode(keybindings_overrides),
"ckey" = C.ckey,
))
@@ -277,29 +277,6 @@
to_chat(usr, "<span class='notice'>You have disabled text popup limiting.")
return
/client/verb/numpad_target()
set name = "Toggle Numpad Targeting"
set category = "Preferences"
set desc = "This button will allow you to enable or disable Numpad Targeting"
prefs.toggles ^= PREFTOGGLE_NUMPAD_TARGET
prefs.save_preferences(src)
if (prefs.toggles & PREFTOGGLE_NUMPAD_TARGET)
to_chat(usr, "<span class='notice'>You have enabled Numpad Targeting.")
else
to_chat(usr, "<span class='notice'>You have disabled Numpad Targeting.")
return
/client/verb/azerty_toggle()
set name = "Toggle QWERTY/AZERTY"
set category = "Preferences"
set desc = "This button will switch you between QWERTY and AZERTY control sets"
prefs.toggles ^= PREFTOGGLE_AZERTY
prefs.save_preferences(src)
if (prefs.toggles & PREFTOGGLE_AZERTY)
to_chat(usr, "<span class='notice'>You are now in AZERTY mode.")
else
to_chat(usr, "<span class='notice'>You are now in QWERTY mode.")
return
/client/verb/toggle_ghost_pda()
set name = "Show/Hide GhostPDA"
set category = "Preferences"