Skip to content

Commit

Permalink
feat(keybindings): ports Nebula's KBs
Browse files Browse the repository at this point in the history
  • Loading branch information
Filatelele committed Jun 1, 2024
1 parent a3f1a4c commit 932c0bb
Show file tree
Hide file tree
Showing 35 changed files with 1,293 additions and 1,014 deletions.
18 changes: 18 additions & 0 deletions baystation12.dme
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "code\__defines\flags.dm"
#include "code\__defines\gamemode.dm"
#include "code\__defines\hydroponics.dm"
#include "code\__defines\input.dm"
#include "code\__defines\integrated_circuits.dm"
#include "code\__defines\inventory_sizes.dm"
#include "code\__defines\items_clothing.dm"
Expand Down Expand Up @@ -123,6 +124,7 @@
#include "code\__std\util.dm"
#include "code\_global_vars\bitfields.dm"
#include "code\_global_vars\bluespace_beacon.dm"
#include "code\_global_vars\client_input.dm"
#include "code\_global_vars\configuration.dm"
#include "code\_global_vars\converter.dm"
#include "code\_global_vars\logging.dm"
Expand Down Expand Up @@ -262,6 +264,7 @@
#include "code\controllers\subsystems\explosion.dm"
#include "code\controllers\subsystems\garbage.dm"
#include "code\controllers\subsystems\inactivity.dm"
#include "code\controllers\subsystems\input.dm"
#include "code\controllers\subsystems\lighting.dm"
#include "code\controllers\subsystems\lobby.dm"
#include "code\controllers\subsystems\machines.dm"
Expand Down Expand Up @@ -1685,6 +1688,7 @@
#include "code\modules\client\preference_setup\antagonism\01_candidacy.dm"
#include "code\modules\client\preference_setup\antagonism\02_setup.dm"
#include "code\modules\client\preference_setup\augmentation\01_modifications.dm"
#include "code\modules\client\preference_setup\controls\keybindings.dm"
#include "code\modules\client\preference_setup\general\01_basic.dm"
#include "code\modules\client\preference_setup\general\02_language.dm"
#include "code\modules\client\preference_setup\general\03_body.dm"
Expand Down Expand Up @@ -1984,6 +1988,20 @@
#include "code\modules\integrated_electronics\subtypes\text.dm"
#include "code\modules\integrated_electronics\subtypes\time.dm"
#include "code\modules\integrated_electronics\subtypes\trig.dm"
#include "code\modules\keybindings\_defines.dm"
#include "code\modules\keybindings\_keybindings.dm"
#include "code\modules\keybindings\admin.dm"
#include "code\modules\keybindings\bindings_atom.dm"
#include "code\modules\keybindings\bindings_client.dm"
#include "code\modules\keybindings\carbon.dm"
#include "code\modules\keybindings\client.dm"
#include "code\modules\keybindings\communication.dm"
#include "code\modules\keybindings\human.dm"
#include "code\modules\keybindings\living.dm"
#include "code\modules\keybindings\mob.dm"
#include "code\modules\keybindings\movement.dm"
#include "code\modules\keybindings\robot.dm"
#include "code\modules\keybindings\setup.dm"
#include "code\modules\library\lib_items.dm"
#include "code\modules\library\lib_machines.dm"
#include "code\modules\library\lib_readme.dm"
Expand Down
5 changes: 5 additions & 0 deletions code/__defines/colors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,8 @@
#define COLOR_BLOOD_UNATHI "#f24b2e"
#define COLOR_BLOOD_TAJARAN "#862a51"
#define COLOR_BLOOD_SKRELL "#1d2cbf"

// Colors for input/hotkey panel.

#define COLOR_INPUT_DISABLED "#f0f0f0"
#define COLOR_INPUT_ENABLED "#d3b5b5"
13 changes: 13 additions & 0 deletions code/__defines/input.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// /Max length of a keypress command before it's considered to be a forged packet/bogus command
#define MAX_KEYPRESS_COMMANDLENGTH 16
/// Maximum keys that can be bound to one button
#define MAX_COMMANDS_PER_KEY 5
/// Maximum keys per keybind
#define MAX_KEYS_PER_KEYBIND 3
/// Length of held key buffer
#define HELD_KEY_BUFFER_LENGTH 15

