diff --git a/code/__DEFINES/layers_planes.dm b/code/__DEFINES/layers_planes.dm index a6c31bf965..51b5978c4f 100644 --- a/code/__DEFINES/layers_planes.dm +++ b/code/__DEFINES/layers_planes.dm @@ -80,8 +80,9 @@ #define SPACEVINE_LAYER 4.8 #define SPACEVINE_MOB_LAYER 4.9 //#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define -#define GASFIRE_LAYER 5.05 -#define RIPPLE_LAYER 5.1 +#define ABOVE_FLY_LAYER 5.1 +#define GASFIRE_LAYER 5.2 +#define RIPPLE_LAYER 5.3 #define GHOST_LAYER 6 #define LOW_LANDMARK_LAYER 9 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index e0df69bfe9..2edef77dbf 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -290,6 +290,8 @@ #define HUMAN_FIRE_STACK_ICON_NUM 3 +#define TYPING_INDICATOR_TIMEOUT 5 MINUTES + #define GRAB_PIXEL_SHIFT_PASSIVE 6 #define GRAB_PIXEL_SHIFT_AGGRESSIVE 12 #define GRAB_PIXEL_SHIFT_NECK 16 diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 9ce96585d3..738d72c6bf 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -77,7 +77,7 @@ if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON) return - + var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["middle"]) ShiftMiddleClickOn(A) diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index 0970b23a16..1f8a03b3e7 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -34,9 +34,11 @@ SUBSYSTEM_DEF(input) "O" = "ooc", "Ctrl+O" = "looc", "T" = "say", - "Ctrl+T" = "whisper", + "Ctrl+T" = "say_indicator", + "Y" = "whisper", "M" = "me", - "Ctrl+M" = "subtle", + "Ctrl+M" = "me_indicator", + "5" = "subtle", "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs "Any" = "\"KeyDown \[\[*\]\]\"", "Any+UP" = "\"KeyUp \[\[*\]\]\"", @@ -51,7 +53,9 @@ SUBSYSTEM_DEF(input) "O" = "ooc", "L" = "looc", "T" = "say", + "Ctrl+T" = "say_indicator", "M" = "me", + "Ctrl+M" = "me_indicator", "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs "Any" = "\"KeyDown \[\[*\]\]\"", "Any+UP" = "\"KeyUp \[\[*\]\]\"", diff --git a/code/modules/keybindings/bindings_living.dm b/code/modules/keybindings/bindings_living.dm index ec6c5dd539..b338c5e899 100644 --- a/code/modules/keybindings/bindings_living.dm +++ b/code/modules/keybindings/bindings_living.dm @@ -23,5 +23,4 @@ lay_down() return - return ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 7444216f4b..c3f43cd6f0 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -104,6 +104,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both. var/icon_limbs //Overrides the icon used for the limbs of this species. Mainly for downstream, and also because hardcoded icons disgust me. Implemented and maintained as a favor in return for a downstream's implementation of synths. + /// Our default override for typing indicator state + var/typing_indicator_state + /////////// // PROCS // /////////// diff --git a/code/modules/mob/living/carbon/human/typing_indicator.dm b/code/modules/mob/living/carbon/human/typing_indicator.dm new file mode 100644 index 0000000000..16ed95790a --- /dev/null +++ b/code/modules/mob/living/carbon/human/typing_indicator.dm @@ -0,0 +1,2 @@ +/mob/living/carbon/human/get_typing_indicator_icon_state() + return dna?.species?.typing_indicator_state || ..() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 228028eb9b..1c92ffe9a5 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -5,6 +5,8 @@ hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD,RAD_HUD) pressure_resistance = 10 + typing_indicator_enabled = TRUE + var/resize = 1 //Badminnery resize var/lastattacker = null var/lastattackerckey = null diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 6a84162ea8..4b90191dcc 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -1,6 +1,8 @@ /mob/living/Moved() . = ..() update_turf_movespeed(loc) + //Hide typing indicator if we move. + clear_typing_indicator() if(is_shifted) is_shifted = FALSE pixel_x = get_standard_pixel_x_offset(lying) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 825f015ef4..46249dbfa6 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -130,3 +130,16 @@ var/siliconaccesstoggle = FALSE var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted. + + var/flavor_text = "" + var/flavor_text_2 = "" //version of the above that only lasts for the current round. + + ///////TYPING INDICATORS/////// + /// Set to true if we want to show typing indicators. + var/typing_indicator_enabled = FALSE + /// Default icon_state of our typing indicator. Currently only supports paths (because anything else is, as of time of typing this, unnecesary. + var/typing_indicator_state = /obj/effect/overlay/typing_indicator + /// The timer that will remove our indicator for early aborts (like when an user finishes their message) + var/typing_indicator_timerid + /// Current state of our typing indicator. Used for cut overlay, DO NOT RUNTIME ASSIGN OTHER THAN FROM SHOW/CLEAR. Used to absolutely ensure we do not get stuck overlays. + var/typing_indicator_current diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index f348829b71..ac89fc2445 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -1,12 +1,53 @@ //Speech verbs. -/mob/verb/say_verb(message as text) - set name = "Say" +// the _keybind verbs uses "as text" versus "as text|null" to force a popup when pressed by a keybind. +/mob/verb/say_typing_indicator() + set name = "say_indicator" + set hidden = TRUE set category = "IC" + display_typing_indicator() + var/message = input(usr, "", "say") as text|null + // If they don't type anything just drop the message. + clear_typing_indicator() // clear it immediately! + if(!length(message)) + return + return say_verb(message) + +/mob/verb/say_verb(message as text) + set name = "say" + set category = "IC" + if(!length(message)) + return if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return - if(message) - say(message) + clear_typing_indicator() // clear it immediately! + say(message) + +/mob/verb/me_typing_indicator() + set name = "me_indicator" + set hidden = TRUE + set category = "IC" + display_typing_indicator() + var/message = input(usr, "", "me") as message|null + // If they don't type anything just drop the message. + clear_typing_indicator() // clear it immediately! + if(!length(message)) + return + return me_verb(message) + +/mob/verb/me_verb(message as message) + set name = "me" + set category = "IC" + if(!length(message)) + return + if(GLOB.say_disabled) //This is here to try to identify lag problems + to_chat(usr, "Speech is currently admin-disabled.") + return + + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) + clear_typing_indicator() // clear it immediately! + + usr.emote("me",1,message,TRUE) /mob/say_mod(input, message_mode) var/customsayverb = findtext(input, "*") @@ -19,6 +60,8 @@ /mob/verb/whisper_verb(message as text) set name = "Whisper" set category = "IC" + if(!length(message)) + return if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return @@ -27,18 +70,6 @@ /mob/proc/whisper(message, datum/language/language=null) say(message, language) //only living mobs actually whisper, everything else just talks -/mob/verb/me_verb(message as message) - set name = "Me" - set category = "IC" - - if(GLOB.say_disabled) //This is here to try to identify lag problems - to_chat(usr, "Speech is currently admin-disabled.") - return - - message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) - - usr.emote("me",1,message,TRUE) - /mob/proc/say_dead(var/message) var/name = real_name var/alt_name = "" diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index 377bb1c5fc..ec82b41cca 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -23,7 +23,6 @@ proc/get_top_level_mob(var/mob/S) message = null mob_type_blacklist_typecache = list(/mob/living/brain) - /datum/emote/living/subtle/proc/check_invalid(mob/user, input) if(stop_bad_mime.Find(input, 1, 1)) to_chat(user, "Invalid emote.") diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm new file mode 100644 index 0000000000..f28cbe4385 --- /dev/null +++ b/code/modules/mob/typing_indicator.dm @@ -0,0 +1,47 @@ +/// state = overlay/image/object/type/whatever add_overlay will accept +GLOBAL_LIST_EMPTY(typing_indicator_overlays) + +/// Fetches the typing indicator we'll use from GLOB.typing_indicator_overlays +/mob/proc/get_indicator_overlay(state) + . = GLOB.typing_indicator_overlays[state] + if(.) + return + // doesn't exist, make it and cache it + if(ispath(state)) + . = GLOB.typing_indicator_overlays[state] = state + // We only support paths for now because anything else isn't necessary yet. + +/// Gets the state we will use for typing indicators. Defaults to src.typing_indicator_state +/mob/proc/get_typing_indicator_icon_state() + return typing_indicator_state + +/** + * Displays typing indicator. + * @param timeout_override - Sets how long until this will disappear on its own without the user finishing their message or logging out. Defaults to src.typing_indicator_timeout + * @param state_override - Sets the state that we will fetch. Defaults to src.get_typing_indicator_icon_state() + * @param force - shows even if src.typing_indcator_enabled is FALSE. + */ +/mob/proc/display_typing_indicator(timeout_override = TYPING_INDICATOR_TIMEOUT, state_override = get_typing_indicator_icon_state(), force = FALSE) + if((!typing_indicator_enabled && !force) || typing_indicator_current) + return + typing_indicator_current = state_override + add_overlay(state_override) + typing_indicator_timerid = addtimer(CALLBACK(src, .proc/clear_typing_indicator), timeout_override, TIMER_STOPPABLE) + +/** + * Removes typing indicator. + */ +/mob/proc/clear_typing_indicator() + cut_overlay(typing_indicator_current) + typing_indicator_current = null + if(typing_indicator_timerid) + deltimer(typing_indicator_timerid) + typing_indicator_timerid = null + +/// Default typing indicator +/obj/effect/overlay/typing_indicator + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + icon = 'icons/mob/talk.dmi' + icon_state = "normal_typing" + appearance_flags = RESET_COLOR | TILE_BOUND | PIXEL_SCALE + layer = ABOVE_FLY_LAYER diff --git a/icons/mob/talk.dmi b/icons/mob/talk.dmi index 05fe6f5623..0a56321037 100644 Binary files a/icons/mob/talk.dmi and b/icons/mob/talk.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 9bcc2ed53e..916d3c56fa 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2243,6 +2243,7 @@ #include "code\modules\mob\say_vr.dm" #include "code\modules\mob\status_procs.dm" #include "code\modules\mob\transform_procs.dm" +#include "code\modules\mob\typing_indicator.dm" #include "code\modules\mob\update_icons.dm" #include "code\modules\mob\camera\camera.dm" #include "code\modules\mob\dead\dead.dm" @@ -2374,6 +2375,7 @@ #include "code\modules\mob\living\carbon\human\say.dm" #include "code\modules\mob\living\carbon\human\species.dm" #include "code\modules\mob\living\carbon\human\status_procs.dm" +#include "code\modules\mob\living\carbon\human\typing_indicator.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\species_types\abductors.dm" #include "code\modules\mob\living\carbon\human\species_types\android.dm" @@ -3320,6 +3322,7 @@ #include "interface\interface.dm" #include "interface\menu.dm" #include "interface\stylesheet.dm" +#include "interface\skin.dmf" #include "modular_citadel\code\__HELPERS\list2list.dm" #include "modular_citadel\code\__HELPERS\lists.dm" #include "modular_citadel\code\__HELPERS\mobs.dm"