SSInput and Diagonal Movement

This commit is contained in:
Chompstation Bot
2021-07-07 18:35:44 +00:00
parent 7e10238662
commit 1513fbe0cb
20 changed files with 4445 additions and 113 deletions

View File

@@ -11,6 +11,9 @@
//#define ZASDBG // Uncomment to turn on super detailed ZAS debugging that probably won't even compile.
#define MULTIZAS // Uncomment to turn on Multi-Z ZAS Support!
// Movement Compile Options
//#define CARDINAL_INPUT_ONLY // Uncomment to disable diagonal player movement (restore previous cardinal-moves-only behavior)
// Comment/Uncomment this to turn off/on shuttle code debugging logs
#define DEBUG_SHUTTLES

21
code/__defines/input.dm Normal file
View File

@@ -0,0 +1,21 @@
// Bitflags for the move_keys_held bitfield.
#define NORTH_KEY (1<<0)
#define SOUTH_KEY (1<<1)
#define EAST_KEY (1<<2)
#define WEST_KEY (1<<3)
#define W_KEY (1<<4)
#define S_KEY (1<<5)
#define D_KEY (1<<6)
#define A_KEY (1<<7)
// Combine the held WASD and arrow keys together (OR) into byond N/S/E/W dir
#define MOVEMENT_KEYS_TO_DIR(MK) ((((MK)>>4)|(MK))&(ALL_CARDINALS))
// Bitflags for pressed modifier keys.
// Values chosen specifically to not conflict with dir bitfield, in case we want to smoosh them together.
#define CTRL_KEY (1<<8)
#define SHIFT_KEY (1<<9)
#define ALT_KEY (1<<10)
// Uncomment to get a lot of debug logging for movement keys.
// #define DEBUG_INPUT(A) to_world_log(A)
#define DEBUG_INPUT(A)

View File

@@ -56,6 +56,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_DBCORE 41 //CHOMPEdit
#define INIT_ORDER_SQLITE 40
#define INIT_ORDER_MEDIA_TRACKS 38 // Gotta get that lobby music up, yo
#define INIT_ORDER_INPUT 37
#define INIT_ORDER_CHEMISTRY 35
#define INIT_ORDER_VIS 32
#define INIT_ORDER_SKYBOX 30
@@ -115,6 +116,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_PROJECTILES 150
#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
// Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed)
// TODO - I don't really like the location of this macro define. Consider it. ~Leshana

View File

@@ -96,6 +96,19 @@
if ("SOUTHEAST") return 6
if ("SOUTHWEST") return 10
// Turns a direction into text showing all bits set
/proc/dirs2text(direction)
if(!direction)
return ""
var/list/dirs = list()
if(direction & NORTH) dirs += "NORTH"
if(direction & SOUTH) dirs += "SOUTH"
if(direction & EAST) dirs += "EAST"
if(direction & WEST) dirs += "WEST"
if(direction & UP) dirs += "UP"
if(direction & DOWN) dirs += "DOWN"
return dirs.Join(" ")
// Converts an angle (degrees) into an ss13 direction
/proc/angle2dir(var/degree)
degree = (degree + 22.5) % 365 // 22.5 = 45 / 2

View File

@@ -0,0 +1,13 @@
SUBSYSTEM_DEF(input)
name = "Input"
wait = 1 // SS_TICKER means this runs every tick
init_order = INIT_ORDER_INPUT
flags = SS_TICKER
priority = FIRE_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
/datum/controller/subsystem/input/fire()
var/list/clients = GLOB.clients // Let's sing the list cache song
for(var/i in 1 to clients.len)
var/client/C = clients[i]
C?.keyLoop()

File diff suppressed because it is too large Load Diff

View File

