Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supercharged Flavourtext + Subtle Emote Refactor (again) #3877

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/__DEFINES/keybinding.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define COMSIG_KB_CLIENT_LOOC_DOWN "keybinding_client_looc_down"
#define COMSIG_KB_CLIENT_SAY_DOWN "keybinding_client_say_down"
#define COMSIG_KB_CLIENT_ME_DOWN "keybinding_client_me_down"
#define COMSIG_KB_CLIENT_SUBTLE_DOWN "keybinding_client_subtle_down"
#define COMSIG_KB_CLIENT_WHISPER_DOWN "keybinding_client_whisper_down"

//Human
Expand Down
2 changes: 2 additions & 0 deletions code/__HELPERS/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@
"elzu_horns" = pick(GLOB.elzu_horns_list),
"ethcolor" = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)],
"flavor_text" = "",
"flavor_portrait" = "",
"flavor_portrait_source" = "",
"frills" = pick(GLOB.frills_list),
"horns" = pick(GLOB.horns_list),
"ipc_antenna" = pick(GLOB.ipc_antennas_list),
Expand Down
2 changes: 1 addition & 1 deletion code/__HELPERS/text.dm
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))

t = replacetext(t, regex("\[^\\S\\r\\n \]", "g"), " ")

t = parsemarkdown_basic_step1(t)
t = parsemarkdown_basic_step1(t, limited)

t = replacetext(t, regex("%s(?:ign)?(?=\\s|$)", "igm"), user ? "<font face=\"[SIGNATURE_FONT]\"><i>[user.real_name]</i></font>" : "<span class=\"paper_field\"></span>")
t = replacetext(t, regex("%f(?:ield)?(?=\\s|$)", "igm"), "<span class=\"paper_field\"></span>")
Expand Down
70 changes: 70 additions & 0 deletions code/datums/components/flavor_text.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/datum/component/flavor_text
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
/// The flavor text to display when the parent is examined.
var/flavor_text
var/portrait_url
var/portrait_source

var/static/flavortext_regex = regex(@"https://i\.imgur\.com/[0-9A-z]{7}\.(?:png|jpe?g)")

/datum/component/flavor_text/Initialize(_flavor_text, _portrait_url, _portrait_source)
//You could technically use this on any atom, but... no.
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE

flavor_text = _flavor_text

if(!length(_portrait_url) || !length(_portrait_source))
return

if(!findtext(_portrait_url, flavortext_regex))
return

portrait_url = _portrait_url
portrait_source = _portrait_source

/datum/component/flavor_text/RegisterWithParent()
RegisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE, PROC_REF(handle_examine_more))

/datum/component/flavor_text/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE)

/datum/component/flavor_text/InheritComponent(datum/component/flavor_text/new_comp, original, _flavor_text, _portrait_url, _portrait_source)
if(new_comp)
flavor_text = new_comp.flavor_text
portrait_url = new_comp.portrait_url
portrait_source = new_comp.portrait_source
else
flavor_text = _flavor_text
portrait_url = _portrait_url
portrait_source = _portrait_source

/datum/component/flavor_text/proc/handle_examine_more(mob/user)
SIGNAL_HANDLER
if(!flavor_text)
return

INVOKE_ASYNC(src, PROC_REF(ui_interact), user)

/datum/component/flavor_text/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "FlavorText", "[user.name]")
ui.set_autoupdate(FALSE)
ui.open()

/datum/component/flavor_text/ui_state(mob/user)
return GLOB.z_state

/datum/component/flavor_text/ui_data(mob/user)
var/list/data = list()
data["characterName"] = flavor_text
data["portraitUrl"] = portrait_url
data["portraitSource"] = portrait_source
data["flavorText"] = flavor_text
return data

/datum/component/flavor_text/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, portrait_url) && !findtext(var_value, flavortext_regex))
return FALSE
return ..()
6 changes: 4 additions & 2 deletions code/datums/dna.dm
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
destination.dna.features = features.Copy()
destination.dna.real_name = real_name
destination.dna.temporary_mutations = temporary_mutations.Copy()
destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
//Update the flavor_text to use new dna text
destination.set_flavor_text(destination.dna.features["flavor_text"], destination.dna.features["portrait_url"], destination.dna.features["portrait_source"])
if(transfer_SE)
destination.dna.mutation_index = mutation_index
destination.dna.default_mutation_genes = default_mutation_genes
Expand Down Expand Up @@ -371,7 +372,8 @@
//Do not use force_transfer_mutations for stuff like cloners without some precautions, otherwise some conditional mutations could break (timers, drill hat etc)
if(newfeatures)
dna.features = newfeatures
flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
//Update the flavor_text to use new dna text
set_flavor_text(dna.features["flavor_text"], dna.features["portrait_url"], dna.features["portrait_source"])