//NOTE: INTENT_HOTKEY_* defines are not actual intents!
//they are here to support hotkeys
#define INTENT_HOTKEY_LEFT "left"
#define INTENT_HOTKEY_RIGHT "right"
1 change: 1 addition & 0 deletions code/__defines/subsystem-priority.dm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define SS_PRIORITY_EXPLOSION 666 // Processing explosion stuff, abnormal number for abnormal stuff
#define SS_PRIORITY_VIRUSES 20 // Processing viruses life.
#define SS_PRIORITY_OPEN_SPACE 20 // Open turf updates.
#define SS_PRIORITY_INPUT 20 // Input sybsystem.
#define SS_PRIORITY_AIRFLOW 15 // Object movement from ZAS airflow.
#define SS_PRIORITY_VOTE 10 // Vote management.
#define SS_PRIORITY_INACTIVITY 10 // Idle kicking.
Expand Down
3 changes: 2 additions & 1 deletion code/__defines/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.

#define SS_INIT_LOBBY 17
#define SS_INIT_LOBBY 18
#define SS_INIT_INPUT 17
#define SS_INIT_GARBAGE 16
#define SS_INIT_EAMS 15
#define SS_INIT_CHAR_SETUP 14
Expand Down
47 changes: 47 additions & 0 deletions code/_global_vars/client_input.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
GLOBAL_LIST_EMPTY(hotkey_keybinding_list_by_key)
GLOBAL_LIST_INIT(keybindings_by_name, init_kb_by_name())

/proc/init_kb_by_name()
var/list/keybindings = list()
for(var/path in subtypesof(/datum/keybinding))
var/datum/keybinding/keybinding = path
if(!keybinding::name)
continue

var/datum/keybinding/instance = new keybinding()
keybindings[instance.name] = instance
if(length(instance.hotkey_keys))
for(var/bound_key in instance.hotkey_keys)
GLOB.hotkey_keybinding_list_by_key[bound_key] += list(instance.name)

return keybindings

// This is a mapping from JS keys to Byond - ref: https://keycode.info/
GLOBAL_LIST_INIT(_kbMap, 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"
))

// Without alt, shift, ctrl and etc because its not necessary
GLOBAL_LIST_INIT(_kbMap_reverse, list(
"North" = "Up",
"East" = "Right",
"South" = "Down",
"West" = "Left",
"Northwest" = "Home",
"Northeast" = "PageUp",
"Southwest" = "End",
"Southeast" = "PageDown",
))
5 changes: 5 additions & 0 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
if(modifiers["middle"])
if(modifiers["shift"])
ShiftMiddleClickOn(A)
else if(modifiers["alt"])
AltMiddleClickOn(A)
else
MiddleClickOn(A)
return 1
Expand Down Expand Up @@ -256,6 +258,9 @@
if(pointed(A))
return

/mob/proc/AltMiddleClickOn(atom/A)
pointed(A)

/atom/proc/MiddleClick(mob/M)
return

Expand Down
38 changes: 38 additions & 0 deletions code/controllers/subsystems/input.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
SUBSYSTEM_DEF(input)
name = "Input"
wait = 1
init_order = SS_INIT_INPUT
flags = SS_TICKER
priority = SS_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY

var/list/macro_set

/datum/controller/subsystem/input/Initialize()
. = ..()
setup_default_macro_sets()
refresh_client_macro_sets()

/// This is for when macro sets are eventualy datumized
/datum/controller/subsystem/input/proc/setup_default_macro_sets()
macro_set = list(
"Any" = "\"KeyDown \[\[*\]\]\"",
"Any+UP" = "\"KeyUp \[\[*\]\]\"",
"Back" = "\".winset \\\"outputwindow.input.text=\\\"\\\"\\\"\"",
"Tab" = "\".winset \\\"outputwindow.input.focus=true?mapwindow.map.focus=true outputwindow.input.background-color=[COLOR_INPUT_DISABLED]:outputwindow.input.focus=true outputwindow.input.background-color=[COLOR_INPUT_ENABLED]\\\"\"",
"Escape" = "Reset-Held-Keys",
)

/// Badmins just wanna have fun
/datum/controller/subsystem/input/proc/refresh_client_macro_sets()
for(var/client/C in GLOB.clients)
C.set_macros()

/**
* It feels input's fire should have CHECK_TICK
* However, stoplag() will probably fuck up all clients' input.
*/