@@ -80,3 +80,32 @@
// Runechat messages
var/list/seen_messages
///////////
// INPUT //
///////////
/// Bitfield of modifier keys (Shift, Ctrl, Alt) held currently.
var/mod_keys_held = 0
/// Bitfield of movement keys (WASD/Cursor Keys) held currently.
var/move_keys_held = 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.
/// Bitfield of movement dirs that were pressed down *this* cycle (even if not currently held).
/// Note that only dirs that actually are first pressed down during this cycle are included, if it was still held from last cycle it won't be in here.
/// On next move, add this dir to the move that would otherwise be done
var/next_move_dir_add
/// Bitfield of movement dirs that were released *this* cycle (even if currently held).
/// Note that only dirs that were already held at the start of this cycle are included, if it pressed then released it won't be in here.
/// On next move, subtract this dir from the move that would otherwise be done
var/next_move_dir_sub
#ifdef CARDINAL_INPUT_ONLY
/// Movement dir of the most recently pressed movement key. Used in cardinal-only movement mode.
var/last_move_dir_pressed = NONE
#endif

View File

@@ -0,0 +1,45 @@
// 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().
// THE TRADITIONAL STYLE FROM /TG (modified)
/atom/movable/keyLoop(client/user)
// Bail out if the user is holding the "face direction" key (Maybe?)
// TODO - I think this breaks non-hotkeys WASD movement, so maybe adopt the /tg solution)
if(user.mod_keys_held & CTRL_KEY)
return
var/must_call_move = FALSE
var/movement_dir = MOVEMENT_KEYS_TO_DIR(user.move_keys_held)
if(user.next_move_dir_add)
must_call_move = TRUE // So that next_move_dir_add gets cleared if its time.
movement_dir |= user.next_move_dir_add
if(user.next_move_dir_sub)
DEBUG_INPUT("[(user.next_move_dir_sub & movement_dir) ? "Actually" : "Want to"] subtract [dirs2text(user.next_move_dir_sub)] from [dirs2text(movement_dir)]")
must_call_move = TRUE // So that next_move_dir_sub gets cleared if its time.
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|SOUTH)) == (NORTH|SOUTH))
movement_dir &= ~(NORTH|SOUTH)
if((movement_dir & (EAST|WEST)) == (EAST|WEST))
movement_dir &= ~(EAST|WEST)
#ifdef CARDINAL_INPUT_ONLY
if(movement_dir & user.last_move_dir_pressed)
movement_dir = user.last_move_dir_pressed
else if (movement_dir == NORTHEAST || movement_dir == NORTHWEST)
DEBUG_INPUT("overriding to NORTH: movement_dir=[dirs2text(movement_dir)] last=[dirs2text(user.last_move_dir_pressed)]")
movement_dir = NORTH
else if (movement_dir == SOUTHEAST || movement_dir == SOUTHWEST)
DEBUG_INPUT("overriding to SOUTH: movement_dir=[dirs2text(movement_dir)] last=[dirs2text(user.last_move_dir_pressed)]")
movement_dir = SOUTH
#endif
// Compensate for client camera spinning (client.dir) so our movement still makes sense I guess.
if(movement_dir) // Only compensate if non-zero, as byond will auto-fill dir otherwise
movement_dir = turn(movement_dir, -dir2angle(user.dir))
// Move, but only if we actually are planing to move, or we need to clear the next move vars
if(movement_dir || must_call_move)
user.Move(get_step(src, movement_dir), movement_dir)

View File