if(mrace)
var/datum/species/newrace = new mrace.type
Expand Down
7 changes: 4 additions & 3 deletions code/datums/emotes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
var/vary = FALSE //used for the honk borg emote
var/only_forced_audio = FALSE //can only code call this event instead of the player.
var/cooldown = 0.8 SECONDS
var/static/regex/stop_bad_mime = regex(@"says|exclaims|yells|asks")
///Range the emote can be seen or heard from
var/range = DEFAULT_MESSAGE_RANGE

/datum/emote/New()
if (ispath(mob_type_allowed_typecache))
Expand Down Expand Up @@ -76,9 +77,9 @@
M.show_message("[FOLLOW_LINK(M, user)] [dchatmsg]")

if(emote_type == EMOTE_AUDIBLE)
user.audible_message(msg, deaf_message = "<span class='emote'>You see how <b>[user]</b> [msg]</span>", audible_message_flags = EMOTE_MESSAGE)
user.audible_message(msg, deaf_message = "<span class='emote'>You see how <b>[user]</b> [msg]</span>", hearing_distance = range, audible_message_flags = EMOTE_MESSAGE)
else
user.visible_message(msg, blind_message = "<span class='emote'>You hear how <b>[user]</b> [msg]</span>", visible_message_flags = EMOTE_MESSAGE)
user.visible_message(msg, blind_message = "<span class='emote'>You hear how <b>[user]</b> [msg]</span>", vision_distance = range, visible_message_flags = EMOTE_MESSAGE)

/// For handling emote cooldown, return true to allow the emote to happen
/datum/emote/proc/check_cooldown(mob/user, intentional)
Expand Down
6 changes: 6 additions & 0 deletions code/datums/keybinding/communication.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
full_name = "Custom Emote (/Me)"
keybind_signal = COMSIG_KB_CLIENT_ME_DOWN

/datum/keybinding/client/communication/subtle
hotkey_keys = null
name = "Subtle"
full_name = "Subtle Custom Emote"
keybind_signal = COMSIG_KB_CLIENT_SUBTLE_DOWN

/datum/keybinding/client/communication/whisper
hotkey_keys = list("Y")
name = "Whisper"
Expand Down
15 changes: 1 addition & 14 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1676,20 +1676,7 @@

/// Returns the atom name that should be used on screentip
/atom/proc/get_screentip_name(client/hovering_client)
if(ishuman(src))
var/mob/living/carbon/human/guy = src
var/mob/client_mob = hovering_client.mob
var/datum/guestbook/guestbook = client_mob.mind?.guestbook
if(guestbook)
var/known_name = guestbook.get_known_name(client_mob, guy)
if(known_name)
return known_name
else
return guy.get_visible_name()
else
return guy.real_name
else
return name
return name

///Called whenever a player is spawned on the same turf as this atom.
/atom/proc/join_player_here(mob/M)
Expand Down
2 changes: 2 additions & 0 deletions code/modules/client/client_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
winset(src, "default-[REF(key)]", "parent=default;name=[key];command=looc")
if("Me")
winset(src, "default-[REF(key)]", "parent=default;name=[key];command=me")
if("Subtle")
winset(src, "default-[REF(key)]", "parent=default;name=[key];command=subtle")
if("Whisper")
winset(src, "default-[REF(key)]", "parent=default;name=[key];command=whisper")