/datum/controller/subsystem/input/fire()
for(var/client/C in GLOB.clients)
C.keyLoop()
2 changes: 1 addition & 1 deletion code/datums/movement/movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ if(LAZYLEN(movement_handlers) && ispath(movement_handlers[1])) { \
for(var/mh in movement_handlers)
var/datum/movement_handler/movement_handler = mh
if(movement_handler.MayMove(mover, is_external) & MOVEMENT_STOP)
return MOVEMENT_HANDLED
return MOVEMENT_STOP

. = movement_handler.DoMove(direction, mover, is_external)
if(. & MOVEMENT_REMOVE)
Expand Down
8 changes: 8 additions & 0 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,11 @@
/// Called on `/mob/proc/start_pulling`.
/atom/movable/proc/on_pulling_try(mob/user)
return

/**
* A wrapper for setDir that should only be able to fail by living mobs.
*
* Called from '/atom/movable/proc/keyLoop', this exists to be overwritten by living mobs with a check to see if we're actually alive enough to change directions
*/
/atom/movable/proc/keybind_face_direction(direction)
return
15 changes: 15 additions & 0 deletions code/modules/client/client_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,18 @@

/// Whether typing indicators are enabled
var/typing_indicators

/// Custom movement keys for this client
var/list/movement_keys = list()
/// Are we locking our movement input?
var/movement_locked = FALSE
/// A buffer of currently held keys.
var/list/keys_held = list()
/// A buffer for combinations such of modifiers + keys (ex: CtrlD, AltE, ShiftT). Format: `"key"` -> `"combo"` (ex: `"D"` -> `"CtrlD"`)
var/list/key_combos_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.
*/
/// Movement dir of the most recently pressed movement key. Used in cardinal-only movement mode.
var/last_move_dir_pressed
68 changes: 68 additions & 0 deletions code/modules/client/client_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@
if(prefs && !istype(mob, world.mob))
prefs.apply_post_login_preferences(src)

if(SSinput.initialized)
set_macros()

turf_examine = new(src)

settings = new(src)
Expand Down Expand Up @@ -705,3 +708,68 @@
var/mob/living/M = mob
if(istype(M) && !M.in_throw_mode)
M.OnMouseDown(object, location, control, params)

/client/Click(atom/A)
//if(!user_acted(src))
// return

if(holder && holder.callproc && holder.callproc.waiting_for_click)
if(alert("Do you want to select \the [A] as the [holder.callproc.arguments.len+1]\th argument?",, "Yes", "No") == "Yes")
holder.callproc.arguments += A

holder.callproc.waiting_for_click = 0
verbs -= /client/proc/cancel_callproc_select
holder.callproc.do_args()
return

if (prefs.hotkeys)
// If hotkey mode is enabled, then clicking the map will automatically
// unfocus the text bar. This removes the red color from the text bar
// so that the visual focus indicator matches reality.
winset(src, null, "outputwindow.input.background-color=[COLOR_INPUT_DISABLED]")
else
winset(src, null, "outputwindow.input.focus=true input.background-color=[COLOR_INPUT_ENABLED]")

return ..()

/**
* Updates the keybinds for special keys
*
* Handles adding macros for the keys that need it
* And adding movement keys to the clients movement_keys list
* At the time of writing this, communication(OOC, Say, IC) require macros
* Arguments:
* * direct_prefs - the preference we're going to get keybinds from
*/
/client/proc/update_special_keybinds(datum/preferences/direct_prefs)
var/datum/preferences/D = prefs || direct_prefs
if(!D?.key_bindings)
return
movement_keys = list()
var/list/communication_hotkeys = 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
if("Say")
winset(src, "default-\ref[key]", "parent=default;name=[key];command=say")
communication_hotkeys += key
if("OOC")
winset(src, "default-\ref[key]", "parent=default;name=[key];command=ooc")
communication_hotkeys += key
if("Me")
winset(src, "default-\ref[key]", "parent=default;name=[key];command=me")
communication_hotkeys += key

// winget() does not work for F1 and F2
for(var/key in communication_hotkeys)
if(!(key in list("F1","F2")) && !winget(src, "default-\ref[key]", "command"))
to_chat(src, "You probably entered the game with a different keyboard layout.\n<a href='?src=\ref[src];reset_macros=1'>Please switch to the English layout and click here to fix the communication hotkeys.</a>")
break
Loading

0 comments on commit 932c0bb

Please sign in to comment.