@@ -0,0 +1,77 @@
// TODO - Optimize this into numerics if this ends up working out
var/global/list/MOVE_KEY_MAPPINGS = list(
"North" = NORTH_KEY,
"South" = SOUTH_KEY,
"East" = EAST_KEY,
"West" = WEST_KEY,
"W" = W_KEY,
"A" = A_KEY,
"S" = S_KEY,
"D" = D_KEY,
"Shift" = SHIFT_KEY,
"Ctrl" = CTRL_KEY,
"Alt" = ALT_KEY,
)
// These verbs are called for all movemen key press and release events
/client/verb/moveKeyDown(movekeyName as text)
set instant = TRUE
set hidden = TRUE
// set name = ".movekeydown"
set name = "KeyDown"
// Map text sent by skin.dmf to our numeric codes. (This can be optimized away once we update skin.dmf)
var/movekey = MOVE_KEY_MAPPINGS[movekeyName]
// Validate input. Must be one (and only one) of the key codes)
if(isnull(movekey) || (movekey & ~0xFFF) || (movekey & (movekey - 1)))
log_debug("Client [ckey] sent an illegal movement key down: [movekeyName] ([movekey])")
return
// Record that we are now holding the key!
move_keys_held |= (movekey & 0x0FF)
mod_keys_held |= (movekey & 0xF00)
// If we were NOT holding at the start of this move cycle and pressed it, remember that.
var/movement = MOVEMENT_KEYS_TO_DIR(movekey)
if(movement && !(next_move_dir_sub & movement) && !(mod_keys_held & CTRL_KEY)) // TODO-LESHANA - Possibly not holding Alt either
DEBUG_INPUT("Saving [dirs2text(movement)] into next_move_dir_ADD")
next_move_dir_add |= movement
#ifdef CARDINAL_INPUT_ONLY
if(movement)
DEBUG_INPUT("set last=[dirs2text(movement)]")
last_move_dir_pressed = movement
#endif
mob.focus?.key_down(movekey, src)
/client/verb/moveKeyUp(movekeyName as text)
set instant = TRUE
set hidden = TRUE
// set name = ".movekeyup"
set name = "KeyUp"
// Map text sent by skin.dmf to our numeric codes. (This can be optimized away once we update skin.dmf)
var/movekey = MOVE_KEY_MAPPINGS[movekeyName]
// Validate input. Must be one (and only one) of the key codes)
if(isnull(movekey) || (movekey & ~0xFFF) || (movekey & (movekey - 1)))
log_debug("Client [ckey] sent an illegal movement key up: [movekeyName] ([movekey])")
return
// Clear bit indicating we were holding the key
move_keys_held &= ~movekey
mod_keys_held &= ~movekey
// If we were holding at the start of this move cycle and now relased it, remember that.
var/movement = MOVEMENT_KEYS_TO_DIR(movekey)
if(movement && !(next_move_dir_add & movement))
DEBUG_INPUT("Saving [dirs2text(movement)] into next_move_dir_SUB")
next_move_dir_sub |= movement
mob.focus?.key_up(movekey, src)
// Called every game tick
/client/keyLoop()
mob.focus?.keyLoop(src)

View File

