Skip to content

Commit

Permalink
Fixes custom bubbles/typing indicators after 3 years. Adds new animat…
Browse files Browse the repository at this point in the history
…ed ones. (#11968)

* at last, bubbles are fixed

* traitify variable

tgstation/tgstation#80122

* commandbar nice

tgstation/tgstation#83081
  • Loading branch information
Tsar-Salat authored Dec 24, 2024
1 parent bf02393 commit d9b15bc
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 40 deletions.
1 change: 1 addition & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -2439,6 +2439,7 @@
#include "code\modules\client\verbs\ooc.dm"
#include "code\modules\client\verbs\ping.dm"
#include "code\modules\client\verbs\suicide.dm"
#include "code\modules\client\verbs\typing.dm"
#include "code\modules\client\verbs\who.dm"
#include "code\modules\clothing\chameleon.dm"
#include "code\modules\clothing\clothing.dm"
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai

/// this object has been frozen
#define TRAIT_FROZEN "frozen"

/// Trait given to a mob that is currently thinking (giving off the "thinking" icon), used in an IC context
#define TRAIT_THINKING_IN_CHARACTER "currently_thinking_IC"

///Turf trait for when a turf is transparent
#define TURF_Z_TRANSPARENT_TRAIT "turf_z_transparent"

Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/traits/sources.dm
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@
/// Trait given to an atom/movable when they orbit something.
#define ORBITING_TRAIT "orbiting"

/// This trait comes from when a mob is currently typing.
#define CURRENTLY_TYPING_TRAIT "currently_typing"

#define VENTCRAWLING_TRAIT "ventcrawling"
#define SPECIES_FLIGHT_TRAIT "species-flight"
#define NO_GRAVITY_TRAIT "no-gravity"
Expand Down
1 change: 1 addition & 0 deletions code/_globalvars/traits/_traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NOMOBSWAP" = TRAIT_NOMOBSWAP,
"TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION,
"TRAIT_THERMAL_VISION" = TRAIT_THERMAL_VISION,
"TRAIT_THINKING_IN_CHARACTER" = TRAIT_THINKING_IN_CHARACTER,
"TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING,
"TRAIT_ABDUCTOR_SCIENTIST_TRAINING" = TRAIT_ABDUCTOR_SCIENTIST_TRAINING,
"TRAIT_SURGEON" = TRAIT_SURGEON,
Expand Down
2 changes: 2 additions & 0 deletions code/datums/mocking/client.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
/// The view of the client, similar to /client/var/view
var/view = "17x15"

var/typing_indicators

/datum/client_interface/proc/should_include_for_role(banning_key = BAN_ROLE_ALL_ANTAGONISTS, role_preference_key = null, poll_ignore_key = null, req_hours = 0, feedback = FALSE)
return TRUE
5 changes: 5 additions & 0 deletions code/modules/client/client_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
cmd_mentor_pm(href_list["mentor_msg"], null)
return TRUE

if(href_list["commandbar_typing"])
handle_commandbar_typing(href_list)

switch(href_list["_src_"])
if("holder")
hsrc = holder
Expand Down Expand Up @@ -209,6 +212,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
tgui_say = new(src, "tgui_say")
tgui_asay = new(src, "tgui_asay")

initialize_commandbar_spy()

GLOB.ahelp_tickets.ClientLogin(src)
GLOB.mhelp_tickets.ClientLogin(src)
GLOB.interviews.client_login(src)
Expand Down
70 changes: 70 additions & 0 deletions code/modules/client/verbs/typing.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#define IC_VERBS list("say", "me", "whisper")

/client/var/commandbar_thinking = FALSE
/client/var/commandbar_typing = FALSE

/client/proc/initialize_commandbar_spy()
src << output('html/typing_indicator.html', "commandbar_spy")

/client/proc/handle_commandbar_typing(href_list)
//if (!typing_indicators) //check pref
// return
if (length(href_list["verb"]) < 1 || !(LOWER_TEXT(href_list["verb"]) in IC_VERBS) || text2num(href_list["argument_length"]) < 1)
if (commandbar_typing)
commandbar_typing = FALSE
stop_typing()

if (commandbar_thinking)
commandbar_thinking = FALSE
stop_thinking()
return

if (!commandbar_thinking)
commandbar_thinking = TRUE
start_thinking()

if (!commandbar_typing)
commandbar_typing = TRUE
start_typing()


/** Sets the mob as "thinking" - with indicator and the TRAIT_THINKING_IN_CHARACTER trait */
/client/proc/start_thinking()
//if(!typing_indicators)
// return FALSE
/// Special exemptions
if(isabductor(mob))
return FALSE
ADD_TRAIT(mob, TRAIT_THINKING_IN_CHARACTER, CURRENTLY_TYPING_TRAIT)
mob.create_thinking_indicator()

/** Removes typing/thinking indicators and flags the mob as not thinking */
/client/proc/stop_thinking()
mob?.remove_all_indicators()

/**
* Handles the user typing. After a brief period of inactivity,
* signals the client mob to revert to the "thinking" icon.
*/
/client/proc/start_typing()
var/mob/client_mob = mob
client_mob.remove_thinking_indicator()
if(!HAS_TRAIT(client_mob, TRAIT_THINKING_IN_CHARACTER))
return FALSE
client_mob.create_typing_indicator()
addtimer(CALLBACK(src, PROC_REF(stop_typing)), 5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE)

/**
* Callback to remove the typing indicator after a brief period of inactivity.
* If the user was typing IC, the thinking indicator is shown.
*/
/client/proc/stop_typing()
if(isnull(mob))
return FALSE
var/mob/client_mob = mob
client_mob.remove_typing_indicator()
if(!HAS_TRAIT(client_mob, TRAIT_THINKING_IN_CHARACTER))
return FALSE
client_mob.create_thinking_indicator()

#undef IC_VERBS
2 changes: 2 additions & 0 deletions code/modules/mob/living/say.dm
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/eavesdrop_range = 0
if(message_mods[WHISPER_MODE]) //If we're whispering
eavesdrop_range = EAVESDROP_EXTRA_RANGE

var/list/listening = get_hearers_in_view(message_range+eavesdrop_range, source, SEE_INVISIBLE_MAXIMUM)
var/list/the_dead = list()

for(var/mob/M as() in GLOB.player_list)
if(!M) //yogs
continue //yogs | null in player_list for whatever reason :shrug:
Expand Down
10 changes: 4 additions & 6 deletions code/modules/mob/mob_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,7 @@ CREATION_TEST_IGNORE_SELF(/mob)
///Is the mob actively shifting?
var/shifting

///Currently possesses a typing indicator icon
var/typing_indicator = FALSE
/// Thinking indicator - mob has input window open
var/thinking_indicator = FALSE
/// User is thinking in character. Used to revert to thinking state after stop_typing
var/thinking_IC = FALSE
///the icon currently used for the typing indicator's bubble
var/active_typing_indicator
///the icon currently used for the thinking indicator's bubble
var/active_thinking_indicator
57 changes: 23 additions & 34 deletions code/modules/tgui_input/say_modal/typing.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/// Thinking
GLOBAL_DATUM_INIT(thinking_indicator, /mutable_appearance, mutable_appearance('icons/mob/talk.dmi', "default3", CALCULATE_MOB_OVERLAY_LAYER(TYPING_LAYER)))

/// Typing
GLOBAL_DATUM_INIT(blind_typing_indicator, /mutable_appearance, mutable_appearance('icons/mob/talk.dmi', "default0", (-TYPING_LAYER), BLIND_FEATURE_PLANE, appearance_flags = KEEP_TOGETHER))
GLOBAL_DATUM_INIT(typing_indicator, /mutable_appearance, mutable_appearance('icons/mob/talk.dmi', "default0", CALCULATE_MOB_OVERLAY_LAYER(TYPING_LAYER)))

/** Creates a thinking indicator over the mob. */
/mob/proc/create_thinking_indicator()
Expand Down Expand Up @@ -33,21 +31,17 @@ GLOBAL_DATUM_INIT(typing_indicator, /mutable_appearance, mutable_appearance('ico
remove_all_indicators()
return ..()

/** Sets the mob as "thinking" - with indicator and variable thinking_IC */
/** Sets the mob as "thinking" - with indicator and the TRAIT_THINKING_IN_CHARACTER trait */
/datum/tgui_say/proc/start_thinking()
if(!window_open || !istype(client.mob))
return FALSE
/// Special exemptions
if(isabductor(client.mob))
if(!window_open)
return FALSE
client.mob.thinking_IC = TRUE
client.mob.create_thinking_indicator()
return client.start_thinking()

/** Removes typing/thinking indicators and flags the mob as not thinking */
/datum/tgui_say/proc/stop_thinking()
if(!istype(client.mob))
return FALSE
client.mob.remove_all_indicators()
return client.stop_thinking()

/**
* Handles the user typing. After a brief period of inactivity,
Expand All @@ -56,53 +50,48 @@ GLOBAL_DATUM_INIT(typing_indicator, /mutable_appearance, mutable_appearance('ico
/datum/tgui_say/proc/start_typing()
if(!istype(client.mob))
return FALSE
client.mob.remove_thinking_indicator()
if(!window_open || !client.mob.thinking_IC)
if(!window_open)
return FALSE
client.mob.create_typing_indicator()
addtimer(CALLBACK(src, PROC_REF(stop_typing)), 5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE)
return client.start_typing()

/**
* Callback to remove the typing indicator after a brief period of inactivity.
* Remove the typing indicator after a brief period of inactivity or during say events.
* If the user was typing IC, the thinking indicator is shown.
*/
/datum/tgui_say/proc/stop_typing()
if(!client?.mob)
return FALSE
client.mob.remove_typing_indicator()
if(!window_open || !client.mob.thinking_IC)
if(!window_open)
return FALSE
client.mob.create_thinking_indicator()
client.stop_typing()

/// Overrides for overlay creation
/mob/living/create_thinking_indicator()
if(thinking_indicator || typing_indicator || !thinking_IC || stat != CONSCIOUS )
if(active_thinking_indicator || active_typing_indicator || stat != CONSCIOUS || !HAS_TRAIT(src, TRAIT_THINKING_IN_CHARACTER))
return FALSE
add_overlay(GLOB.thinking_indicator)
thinking_indicator = TRUE
active_thinking_indicator = mutable_appearance('icons/mob/talk.dmi', "[bubble_icon]3", TYPING_LAYER)
add_overlay(active_thinking_indicator)

/mob/living/remove_thinking_indicator()
if(!thinking_indicator)
if(!active_thinking_indicator)
return FALSE
cut_overlay(GLOB.thinking_indicator)
thinking_indicator = FALSE
cut_overlay(active_thinking_indicator)
active_thinking_indicator = null

/mob/living/create_typing_indicator(override = FALSE)
if(typing_indicator || ((thinking_indicator || !thinking_IC) && !override) || stat != CONSCIOUS)
if(active_typing_indicator || ((active_thinking_indicator || !HAS_TRAIT(src, TRAIT_THINKING_IN_CHARACTER)) && !override) || stat != CONSCIOUS)
return FALSE
add_overlay(GLOB.typing_indicator)
active_typing_indicator = mutable_appearance('icons/mob/talk.dmi', "[bubble_icon]0", TYPING_LAYER)
add_overlay(active_typing_indicator)
add_overlay(GLOB.blind_typing_indicator)
typing_indicator = TRUE

/mob/living/remove_typing_indicator()
if(!typing_indicator)
if(!active_typing_indicator)
return FALSE
cut_overlay(GLOB.typing_indicator)
cut_overlay(active_typing_indicator)
cut_overlay(GLOB.blind_typing_indicator)
typing_indicator = FALSE
active_typing_indicator = null

/mob/living/remove_all_indicators()
thinking_IC = FALSE
REMOVE_TRAIT(src, TRAIT_THINKING_IN_CHARACTER, CURRENTLY_TYPING_TRAIT)
remove_thinking_indicator()
remove_typing_indicator()

Expand Down
46 changes: 46 additions & 0 deletions html/typing_indicator.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body>
<script>
lastseentypedtext = "";
function getoutput() {
setTimeout(getoutput, 1000);
window.location = "byond://winget?callback=checkoutput&id=:Input&property=text";
}
function checkoutput(props) {
if (typeof props !== 'object')
return;

if (typeof props.text !== 'string' && !(props.text instanceof String))
return;

var text = props.text;

if (text == lastseentypedtext)
return;

lastseentypedtext = text;

var words = text.split(" ");
var verb = words[0];
var argument = "";
var argument_length = -1;

if (words.length >= 2) {
words.splice(0, 1)
argument = words.join(" ");
argument_length = argument.length;
}

if (argument_length > 0 && argument[0] == "\"")
argument_length -= 1;

window.location = "byond://?commandbar_typing=1&verb="+encodeURIComponent(verb)+"&argument_length="+argument_length;
}
setTimeout(getoutput, 2000);
</script>
</body>
</html>
Binary file modified icons/mob/talk.dmi
Binary file not shown.
9 changes: 9 additions & 0 deletions interface/skin.dmf
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ window "mainwindow"
anchor2 = none
is-visible = false
saved-params = ""
elem "commandbar_spy"
type = BROWSER
is-default = false
pos = 0,0
size = 200x200
anchor1 = -1,-1
anchor2 = -1,-1
is-visible = false
saved-params = ""

window "mapwindow"
elem "mapwindow"
Expand Down

0 comments on commit d9b15bc

Please sign in to comment.