Expand Down
36 changes: 26 additions & 10 deletions code/modules/client/preferences.dm
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"elzu_horns" = "None",
"elzu_tail" = "None",
"flavor_text" = "",
"flavor_portrait" = "",
"flavor_portrait_source" = "",
"body_size" = "Normal"
)
var/list/randomise = list(
Expand Down Expand Up @@ -325,14 +327,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<a href='?_src_=prefs;preference=toggle_random;random_type=[RANDOM_AGE]'>Always Random Age: [(randomise[RANDOM_AGE]) ? "Yes" : "No"]</A>"
dat += "<a href='?_src_=prefs;preference=toggle_random;random_type=[RANDOM_AGE_ANTAG]'>When Antagonist: [(randomise[RANDOM_AGE_ANTAG]) ? "Yes" : "No"]</A>"

dat += "<br><a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Flavor Text</b></a>"
if(length(features["flavor_text"]) <= 40)
if(!length(features["flavor_text"]))
dat += "\[...\]"
else
dat += "[features["flavor_text"]]"
else
dat += "[copytext_char(features["flavor_text"], 1, 37)]...<BR>"
dat += "<br><b>Flavor Text: </b>"
var/flavortext = "\[...\]"
if(length(features["flavor_text"]) > 40)
flavortext = copytext_char(features["flavor_text"], 1, 37) + "..."
else if(length(features["flavor_text"]))
flavortext = features["flavor_text"]
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'>[flavortext]</a>"

dat += "<br><b>Portrait:</b>"
var/portrait_text = length(features["flavor_portrait"]) ? "\[Image by [features["flavor_portrait_source"]]\]" : "\[Unset\]"
dat += "<a href='?_src_=prefs;preference=flavor_portrait;task=input'>[portrait_text]</a>"

dat += "<br><br><b>Special Names:</b><BR>"
var/old_group
Expand Down Expand Up @@ -1706,9 +1711,20 @@ GLOBAL_LIST_EMPTY(preferences_datums)

if("flavor_text")
var/msg = stripped_multiline_input(usr, "A snippet of text shown when others examine you, describing what you may look like. This can also be used for OOC notes.", "Flavor Text", html_decode(features["flavor_text"]), MAX_FLAVOR_LEN, TRUE)
if(msg) //WS edit - "Cancel" does not clear flavor text
if(msg)
features["flavor_text"] = msg

if("flavor_portrait")
var/url = input(user, "A URL to an image that will be shown when others examine you.", "Flavor Portrait", features["flavor_portrait"]) as text|null
if(isnull(url))
return
features["flavor_portrait"] = url

var/source = input(user, "The name of the artist or other source for the specified image.", "Flavor Portrait", features["flavor_portrait_source"]) as text|null
if(isnull(source))
return
features["flavor_portrait_source"] = source

if("hair")
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
if(new_hair)
Expand Down Expand Up @@ -2485,7 +2501,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)

character.fbp = fbp

character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially
character.set_flavor_text(features["flavor_text"], features["flavor_portrait"], features["flavor_portrait_source"]) //Let's update their flavor_text at least initially

if(loadout) //I have been told not to do this because it's too taxing on performance, but hey, I did it anyways! //I hate you old me //don't be mean
for(var/gear in equipped_gear)
Expand Down
8 changes: 8 additions & 0 deletions code/modules/client/preferences_savefile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car

//Flavor Text
S["feature_flavor_text"] >> features["flavor_text"]
S["feature_flavor_portrait"] >> features["flavor_portrait"]
S["feature_flavor_source"] >> features["flavor_source"]

//try to fix any outdated data if necessary
//preference updating will handle saving the updated data for us.
Expand Down Expand Up @@ -562,7 +564,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["vox_neck_quills"] = sanitize_inlist(features["vox_neck_quills"], GLOB.vox_neck_quills_list, "None")
features["elzu_horns"] = sanitize_inlist(features["elzu_horns"], GLOB.elzu_horns_list)
features["tail_elzu"] = sanitize_inlist(features["tail_elzu"], GLOB.tails_list_elzu)

features["flavor_text"] = sanitize_text(features["flavor_text"], initial(features["flavor_text"]))
features["flavor_portrait"] = sanitize_text(features["flavor_portrait"], initial(features["flavor_portrait"]))
features["flavor_source"] = sanitize_text(features["flavor_source"], initial(features["flavor_source"]))

all_quirks = SANITIZE_LIST(all_quirks)

Expand Down Expand Up @@ -647,6 +652,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car

//Flavor text
WRITE_FILE(S["feature_flavor_text"] , features["flavor_text"])
WRITE_FILE(S["feature_flavor_portrait"] , features["flavor_portrait"])
WRITE_FILE(S["feature_flavor_source"] , features["flavor_source"])