@@ -0,0 +1,42 @@
# In-code keypress handling system
This whole system is heavily based off of forum_account's keyboard library.
Thanks to forum_account for saving the day, the library can be found
[here](https://secure.byond.com/developer/Forum_account/Keyboard)!
.dmf macros have some very serious shortcomings. For example, they do not allow reusing parts
of one macro in another, so giving cyborgs their own shortcuts to swap active module couldn't
inherit the movement that all mobs should have anyways. The webclient only supports one macro,
so having more than one was problematic. Additionally each keybind has to call an actual
verb, which meant a lot of hidden verbs that just call one other proc. Also our existing
macro was really bad and tied unrelated behavior into `Northeast()`, `Southeast()`, `Northwest()`,
and `Southwest()`.
The basic premise of this system is to not screw with .dmf macro setup at all and handle
pressing those keys in the code instead. We have every key call `client.keyDown()`
or `client.keyUp()` with the pressed key as an argument. Certain keys get processed
directly by the client because they should be doable at any time, then we call
`keyDown()` or `keyUp()` on the client's holder and the client's mob's focus.
By default `mob.focus` is the mob itself, but you can set it to any datum to give control of a
client's keypresses to another object. This would be a good way to handle a menu or driving
a mech. You can also set it to null to disregard input from a certain user.
Movement is handled by having each client call `client.keyLoop()` every game tick.
As above, this calls holder and `focus.keyLoop()`. `atom/movable/keyLoop()` handles movement
Try to keep the calculations in this proc light. It runs every tick for every client after all!
You can also tell which keys are being held down now. Each client a list of keys pressed called
`keys_held`. Each entry is a key as a text string associated with the world.time when it was
pressed.
No client-set keybindings at this time, but it shouldn't be too hard if someone wants.
Notes about certain keys:
* `Tab` has client-sided behavior but acts normally
* `T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away.
* `\` needs to be escaped in the dmf so any usage is `\\`
You cannot `TICK_CHECK` or check `world.tick_usage` inside of procs called by key down and up
events. They happen outside of a byond tick and have no meaning there. Key looping
works correctly since it's part of a subsystem, not direct input.

View File

@@ -0,0 +1,34 @@
// 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
return
/datum/proc/key_up(key, client/user) // Called when a key is released
return
/datum/proc/keyLoop(client/user) // Called once every server tick
set waitfor = FALSE
return
/// Set mob's focus
/// TODO - Do we even need this concept?
/mob/proc/set_focus(datum/new_focus)
if(focus == new_focus)
return
focus = new_focus
/// Turns a keys bitfield into text showing all bits set
/proc/keys2text(keys)
if(!keys)
return ""
var/list/out = list()
if(keys & NORTH_KEY) out += "NORTH"
if(keys & SOUTH_KEY) out += "SOUTH"
if(keys & EAST_KEY) out += "EAST"
if(keys & WEST_KEY) out += "WEST"
if(keys & W_KEY) out += "W"
if(keys & A_KEY) out += "A"
if(keys & S_KEY) out += "S"
if(keys & D_KEY) out += "D"
if(keys & CTRL_KEY) out += "CTRL"
if(keys & SHIFT_KEY) out += "SHIFT"
if(keys & ALT_KEY) out += "ALT"
return out.Join(" ")

View File

@@ -3,7 +3,7 @@
/mob/living
var/ooc_notes = null
appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER
appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER|LONG_GLIDE
var/hunger_rate = DEFAULT_HUNGER_FACTOR
//custom say verbs
var/custom_say = null

View File

@@ -197,7 +197,15 @@ default behaviour is:
now_pushing = 0
return
step(AM, t)
var/turf/T = AM.loc
var/turf/T2 = get_step(AM,t)
if(!T2) // Map edge
now_pushing = 0
return
var/move_time = movement_delay(loc, t)
move_time = DS2NEARESTTICK(move_time)
if(AM.Move(T2, t, move_time))
Move(T, t, move_time)
if(ishuman(AM) && AM:grabbed_by)
for(var/obj/item/weapon/grab/G in AM:grabbed_by)

File diff suppressed because it is too large Load Diff

View File

@@ -231,3 +231,5 @@
var/in_enclosed_vehicle = 0 //For mechs and fighters ambiance. Can be used in other cases.
var/list/progressbars = null //VOREStation Edit
var/datum/focus //What receives our keyboard inputs. src by default // VOREStation Add - Key Handling

View File

@@ -140,22 +140,32 @@
// Used many times below, faster reference.
var/atom/loc = my_mob.loc
// We're controlling an object which is SOMEHOW DIFFERENT FROM AN EYE??
// We're controlling an object which is when admins possess an object.
if(my_mob.control_object)
Move_object(direct)
// Ghosty mob movement
if(my_mob.incorporeal_move && isobserver(my_mob))
Process_Incorpmove(direct)
DEBUG_INPUT("--------")
next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up.
next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists.
return
// We're in the middle of another move we've already decided to do
if(moving)
log_debug("Client [src] attempted to move while moving=[moving]")
return 0
// We're still cooling down from the last move
if(!my_mob.checkMoveCooldown())
return
DEBUG_INPUT("--------")
next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up.
next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists.
if(!n || !direct)
return
// If dead and we try to move in our mob, it leaves our body
if(my_mob.stat == DEAD && isliving(my_mob) && !my_mob.forbid_seeing_deadchat)
@@ -287,6 +297,10 @@
else
. = my_mob.SelfMove(n, direct, total_delay)
// If we ended up moving diagonally, increase delay.
if((direct & (direct - 1)) && mob.loc == n)
my_mob.setMoveCooldown(total_delay * 2)
// If we have a grab
var/list/grablist = my_mob.ret_grab()
if(LAZYLEN(grablist))

View File

@@ -2,9 +2,24 @@ macro "borghotkeymode"
elem
name = "TAB"
command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5\""
elem
name = "CENTER+REP"
command = ".center"
elem
name = "Shift"
command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem
name = "NORTHEAST"
command = ".northeast"
@@ -24,8 +39,11 @@ macro "borghotkeymode"
name = "CTRL+WEST"
command = "westface"
elem
name = "WEST+REP"
command = ".west"
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem
name = "ALT+NORTH"
command = "northfaceperm"
@@ -33,8 +51,11 @@ macro "borghotkeymode"
name = "CTRL+NORTH"
command = "northface"
elem
name = "NORTH+REP"
command = ".moveup"
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem
name = "ALT+EAST"
command = "eastfaceperm"
@@ -42,18 +63,18 @@ macro "borghotkeymode"
name = "CTRL+EAST"
command = "eastface"
elem
name = "EAST+REP"
command = ".moveright"
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem
name = "ALT+SOUTH"
command = "southfaceperm"
elem
name = "CTRL+SOUTH"
command = "southface"
elem
name = "SOUTH+REP"
command = ".movedown"
elem
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
elem
@@ -65,6 +86,11 @@ macro "borghotkeymode"
elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem
name = "INSERT"
command = "a-intent right"
@@ -99,17 +125,17 @@ macro "borghotkeymode"
name = "5"
command = ".me"
elem
name = "A+REP"
command = ".moveleft"
name = "A"
command = "KeyDown A"
elem
name = "A+UP"
command = "KeyUp A"
elem
name = "CTRL+A+REP"
command = ".moveleft"
elem
name = "D+REP"
command = ".moveright"
elem
name = "CTRL+D+REP"
command = ".moveright"
name = "D"
command = "KeyDown D"
elem
name = "D+UP"
command = "KeyUp D"
elem
name = "F"
command = "a-intent left"
@@ -141,20 +167,20 @@ macro "borghotkeymode"
name = "CTRL+R"
command = ".southwest"
elem "s_key"
name = "S+REP"
command = ".movedown"
elem
name = "CTRL+S+REP"
command = ".movedown"
name = "S"
command = "KeyDown S"
elem
name = "S+UP"
command = "KeyUp S"
elem
name = "T"
command = ".say"
elem "w_key"
name = "W+REP"
command = ".moveup"
elem
name = "CTRL+W+REP"
command = ".moveup"
name = "W"
command = "KeyDown W"
elem
name = "W+UP"
command = "KeyUp W"
elem
name = "X"
command = ".northeast"
@@ -235,9 +261,24 @@ macro "macro"
elem
name = "TAB"
command = ".winset \"mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true\""
elem
name = "CENTER+REP"
command = ".center"
elem
name = "Shift"
command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem
name = "NORTHEAST"
command = ".northeast"
@@ -257,8 +298,11 @@ macro "macro"
name = "CTRL+WEST"
command = "westface"
elem
name = "WEST+REP"
command = ".moveleft"
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem
name = "ALT+NORTH"
command = "northfaceperm"
@@ -266,8 +310,11 @@ macro "macro"
name = "CTRL+NORTH"
command = "northface"
elem
name = "NORTH+REP"
command = ".moveup"
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem
name = "ALT+EAST"
command = "eastfaceperm"
@@ -275,18 +322,18 @@ macro "macro"
name = "CTRL+EAST"
command = "eastface"
elem
name = "EAST+REP"
command = ".moveright"
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem
name = "ALT+SOUTH"
command = "southfaceperm"
elem
name = "CTRL+SOUTH"
command = "southface"
elem
name = "SOUTH+REP"
command = ".movedown"
elem
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
elem
@@ -298,6 +345,11 @@ macro "macro"
elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem
name = "INSERT"
command = "a-intent right"
@@ -317,11 +369,17 @@ macro "macro"
name = "CTRL+4"
command = "a-intent harm"
elem
name = "CTRL+A+REP"
command = ".moveleft"
name = "CTRL+A"
command = "KeyDown A"
elem
name = "CTRL+A+UP"
command = "KeyUp A"
elem
name = "CTRL+D+REP"
command = ".moveright"
name = "CTRL+D"
command = "KeyDown D"
elem
name = "CTRL+D+UP"
command = "KeyUp D"
elem
name = "CTRL+E"
command = "quick-equip"
@@ -338,11 +396,17 @@ macro "macro"
name = "CTRL+R"
command = ".southwest"
elem
name = "CTRL+S+REP"
command = ".movedown"
name = "CTRL+S"
command = "KeyDown S"
elem
name = "CTRL+S+UP"
command = "KeyUp S"
elem
name = "CTRL+W+REP"
command = ".moveup"
name = "CTRL+W"
command = "KeyDown W"
elem
name = "CTRL+W+UP"
command = "KeyUp W"
elem
name = "CTRL+X"
command = ".northeast"
@@ -420,9 +484,24 @@ macro "hotkeymode"
elem
name = "TAB"
command = ".winset \"mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true\""
elem
name = "CENTER+REP"
command = ".center"
elem
name = "Shift"
command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem
name = "NORTHEAST"
command = ".northeast"
@@ -442,8 +521,11 @@ macro "hotkeymode"
name = "CTRL+WEST"
command = "westface"
elem
name = "WEST+REP"
command = ".moveleft"
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem
name = "ALT+NORTH"
command = "northfaceperm"
@@ -451,8 +533,11 @@ macro "hotkeymode"
name = "CTRL+NORTH"
command = "northface"
elem
name = "NORTH+REP"
command = ".moveup"
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem
name = "ALT+EAST"
command = "eastfaceperm"
@@ -460,18 +545,18 @@ macro "hotkeymode"
name = "CTRL+EAST"
command = "eastface"
elem
name = "EAST+REP"
command = ".moveright"
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem
name = "ALT+SOUTH"
command = "southfaceperm"
elem
name = "CTRL+SOUTH"
command = "southface"
elem
name = "SOUTH+REP"
command = ".movedown"
elem
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
elem
@@ -483,6 +568,11 @@ macro "hotkeymode"
elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem
name = "INSERT"
command = "a-intent right"
@@ -520,17 +610,17 @@ macro "hotkeymode"
name = "6"
command = ".Subtle"
elem
name = "A+REP"
command = ".moveleft"
name = "A"
command = "KeyDown A"
elem
name = "A+UP"
command = "KeyUp A"
elem
name = "CTRL+A+REP"
command = ".moveleft"
elem
name = "D+REP"
command = ".moveright"
elem
name = "CTRL+D+REP"
command = ".moveright"
name = "D"
command = "KeyDown D"
elem
name = "D+UP"
command = "KeyUp D"
elem
name = "E"
command = "quick-equip"
@@ -574,20 +664,20 @@ macro "hotkeymode"
name = "CTRL+R"
command = ".southwest"
elem "s_key"
name = "S+REP"
command = ".movedown"
elem
name = "CTRL+S+REP"
command = ".movedown"
name = "S"
command = "KeyDown S"
elem
name = "S+UP"
command = "KeyUp S"
elem
name = "T"
command = ".say"
elem "w_key"
name = "W+REP"
command = ".moveup"
elem
name = "CTRL+W+REP"
command = ".moveup"
name = "W"
command = "KeyDown W"
elem
name = "W+UP"
command = "KeyUp W"
elem
name = "X"
command = ".northeast"
@@ -674,9 +764,24 @@ macro "borgmacro"
elem
name = "TAB"
command = ".winset \"mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\""
elem
name = "CENTER+REP"
command = ".center"
elem
name = "Shift"
command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem
name = "NORTHEAST"
command = ".northeast"
@@ -696,8 +801,11 @@ macro "borgmacro"
name = "CTRL+WEST"
command = "westface"
elem
name = "WEST+REP"
command = ".moveleft"
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem
name = "ALT+NORTH"
command = "northfaceperm"
@@ -705,8 +813,11 @@ macro "borgmacro"
name = "CTRL+NORTH"
command = "northface"
elem
name = "NORTH+REP"
command = ".moveup"
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem
name = "ALT+EAST"
command = "eastfaceperm"
@@ -714,18 +825,18 @@ macro "borgmacro"
name = "CTRL+EAST"
command = "eastface"
elem
name = "EAST+REP"
command = ".moveright"
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem
name = "ALT+SOUTH"
command = "southfaceperm"
elem
name = "CTRL+SOUTH"
command = "southface"
elem
name = "SOUTH+REP"
command = ".movedown"
elem
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
elem
@@ -737,6 +848,11 @@ macro "borgmacro"
elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem
name = "INSERT"
command = "a-intent right"
@@ -756,11 +872,17 @@ macro "borgmacro"
name = "CTRL+4"
command = "a-intent left"
elem
name = "CTRL+A+REP"
command = ".moveleft"
name = "CTRL+A"
command = "KeyDown A"
elem
name = "CTRL+A+UP"
command = "KeyUp A"
elem
name = "CTRL+D+REP"
command = ".moveright"
name = "CTRL+D"
command = "KeyDown D"
elem
name = "CTRL+D+UP"
command = "KeyUp D"
elem
name = "CTRL+F"
command = "a-intent left"
@@ -774,11 +896,17 @@ macro "borgmacro"
name = "CTRL+R"
command = ".southwest"
elem
name = "CTRL+S+REP"
command = ".movedown"
name = "CTRL+S"
command = "KeyDown S"
elem
name = "CTRL+S+UP"
command = "KeyUp S"
elem
name = "CTRL+W+REP"
command = ".moveup"
name = "CTRL+W"
command = "KeyDown W"
elem
name = "CTRL+W+UP"
command = "KeyUp W"
elem
name = "CTRL+X"
command = ".northeast"

View File

@@ -249,7 +249,7 @@
var/mob/living/carbon/human/user = AM
var/choice = tgui_alert(usr, "Do you want to depart via the tram? Your character will leave the round.","Departure",list("Yes","No"))
var/choice = tgui_alert(user, "Do you want to depart via the tram? Your character will leave the round.","Departure",list("Yes","No"))
if(user && Adjacent(user) && choice == "Yes")
var/mob/observer/dead/newghost = user.ghostize()
newghost.timeofdeath = world.time

View File

@@ -132,7 +132,7 @@ export const releaseHeldKeys = () => {
if (keyState[byondKeyCode]) {
keyState[byondKeyCode] = false;
logger.log(`releasing key "${byondKeyCode}"`);
Byond.command(`KeyUp "${byondKeyCode}"`);
Byond.command(`TguiKeyUp "${byondKeyCode}"`);
}
}
};

View File

@@ -51,6 +51,7 @@
#include "code\__defines\gamemode.dm"
#include "code\__defines\holomap.dm"
#include "code\__defines\hoses.dm"
#include "code\__defines\input.dm"
#include "code\__defines\instruments.dm"
#include "code\__defines\integrated_circuits.dm"
#include "code\__defines\inventory_sizes.dm"
@@ -281,6 +282,7 @@
#include "code\controllers\subsystems\garbage.dm"
#include "code\controllers\subsystems\holomaps.dm"
#include "code\controllers\subsystems\inactivity.dm"
#include "code\controllers\subsystems\input.dm"
#include "code\controllers\subsystems\job.dm"
#include "code\controllers\subsystems\lighting.dm"
#include "code\controllers\subsystems\machines.dm"
@@ -2602,6 +2604,9 @@
#include "code\modules\integrated_electronics\subtypes\trig.dm"
#include "code\modules\integrated_electronics\subtypes\z_mixed_ch.dm"
#include "code\modules\integrated_electronics\~defines\~defines.dm"
#include "code\modules\keybindings\bindings_atom.dm"
#include "code\modules\keybindings\bindings_movekeys.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"