Skip to content

Commit

Permalink
Port hotkey system from SS220 Paradise (#13)
Browse files Browse the repository at this point in the history
* Port hotkey system from paradise

* Заменил для некоторых вещей клик СКМ на Альт+СКМ, в целом ни на что не влияет, т.к. у них были аналоги в виде обычного Альт клика
  • Loading branch information
Vallat authored Jul 2, 2021
1 parent c0451b4 commit 7157515
Show file tree
Hide file tree
Showing 36 changed files with 728 additions and 880 deletions.
12 changes: 12 additions & 0 deletions baystation12.dme
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
#include "code\controllers\subsystems\goals.dm"
#include "code\controllers\subsystems\graphs.dm"
#include "code\controllers\subsystems\inactivity.dm"
#include "code\controllers\subsystems\input.dm"
#include "code\controllers\subsystems\jobs.dm"
#include "code\controllers\subsystems\kv.dm"
#include "code\controllers\subsystems\lighting.dm"
Expand Down Expand Up @@ -1967,6 +1968,17 @@
#include "code\modules\item_worth\item_worth.dm"
#include "code\modules\item_worth\value_procs.dm"
#include "code\modules\item_worth\worths_list.dm"
#include "code\modules\keybindings\bindings_admin.dm"
#include "code\modules\keybindings\bindings_ai.dm"
#include "code\modules\keybindings\bindings_atom.dm"
#include "code\modules\keybindings\bindings_carbon.dm"
#include "code\modules\keybindings\bindings_client.dm"
#include "code\modules\keybindings\bindings_human.dm"
#include "code\modules\keybindings\bindings_living.dm"
#include "code\modules\keybindings\bindings_mob.dm"
#include "code\modules\keybindings\bindings_robot.dm"
#include "code\modules\keybindings\focus.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
9 changes: 8 additions & 1 deletion code/__defines/admin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,11 @@
#define TICKET_ASSIGNED 2 // An admin has assigned themself to the ticket and will respond

#define LAST_CKEY(M) (M.ckey || M.last_ckey)
#define LAST_KEY(M) (M.key || M.last_ckey)
#define LAST_KEY(M) (M.key || M.last_ckey)

///Max length of a keypress command before it's considered to be a forged packet/bogus command
#define MAX_KEYPRESS_COMMANDLENGTH 16
///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
#define HELD_KEY_BUFFER_LENGTH 15
3 changes: 3 additions & 0 deletions code/__defines/colors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,6 @@
#define COLOR_DARKMODE_BACKGROUND "#202020"
#define COLOR_DARKMODE_DARKBACKGROUND "#171717"
#define COLOR_DARKMODE_TEXT "#a4bad6"

#define COLOR_INPUT_DISABLED "#F0F0F0"
#define COLOR_INPUT_ENABLED "#D3B5B5"
9 changes: 9 additions & 0 deletions code/__defines/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,12 @@
#define INIT_MACHINERY_PROCESS_ALL 0x3
//--

//intent defines
#define INTENT_HELP "help"
#define INTENT_GRAB "grab"
#define INTENT_DISARM "disarm"
#define INTENT_HARM "harm"
//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 @@ -10,6 +10,7 @@
#define SS_PRIORITY_ICON_UPDATE 20 // Queued icon updates. Mostly used by APCs and tables.

// Normal
#define SS_PRIORITY_INPUT 1000
#define SS_PRIORITY_TICKER 100 // Gameticker.
#define SS_PRIORITY_MOB 95 // Mob Life().
#define SS_PRIORITY_MACHINERY 95 // Machinery + powernet ticks.
Expand Down
1 change: 1 addition & 0 deletions code/__defines/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ return;\
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.

#define SS_INIT_INPUT 19
#define SS_INIT_EARLY 18
#define SS_INIT_GARBAGE 17
#define SS_INIT_CHEMISTRY 16
Expand Down
3 changes: 3 additions & 0 deletions code/_helpers/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1118,3 +1118,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
M.start_pulling(t)
else
step(user.pulling, get_dir(user.pulling.loc, A))

/proc/REF(input)
return "\ref[input]"
11 changes: 7 additions & 4 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
if(modifiers["middle"])
MiddleClickOn(A)
return 1
if(modifiers["middle"] && modifiers["alt"])
AltMiddleClickOn(A)
return 1
if(modifiers["shift"])
ShiftClickOn(A)
return 0
Expand Down Expand Up @@ -219,7 +222,10 @@
Only used for swapping hands
*/
/mob/proc/MiddleClickOn(var/atom/A)
swap_hand()
pointed(A)
return

/mob/proc/AltMiddleClickOn(var/atom/A)
return

// In case of use break glass
Expand Down Expand Up @@ -302,11 +308,8 @@
/mob/proc/CtrlAltClickOn(var/atom/A)
if(A.CtrlAltClick(src))
return
pointed(A)

/atom/proc/CtrlAltClick(var/mob/user)
if(user.client && user.client.eye == user)
user.pointed(src)
return

/*
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/click_inf.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/mob/living/carbon/MiddleClickOn(atom/A)
/mob/living/carbon/AltMiddleClickOn(atom/A)
if(!stat && mind && iscarbon(A) && A != src)
var/datum/changeling/C = mind.changeling
if(C?.chosen_sting)
Expand Down
5 changes: 3 additions & 2 deletions code/_onclick/cyborg.dm
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@
return
return

//Middle click cycles through selected modules.
/mob/living/silicon/robot/MiddleClickOn(var/atom/A)
//Alt Middle click cycles through selected modules.
//Though we have "X" marcos for it and humans now can't swap hands using middle click, I'll let it be here
/mob/living/silicon/robot/AltMiddleClickOn(var/atom/A)
cycle_modules()
return

Expand Down
3 changes: 2 additions & 1 deletion code/_onclick/hud/ability_screen_objects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@
toggle_open(2) //forces the icons to refresh on screen

/mob/Life()
set waitfor = FALSE
UNLINT(..())
if(ability_master)
ability_master.update_spells(0)
Expand Down Expand Up @@ -410,4 +411,4 @@
for(var/obj/screen/ability/spell/spell in spell_objects)
spell.spell.silenced = amount
spell.spell.process()
spell.update_charge(1)
spell.update_charge(1)
4 changes: 2 additions & 2 deletions code/_onclick/rig.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/mob/living/MiddleClickOn(atom/A)
/mob/living/AltMiddleClickOn(atom/A)
if(get_preference_value(/datum/client_preference/hardsuit_activation) == GLOB.PREF_MIDDLE_CLICK)
if(HardsuitClickOn(A))
return
Expand Down Expand Up @@ -51,4 +51,4 @@
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
return 1
return 0
return 0
124 changes: 124 additions & 0 deletions code/controllers/subsystems/input.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
SUBSYSTEM_DEF(input)
name = "Input"
wait = 1 //SS_TICKER means this runs every tick
init_order = SS_INIT_INPUT
flags = SS_TICKER
priority = SS_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY

var/list/macro_sets
var/list/movement_keys
var/list/alt_movement_keys

/datum/controller/subsystem/input/Initialize()
setup_default_macro_sets()

setup_default_movement_keys()

initialized = TRUE

refresh_client_macro_sets()

return ..()

// This is for when macro sets are eventualy datumized
/datum/controller/subsystem/input/proc/setup_default_macro_sets()
var/list/static/default_macro_sets

if(default_macro_sets)
macro_sets = default_macro_sets
return

default_macro_sets = list(
"default" = list(
"Tab" = "\".winset \\\"input.focus=true?map.focus=true input.background-color=[COLOR_INPUT_DISABLED]:input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"",
"Back" = "\".winset \\\"input.focus=true input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs
"Any" = "\"KeyDown \[\[*\]\]\"",
"Any+UP" = "\"KeyUp \[\[*\]\]\"",
),
"old_default" = list(
"Tab" = "\".winset \\\"mainwindow.macro=old_hotkeys map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\"",
),
"old_hotkeys" = list(
"Tab" = "\".winset \\\"mainwindow.macro=old_default input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"",
"Back" = "\".winset \\\"input.focus=true input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs
"Any" = "\"KeyDown \[\[*\]\]\"",
"Any+UP" = "\"KeyUp \[\[*\]\]\"",
),
)

// Because i'm lazy and don't want to type all these out twice
var/list/old_default = default_macro_sets["old_default"]

var/list/static/oldmode_keys = list(
"North", "East", "South", "West",
"Northeast", "Southeast", "Northwest", "Southwest",
"Insert", "Delete", "Ctrl", "Alt", "Shift",
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
)

for(var/i in 1 to oldmode_keys.len)
var/key = oldmode_keys[i]
old_default[key] = "\"KeyDown [key]\""
old_default["[key]+UP"] = "\"KeyUp [key]\""

var/list/static/oldmode_ctrl_override_keys = list(
"W" = "W", "A" = "A", "S" = "S", "D" = "D", // movement
"1" = "1", "2" = "2", "3" = "3", "4" = "4", // intent
"B" = "B", // resist, rest
"E" = "E", // quick equip
"F" = "F", // intent left
"G" = "G", // intent right
"H" = "H", // stop pulling
"Q" = "Q", // drop
"R" = "R", // throw
"X" = "X", // switch hands
"Y" = "Y", // activate item
"Z" = "Z", // activate item
"T" = "T", // say, whisper
"M" = "M", // me
"O" = "O", // ooc
"L" = "L", // looc
"C" = "C", // stop pulling
)

for(var/i in 1 to oldmode_ctrl_override_keys.len)
var/key = oldmode_ctrl_override_keys[i]
var/override = oldmode_ctrl_override_keys[key]
old_default["Ctrl+[key]"] = "\"KeyDown [override]\""
old_default["Ctrl+[key]+UP"] = "\"KeyUp [override]\""

macro_sets = default_macro_sets

// For initially setting up or resetting to default the movement keys
/datum/controller/subsystem/input/proc/setup_default_movement_keys()
var/static/list/default_movement_keys = list(
"W" = NORTH, "A" = WEST, "S" = SOUTH, "D" = EAST, // WASD
"North" = NORTH, "West" = WEST, "South" = SOUTH, "East" = EAST, // Arrow keys & Numpad
)
var/static/list/azerty_movement_keys = list(
"Z" = NORTH, "Q" = WEST, "S" = SOUTH, "D" = EAST, // WASD
"North" = NORTH, "West" = WEST, "South" = SOUTH, "East" = EAST, // Arrow keys & Numpad
)
movement_keys = default_movement_keys.Copy()
alt_movement_keys = azerty_movement_keys.Copy()

// 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()

/datum/controller/subsystem/input/fire()
var/list/clients = GLOB.clients // Let's sing the list cache song
if(listclearnulls(clients)) // clear nulls before we run keyloop
log_world("Found a null in clients list!")
for(var/i in 1 to clients.len)
var/client/C = clients[i]
C.keyLoop()

/datum/controller/subsystem/input/Recover()
macro_sets = SSinput.macro_sets
movement_keys = SSinput.movement_keys
alt_movement_keys = SSinput.alt_movement_keys
7 changes: 5 additions & 2 deletions code/game/verbs/ooc.dm
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
/client/verb/ooc(message as text)
/client/verb/ooc(message = "" as text)
set name = "OOC"
set category = "OOC"

if(!message)
message = input(src.mob, "", "ooc \"text\"") as text|null

sanitize_and_communicate(/decl/communication_channel/ooc, src, message)

/client/verb/looc(message as text)
/client/verb/looc(message = "" as text)
set name = "LOOC"
set desc = "Local OOC, seen only by those in view. Remember: Just because you see someone that doesn't mean they see you."
set category = "OOC"
Expand Down
3 changes: 3 additions & 0 deletions code/modules/client/client_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@
prefs?.apply_post_login_preferences()
//[/INF]

if(SSinput.initialized)
set_macros()

//////////////
//DISCONNECT//
//////////////
Expand Down
32 changes: 32 additions & 0 deletions code/modules/keybindings/bindings_admin.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/datum/admins/key_down(_key, client/user)
switch(_key)
if("F5")
// if(user.keys_held["Shift"])
// user.get_mentor_say()
// else
user.get_admin_say()
return
if("F6")
user.admin_ghost()
return
if("F7")
player_panel()
return
if("F8")
user.cmd_admin_pm_panel()
return
if("F9")
user.invisimin()
return
if("F10")
user.get_dead_say()
return
..()

/client/proc/get_admin_say()
var/msg = input(src, null, "asay \"text\"") as text|null
cmd_admin_say(msg)

/client/proc/get_dead_say()
var/msg = input(src, null, "dsay \"text\"") as text
dsay(msg)
6 changes: 6 additions & 0 deletions code/modules/keybindings/bindings_ai.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/mob/living/silicon/ai/key_down(_key, client/user)
switch(_key)
if("4")
a_intent_change(INTENT_HOTKEY_LEFT)
return
return ..()
19 changes: 19 additions & 0 deletions code/modules/keybindings/bindings_atom.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// You might be wondering why this isn't client level. If focus is null, we don't want you to move.
// Only way to do that is to tie the behavior into the focus's keyLoop().

/atom/movable/keyLoop(client/user)
if(!user.keys_held["Ctrl"])
var/movement_dir = null
var/list/movement = SSinput.movement_keys
for(var/_key in user.keys_held)
movement_dir = movement_dir | movement[_key]
if(user.next_move_dir_add)
movement_dir |= user.next_move_dir_add
if(user.next_move_dir_sub)
movement_dir &= ~user.next_move_dir_sub
// Sanity checks in case you hold left and right and up to make sure you only go up
if((movement_dir & NORTH) && (movement_dir & SOUTH))
movement_dir &= ~(NORTH|SOUTH)
if((movement_dir & EAST) && (movement_dir & WEST))
movement_dir &= ~(EAST|WEST)
user.Move(get_step(src, movement_dir), movement_dir)
21 changes: 21 additions & 0 deletions code/modules/keybindings/bindings_carbon.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

/mob/living/carbon/key_down(_key, client/user)
user.keys_held[_key] = world.time
if(!user.keys_held["Shift"])
switch(_key)
if("R", "Southwest") // Southwest is End
toggle_throw_mode()
return
if("1")
a_intent_change(I_HELP)
return
if("2")
a_intent_change(I_DISARM)
return
if("3")
a_intent_change(I_GRAB)
return
if("4")
a_intent_change(I_HURT)
return
return ..()
Loading

0 comments on commit 7157515

Please sign in to comment.