//Custom names
for(var/custom_name_id in GLOB.preferences_custom_names)
var/savefile_slot_name = custom_name_id + "_name" //TODO remove this
Expand Down
2 changes: 1 addition & 1 deletion code/modules/client/verbs/looc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC")

mob.log_talk(raw_msg, LOG_LOOC, tag = "(LOOC)")

var/list/heard = get_hearers_in_view(7, get_top_level_mob(mob))
var/list/heard = get_hearers_in_view(7, mob)
for(var/mob/hearer_mob in heard)
var/client/hearer = hearer_mob.client

Expand Down
34 changes: 29 additions & 5 deletions code/modules/mob/living/carbon/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@

paper_note.show_through_camera(usr)

if(href_list["flavor_more"])
var/datum/browser/popup = new(usr, "[name]'s flavor text", "[name]'s Flavor Text (expanded)", 500, 200)
popup.set_content(flavor_text_html)
popup.open()
return

/mob/living/carbon/on_fall()
. = ..()
loc?.handle_fall(src)//it's loc so it doesn't call the mob's handle_fall which does nothing
Expand Down Expand Up @@ -1153,11 +1159,6 @@
update_inv_gloves()
. = TRUE

/mob/living/carbon/proc/update_flavor_text_feature(new_text)
if(!dna)
return
dna.features["flavor_text"] = new_text

/// Returns whether or not the carbon should be able to be shocked
/mob/living/carbon/proc/should_electrocute(power_source)
if (ismecha(loc))
Expand Down Expand Up @@ -1206,3 +1207,26 @@
set_lying_angle(pick(90, 270))
else
set_lying_angle(new_lying_angle)

/mob/living/carbon/proc/set_flavor_text(new_text, new_portrait, new_source)
if(!new_text)
return

AddComponent(/datum/component/flavor_text, new_text, new_portrait, new_source)

flavor_text_html = parsemarkdown_basic(new_text)
flavor_text = new_text

if(dna)
dna.features["flavor_text"] = flavor_text
dna.features["flavor_portrait"] = new_portrait
dna.features["flavor_source"] = new_source

/mob/living/carbon/verb/change_flavor_text()
set name = "Change Flavor Text"
set category = "IC"
set src in usr

var/new_text = stripped_multiline_input(usr, "A snippet of text shown when others examine you, describing what you may look like. This can also be used for OOC notes.", "Flavor Text", html_decode(flavor_text), MAX_FLAVOR_LEN, TRUE)

set_flavor_text(new_text)
7 changes: 6 additions & 1 deletion code/modules/mob/living/carbon/carbon_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
/// Timer id of any transformation
var/transformation_timer

/// WS edit - moth dust when hugging
/// moth dust when hugging
var/mothdust

///List of quirk cooldowns to track
Expand All @@ -94,3 +94,8 @@

/// Can other carbons be shoved into this one to make it fall?
var/can_be_shoved_into = FALSE

/// A snippet of text shown when the mob is examined.
var/flavor_text = ""
/// Plaintext version of the flavor text, formatted with markdown.
var/flavor_text_html = ""
19 changes: 16 additions & 3 deletions code/modules/mob/living/carbon/human/examine.dm
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,10 @@
if(invisible_man)
. += "...?"
else
var/flavor = print_flavor_text()
if(flavor)
. += flavor
var/text_to_add = flavor_text
if(length(text_to_add) > MAX_SHORTFLAVOR_LEN)
text_to_add = "[copytext(text_to_add, 1, MAX_SHORTFLAVOR_LEN)]... <a href=\"byond://?src=[text_ref(src)];flavor_more=1\">More...</a>"
. += span_notice(text_to_add)
. += "*---------*</span>"

SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
Expand Down Expand Up @@ -431,3 +432,15 @@
return
if(get_age())
. += span_notice("[p_they(TRUE)] appear[p_s()] to be [get_age()].")

/mob/living/carbon/human/get_screentip_name(client/hovering_client)
var/mob/client_mob = hovering_client.mob
var/datum/guestbook/guestbook = client_mob.mind?.guestbook
if(guestbook)
var/known_name = guestbook.get_known_name(client_mob, src)
if(known_name)
return known_name
else
return get_visible_name()
else
return real_name
Loading
Loading