Merge pull request #1088 from ArchieBeepBoop/sillycons

Flavortext... But as an element.
This commit is contained in:
QuoteFox
2021-04-23 05:24:19 +01:00
committed by GitHub
18 changed files with 240 additions and 89 deletions
+5
View File
@@ -294,6 +294,7 @@
#define SPEECH_LANGUAGE 5
#define SPEECH_IGNORE_SPAM 6
#define SPEECH_FORCED 7 */
#define COMSIG_MOB_ANTAG_ON_GAIN "mob_antag_on_gain" //from base of /datum/antagonist/on_gain(): (antag_datum)
///from base of /mob/Login(): ()
#define COMSIG_MOB_LOGIN "mob_login"
@@ -378,6 +379,7 @@
///from base of mob/living/carbon/soundbang_act(): (list(intensity))
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang"
#define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE)
///from /item/organ/proc/Insert() (/obj/item/organ/)
#define COMSIG_CARBON_GAIN_ORGAN "carbon_gain_organ"
///from /item/organ/proc/Remove() (/obj/item/organ/)
@@ -566,6 +568,9 @@
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby"
///Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit"
#define COMSIG_HUMAN_PREFS_COPIED_TO "human_prefs_copied_to" //from datum/preferences/copy_to(): (datum/preferences, icon_updates, roundstart_checks)
#define COMSIG_HUMAN_HARDSET_DNA "human_hardset_dna" //from mob/living/carbon/human/hardset_dna(): (ui, se, newreal_name, newblood_type, datum/species, newfeatures)
#define COMSIG_HUMAN_ON_RANDOMIZE "humman_on_randomize" //from base of proc/randomize_human()
///Whenever EquipRanked is called, called after job is set
#define COMSIG_JOB_RECEIVED "job_received"
-11
View File
@@ -104,17 +104,6 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
if(!src.holder) return
message_admins("[key_name_admin(usr)] manually reloaded mentors")
//Flavor Text
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavor Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
var/new_flavor = input(src, "Enter your new flavor text:", "Flavor text", null) as message|null
if(!isnull(new_flavor))
flavor_text = sanitize(new_flavor)
to_chat(src, "Your flavor text has been updated.")
//LOOC toggles
/client/verb/listen_looc()
set name = "Show/Hide LOOC"
+1
View File
@@ -231,6 +231,7 @@
"ipc_screen" = snowflake_ipc_antenna_list ? pick(snowflake_ipc_antenna_list) : "None",
"ipc_antenna" = "None",
"flavor_text" = "",
"silicon_flavor_text" = "",
"ooc_text" = ""))
/proc/random_hair_style(gender)
+5 -2
View File
@@ -54,11 +54,12 @@
if(ishuman(destination))
var/mob/living/carbon/human/H = destination
H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
destination.ooc_text = destination.dna.features["ooc_text"] //Update the flavor_text to use new dna text
if(transfer_SE)
destination.dna.mutation_index = mutation_index
SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, src, transfer_SE)
/datum/dna/proc/copy_dna(datum/dna/new_dna)
new_dna.unique_enzymes = unique_enzymes
new_dna.mutation_index = mutation_index
@@ -356,7 +357,6 @@
if(newfeatures)
dna.features = newfeatures
flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
ooc_text = dna.features["ooc_text"] //Update the flavor_text to use new dna text
if(mrace)
@@ -379,6 +379,9 @@
dna.mutation_index = mutation_index
domutcheck()
SEND_SIGNAL(src, COMSIG_HUMAN_HARDSET_DNA, ui, newreal_name, newblood_type, mrace, newfeatures)
// change to SEND_SIGNAL(src, COMSIG_HUMAN_HARDSET_DNA, ui, se, newreal_name, newblood_type, mrace, newfeatures) if we add structural enzymes.
if(mrace || newfeatures || ui)
update_body()
update_hair()
+187
View File
@@ -0,0 +1,187 @@
GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
/datum/element/flavor_text
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 3
var/flavor_name = "Flavor Text"
var/list/texts_by_atom = list()
var/addendum = ""
var/always_show = FALSE
var/max_len = MAX_FLAVOR_LEN
var/can_edit = TRUE
/// For preference/DNA saving/loading. Null to prevent. Prefs are only loaded from obviously if it exists in preferences.features.
var/save_key
/// Do not attempt to render a preview on examine. If this is on, it will display as \[flavor_name\]
var/examine_no_preview = FALSE
var/examineTabOutput = ""
/datum/element/flavor_text/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FLAVOR_LEN, _always_show = FALSE, _edit = TRUE, _save_key, _examine_no_preview = FALSE)
. = ..()
if(. == ELEMENT_INCOMPATIBLE || !isatom(target)) //no reason why this shouldn't work on atoms too.
return ELEMENT_INCOMPATIBLE
if(_max_len)
max_len = _max_len
texts_by_atom[target] = copytext(text, 1, max_len)
if(_name)
flavor_name = _name
if(!isnull(addendum))
addendum = _addendum
always_show = _always_show
can_edit = _edit
save_key = _save_key
examine_no_preview = _examine_no_preview
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/show_flavor)
if(can_edit && ismob(target)) //but only mobs receive the proc/verb for the time being
var/mob/M = target
LAZYOR(GLOB.mobs_with_editable_flavor_text[M], src)
M.verbs |= /mob/proc/manage_flavor_tests
if(save_key && ishuman(target))
RegisterSignal(target, COMSIG_HUMAN_PREFS_COPIED_TO, .proc/update_prefs_flavor_text)
/datum/element/flavor_text/Detach(atom/A)
. = ..()
UnregisterSignal(A, list(COMSIG_PARENT_EXAMINE, COMSIG_HUMAN_PREFS_COPIED_TO))
texts_by_atom -= A
if(can_edit && ismob(A))
var/mob/M = A
LAZYREMOVE(GLOB.mobs_with_editable_flavor_text[M], src)
if(!GLOB.mobs_with_editable_flavor_text[M])
GLOB.mobs_with_editable_flavor_text -= M
M.verbs -= /mob/proc/manage_flavor_tests
/datum/element/flavor_text/proc/show_flavor(atom/target, mob/user, list/examine_list)
if(!always_show && isliving(target))
var/mob/living/L = target
var/unknown = L.get_visible_name() == "Unknown"
if(!unknown && iscarbon(target))
var/mob/living/carbon/C = L
unknown = (C.wear_mask && (C.wear_mask.flags_inv & HIDEFACE)) || (C.head && (C.head.flags_inv & HIDEFACE))
if(unknown)
if(!("...?" in examine_list)) //can't think of anything better in case of multiple flavor texts.
examine_list += "...?"
return
var/text = texts_by_atom[target]
if(!text)
return
if(examine_no_preview)
examine_list += "<span class='notice'><a href='?src=[REF(src)];show_flavor=[REF(target)]'>\[[flavor_name]\]</a></span>"
return
var/msg = replacetext(text, "\n", " ")
if(length_char(msg) <= 40)
examine_list += "<span class='notice'>[msg]</span>"
else
examine_list += "<span class='notice'>[copytext_char(msg, 1, 37)]... <a href='?src=[REF(src)];show_flavor=[REF(target)]'>More...</span></a>"
//Examine Tab stuff - Hyperstation
examineTabOutput = "<center>"
if(ishuman(target)) //user just returned, y'know, the user's own species. dumb.
var/mob/living/carbon/human/L = target
if(L.gender)
examineTabOutput += "[icon2html('hyperstation/icons/chat/gender.dmi', world, L.gender)]"
examineTabOutput += "([L.dna.custom_species ? L.dna.custom_species : L.dna.species.name])"
examineTabOutput += "</center>"
examineTabOutput += "<br>[url_encode(msg)]"
if(ismob(target))
var/mob/M = target
if(M.ooc_text)
examineTabOutput += "<br><br><i><b>OOC</b>"
examineTabOutput += "<br>[url_encode(M.ooc_text)]"
user.client << output(examineTabOutput, "statbrowser:update_examine") //open the examine window
user.client << output(null, "statbrowser:create_mobexamine") //open the examine window
/datum/element/flavor_text/Topic(href, href_list)
. = ..()
if(.)
return
if(href_list["show_flavor"])
var/atom/target = locate(href_list["show_flavor"])
var/text = texts_by_atom[target]
if(text)
usr << browse("<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[target.name]</TITLE></HEAD><BODY><TT>[replacetext(texts_by_atom[target], "\n", "<BR>")]</TT></BODY></HTML>", "window=[target.name];size=500x200")
onclose(usr, "[target.name]")
return TRUE
/mob/proc/manage_flavor_tests()
set name = "Manage Flavor Texts"
set desc = "Used to manage your various flavor texts."
set category = "IC"
var/list/L = GLOB.mobs_with_editable_flavor_text[src]
if(length(L) == 1)
var/datum/element/flavor_text/F = L[1]
F.set_flavor(src)
return
var/list/choices = list()
for(var/i in L)
var/datum/element/flavor_text/F = i
choices[F.flavor_name] = F
var/chosen = input(src, "Which flavor text would you like to modify?") as null|anything in choices
if(!chosen)
return
var/datum/element/flavor_text/F = choices[chosen]
F.set_flavor(src)
/datum/element/flavor_text/proc/set_flavor(mob/user)
if(!(user in texts_by_atom))
return FALSE
var/lower_name = lowertext(flavor_name)
var/new_text = stripped_multiline_input(user, "Set the [lower_name] displayed on 'examine'. [addendum]", flavor_name, html_decode(texts_by_atom[usr]), max_len, TRUE)
if(!isnull(new_text) && (user in texts_by_atom))
texts_by_atom[user] = new_text
to_chat(src, "Your [lower_name] has been updated.")
return TRUE
return FALSE
/datum/element/flavor_text/proc/update_prefs_flavor_text(mob/living/carbon/human/H, datum/preferences/P, icon_updates = TRUE, roundstart_checks = TRUE)
if(P.features.Find(save_key))
texts_by_atom[H] = P.features[save_key]
//subtypes with additional hooks for DNA and preferences.
/datum/element/flavor_text/carbon
//list of antagonists etcetera that should have nothing to do with people's snowflakes.
var/static/list/i_dont_even_know_who_you_are = typecacheof(list(/datum/antagonist/abductor, /datum/antagonist/ert,
/datum/antagonist/nukeop, /datum/antagonist/wizard))
/datum/element/flavor_text/carbon/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FLAVOR_LEN, _always_show = FALSE, _edit = TRUE, _save_key = "flavor_text", _examine_no_preview = FALSE)
if(!iscarbon(target))
return ELEMENT_INCOMPATIBLE
. = ..()
if(. == ELEMENT_INCOMPATIBLE)
return
RegisterSignal(target, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, .proc/update_dna_flavor_text)
RegisterSignal(target, COMSIG_MOB_ANTAG_ON_GAIN, .proc/on_antag_gain)
if(ishuman(target))
RegisterSignal(target, COMSIG_HUMAN_HARDSET_DNA, .proc/update_dna_flavor_text)
RegisterSignal(target, COMSIG_HUMAN_ON_RANDOMIZE, .proc/unset_flavor)
/datum/element/flavor_text/carbon/Detach(mob/living/carbon/C)
. = ..()
UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_MOB_ANTAG_ON_GAIN, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
/datum/element/flavor_text/carbon/proc/update_dna_flavor_text(mob/living/carbon/C)
texts_by_atom[C] = C.dna.features[save_key]
/datum/element/flavor_text/carbon/set_flavor(mob/living/carbon/user)
. = ..()
if(. && user.dna)
user.dna.features[save_key] = texts_by_atom[user]
/datum/element/flavor_text/carbon/proc/unset_flavor(mob/living/carbon/user)
texts_by_atom[user] = ""
/datum/element/flavor_text/carbon/proc/on_antag_gain(mob/living/carbon/user, datum/antagonist/antag)
if(is_type_in_typecache(antag, i_dont_even_know_who_you_are))
texts_by_atom[user] = ""
if(user.dna)
user.dna.features[save_key] = ""
+4 -1
View File
@@ -37,7 +37,10 @@
H.dna.features["moth_wings"] = pick(GLOB.moth_wings_list)
H.dna.features["moth_fluff"] = pick(GLOB.moth_fluffs_list)
H.dna.features["deco_wings"] = pick(GLOB.deco_wings_list)
H.dna.features["flavor_text"] = "" //Oh no.
SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)
H.update_body()
H.update_hair()
H.update_body_parts()
H.update_body_parts()
@@ -72,6 +72,7 @@ GLOBAL_LIST_EMPTY(antagonists)
give_antag_moodies()
if(is_banned(owner.current) && replace_banned)
replace_banned_player()
SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src)
/datum/antagonist/proc/is_banned(mob/M)
if(!M)
+18
View File
@@ -181,6 +181,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"ipc_screen" = "Sunburst",
"ipc_antenna" = "None",
"flavor_text" = "",
"silicon_flavor_text" = "",
"ooc_text" = ""
)
@@ -393,6 +394,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "[features["flavor_text"]]"
else
dat += "[TextPreview(features["flavor_text"])]...<BR>"
dat += "<h2>Silicon Flavor Text</h2>"
dat += "<a href='?_src_=prefs;preference=silicon_flavor_text;task=input'><b>Set Silicon Examine Text</b></a><br>"
if(length(features["silicon_flavor_text"]) <= 40)
if(!length(features["silicon_flavor_text"]))
dat += "\[...\]"
else
dat += "[features["silicon_flavor_text"]]"
else
dat += "[TextPreview(features["silicon_flavor_text"])]...<BR>"
dat += "<h2>OOC Text</h2>"
dat += "<a href='?_src_=prefs;preference=ooc_text;task=input'><b>Set OOC Text</b></a><br>"
if(length(features["ooc_text"]) <= 40)
@@ -1711,6 +1721,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
msg = msg
features["flavor_text"] = msg
if("silicon_flavor_text")
var/msg = stripped_multiline_input(usr, "Set the silicon flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Silicon Flavor Text", features["silicon_flavor_text"], MAX_FLAVOR_LEN, TRUE)
if(msg)
msg = msg
features["silicon_flavor_text"] = msg
if("ooc_text")
var/msg = stripped_multiline_input(usr, "Set the OOC text in your 'examine' verb. This should be OOC only!", "OOC Text", html_decode(features["ooc_text"]), MAX_MESSAGE_LEN, TRUE)
if(msg)
@@ -2754,6 +2770,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
character.Digitigrade_Leg_Swap(TRUE)
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
//speech stuff
if(custom_tongue != "default")
var/new_tongue = GLOB.roundstart_tongues[custom_tongue]
@@ -436,6 +436,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
else //We have no old flavortext, default to new
S["feature_flavor_text"] >> features["flavor_text"]
S["feature_silicon_flavor_text"] >> features["silicon_flavor_text"]
if((S["ooc_text"] != "") && (S["ooc_text"] != null) && S["ooc_text"])
S["ooc_text"] >> features["ooc_text"]
@@ -513,6 +514,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default")
custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default")
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN)
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
@@ -8,7 +8,6 @@
var/t_is = p_are()
var/obscure_name
var/dispSize = round(12*size_multiplier) // gets the character's sprite size percent and converts it to the nearest half foot
var/output = ""
if(isliving(user))
var/mob/living/L = user
@@ -24,25 +23,13 @@
if (vassDesc != "")
. += vassDesc
output = "<center>"
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if(ishuman(src)) //user just returned, y'know, the user's own species. dumb.
var/mob/living/carbon/human/H = src
if(gender)
output += "[icon2html('hyperstation/icons/chat/gender.dmi', world, gender)]"
output += "<b>[src.name]</b>"
var/datum/species/pref_species = H.dna.species
if(get_visible_name() == "Unknown") // same as flavor text, but hey it works.
. += "You can't make out what species they are."
else if(skipface)
. += "You can't make out what species they are."
else
. += "[t_He] [t_is] a [H.dna.custom_species ? H.dna.custom_species : pref_species.name]!"
output += "([H.dna.custom_species ? H.dna.custom_species : pref_species.name])"
output += "</center>"
if(skipface || get_visible_name() == "Unknown")
. += "You can't make out what species they are."
else
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]!"
//uniform
if(w_uniform && !(SLOT_W_UNIFORM in obscured))
@@ -416,30 +403,9 @@
else if(isobserver(user) && traitstring)
. += "<span class='info'><b>Traits:</b> [traitstring]</span>"
if(print_flavor_text())
output += "<br><b>General</b>"
if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
. += "...?"
output += "<br>...?"
else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either.
. += "...?"
output += "<br>...?"
else
. += "[print_flavor_text()]"
output += "<br>[url_encode(flavor_text)]"
if(ooc_text)
output += "<br><br><i><b>OOC</b>"
output += "<br>[url_encode(ooc_text)]"
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, msg)
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
. += "*---------*</span>"
//stat panel
if(ishuman(src))
user.client << output(output, "statbrowser:update_examine") //open the examine window
user.client << output(null, "statbrowser:create_mobexamine") //open the examine window
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
var/list/dat = list()
if(!pronoun_replacement)
@@ -37,6 +37,8 @@
if(!CONFIG_GET(flag/disable_human_mood))
AddComponent(/datum/component/mood)
AddElement(/datum/element/mob_holder/micro, "micro")
AddElement(/datum/element/flavor_text/carbon, "", "Flavor Text", "", MAX_FLAVOR_LEN, FALSE, TRUE, "flavor_text")
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
/mob/living/carbon/human/Destroy()
QDEL_NULL(physiology)
@@ -55,6 +55,11 @@
diag_hud_set_status()
diag_hud_set_health()
/mob/living/silicon/ComponentInitialize()
. = ..()
AddElement(/datum/element/flavor_text, "", "Silicon Flavor Text", "", MAX_FLAVOR_LEN, FALSE, TRUE, "silicon_flavor_text")
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
/mob/living/silicon/med_hud_set_health()
return //we use a different hud
-7
View File
@@ -525,13 +525,6 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
unset_machine()
src << browse(null, t1)
if(href_list["flavor_more"])
usr << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", name, replacetext(flavor_text, "\n", "<BR>")), text("window=[];size=500x200", name))
onclose(usr, "[name]")
if(href_list["flavor_change"])
update_flavor_text()
if(href_list["refresh"])
if(machine && in_range(src, usr))
show_inv(machine)
-2
View File
@@ -129,9 +129,7 @@
///Whether the mob is updating glide size when movespeed updates or not
var/updating_glide_size = TRUE
var/flavor_text = ""
var/ooc_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.
-25
View File
@@ -2,31 +2,6 @@
////////////////////SUBTLE COMMAND////////////////////
//////////////////////////////////////////////////////
/mob/proc/update_flavor_text()
set src in usr
if(usr != src)
to_chat(usr, "No.")
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. IC only!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN, TRUE)
if(msg)
flavor_text = html_encode(msg)
flavor_text = msg
/mob/proc/warn_flavor_changed()
if(flavor_text && flavor_text != "") // don't spam people that don't use it!
to_chat(src, "<h2 class='alert'>OOC Warning:</h2>")
to_chat(src, "<span class='alert'>Your flavor text is likely out of date! <a href='?src=[REF(src)];flavor_change=1'>Change</a></span>")
/mob/proc/print_flavor_text()
if(flavor_text && flavor_text != "")
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor_text, "\n", " "))
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
/mob/proc/get_top_level_mob()
if(istype(src.loc,/mob)&&src.loc!=src)
var/mob/M=src.loc