mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Refactors names and voices / potted plants no longer conceal voice (just appearance) / honorifics show on examine (#92781)
## About The Pull Request Closes #92778 Closes #86829 <img width="347" height="39" alt="image" src="https://github.com/user-attachments/assets/c50bd1ff-8c00-47a7-a31a-617fae2adc5b" /> 1. Splits `TRAIT_UNKNOWN` into `TRAIT_UNKNOWN_APPEARANCE` and `TRAIT_UNKNOWN_VOICE` 2. Renames some stuff like `getvoice` and `getspecialvoice` 3. Gets rid some crummy signals around `get_visible_name` and `get_voice` 4. Heads now apply the disfigured trait when relevant (rather than snowflake checking for damage amount) 5. Ling voice refactored into using special voice (it was only used by a viro symptom anyways; I don't anticipate this overlap being problematic) 6. Mask voice changer refactored into a trait ## Why It's Good For The Game Potted plants shouldn't have magical voice concealing powers - especially not over radio, but not over in person either. It's a damn plant So I addressed this by refactoring our face and voice system. Overall things should be a lot cleaner and easier to use. ## Changelog 🆑 Melbert refactor: Refactored a lot of code relating to human face and voice, ie, what shows up in examine and in say. Report anything odd when examining people, with ID cards, when talking over radio, or when disguised refcator: Refactored how you get disfigured when your head's super damaged refactor: Refactored ling mimic voice and traitor voice changer del: Potted plants no longer hide voice. They still hide appearance, though qol: Honorifics now show in examine / in world, rather than only when speaking. /🆑
This commit is contained in:
@@ -116,11 +116,6 @@
|
||||
#define MOVABLE_SAY_QUOTE_MESSAGE_SPANS 2
|
||||
#define MOVABLE_SAY_QUOTE_MESSAGE_MODS 3
|
||||
|
||||
/// Sent from /atom/movable/proc/compose_message() after the name part: (list/stored_name, visible_name)
|
||||
#define COMSIG_MOVABLE_MESSAGE_GET_NAME_PART "movable_message_get_name_part"
|
||||
///The index of the name part
|
||||
#define NAME_PART_INDEX 1
|
||||
|
||||
/// From /datum/element/immerse/proc/add_submerge_overlay(): (visual_overlay)
|
||||
#define COMSIG_MOVABLE_EDIT_UNIQUE_IMMERSE_OVERLAY "movable_edit_unique_submerge_overlay"
|
||||
/// From base of area/Exited(): (area/left, direction)
|
||||
|
||||
@@ -143,6 +143,3 @@
|
||||
///Defines for priorities for the bubble_icon_override comp
|
||||
#define BUBBLE_ICON_PRIORITY_ACCESSORY 2
|
||||
#define BUBBLE_ICON_PRIORITY_ORGAN 1
|
||||
|
||||
/// Sent from /atom/movable/proc/compose_message() to find an honorific. Compatible with NAME_PART_INDEX: (list/stored_name, mob/living/carbon/carbon_human)
|
||||
#define COMSIG_ID_GET_HONORIFIC "id_get_honorific"
|
||||
|
||||
@@ -80,8 +80,10 @@
|
||||
#define HEAD_EYEHOLES (1<<5)
|
||||
/// Head can have debrain overlay
|
||||
#define HEAD_DEBRAIN (1<<6)
|
||||
/// All head flags, default for most heads
|
||||
#define HEAD_ALL_FEATURES (HEAD_HAIR|HEAD_FACIAL_HAIR|HEAD_LIPS|HEAD_EYESPRITES|HEAD_EYECOLOR|HEAD_EYEHOLES|HEAD_DEBRAIN)
|
||||
/// Head will never be disfigured by damage
|
||||
#define HEAD_NO_DISFIGURE (1<<7)
|
||||
/// Default for most heads
|
||||
#define HEAD_DEFAULT_FEATURES (HEAD_HAIR|HEAD_FACIAL_HAIR|HEAD_LIPS|HEAD_EYESPRITES|HEAD_EYECOLOR|HEAD_EYEHOLES|HEAD_DEBRAIN)
|
||||
|
||||
/// Return value when the surgery step fails :(
|
||||
#define SURGERY_STEP_FAIL -1
|
||||
|
||||
@@ -619,7 +619,11 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_BLIND_TOOL "blind_tool"
|
||||
|
||||
/// The person with this trait always appears as 'unknown'.
|
||||
#define TRAIT_UNKNOWN "unknown"
|
||||
#define TRAIT_UNKNOWN_APPEARANCE "unknown_appearance"
|
||||
/// The person with this trait always talks as 'unknown'
|
||||
#define TRAIT_UNKNOWN_VOICE "unknown_voice"
|
||||
/// Spoken voice always matches any worn ID. If no worn ID, defaults to actual name.
|
||||
#define TRAIT_VOICE_MATCHES_ID "voice_matches_id"
|
||||
|
||||
/// If the mob has this trait and die, their bomb implant doesn't detonate automatically. It must be consciously activated.
|
||||
#define TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION "prevent_implant_auto_explosion"
|
||||
|
||||
@@ -411,7 +411,7 @@
|
||||
return gender
|
||||
|
||||
/mob/living/carbon/human/get_visible_gender()
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return PLURAL
|
||||
// If both face and uniform are hidden, can't assess gender
|
||||
if(obscured_slots & (HIDEFACE|HIDEJUMPSUIT) == (HIDEFACE|HIDEJUMPSUIT))
|
||||
|
||||
@@ -589,7 +589,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE,
|
||||
"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE,
|
||||
"TRAIT_UNINTELLIGIBLE_SPEECH" = TRAIT_UNINTELLIGIBLE_SPEECH,
|
||||
"TRAIT_UNKNOWN" = TRAIT_UNKNOWN,
|
||||
"TRAIT_UNKNOWN_APPEARANCE" = TRAIT_UNKNOWN_APPEARANCE,
|
||||
"TRAIT_UNKNOWN_VOICE" = TRAIT_UNKNOWN_VOICE,
|
||||
"TRAIT_UNNATURAL_RED_GLOWY_EYES" = TRAIT_UNNATURAL_RED_GLOWY_EYES,
|
||||
"TRAIT_UNOBSERVANT" = TRAIT_UNOBSERVANT,
|
||||
"TRAIT_UNSTABLE" = TRAIT_UNSTABLE,
|
||||
@@ -602,6 +603,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_VENTCRAWLER_NUDE" = TRAIT_VENTCRAWLER_NUDE,
|
||||
"TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE,
|
||||
"TRAIT_VIRUS_RESISTANCE" = TRAIT_VIRUS_RESISTANCE,
|
||||
"TRAIT_VOICE_MATCHES_ID" = TRAIT_VOICE_MATCHES_ID,
|
||||
"TRAIT_VORACIOUS" = TRAIT_VORACIOUS,
|
||||
"TRAIT_WAS_EVOLVED" = TRAIT_WAS_EVOLVED,
|
||||
"TRAIT_WATER_ADAPTATION" = TRAIT_WATER_ADAPTATION,
|
||||
|
||||
@@ -315,7 +315,8 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
|
||||
"TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE,
|
||||
"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE,
|
||||
"TRAIT_UNINTELLIGIBLE_SPEECH" = TRAIT_UNINTELLIGIBLE_SPEECH,
|
||||
"TRAIT_UNKNOWN" = TRAIT_UNKNOWN,
|
||||
"TRAIT_UNKNOWN_APPEARANCE" = TRAIT_UNKNOWN_APPEARANCE,
|
||||
"TRAIT_UNKNOWN_VOICE" = TRAIT_UNKNOWN_VOICE,
|
||||
"TRAIT_UNNATURAL_RED_GLOWY_EYES" = TRAIT_UNNATURAL_RED_GLOWY_EYES,
|
||||
"TRAIT_UNOBSERVANT" = TRAIT_UNOBSERVANT,
|
||||
"TRAIT_UNSTABLE" = TRAIT_UNSTABLE,
|
||||
@@ -326,6 +327,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
|
||||
"TRAIT_VENTCRAWLER_NUDE" = TRAIT_VENTCRAWLER_NUDE,
|
||||
"TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE,
|
||||
"TRAIT_VIRUS_RESISTANCE" = TRAIT_VIRUS_RESISTANCE,
|
||||
"TRAIT_VOICE_MATCHES_ID" = TRAIT_VOICE_MATCHES_ID,
|
||||
"TRAIT_VORACIOUS" = TRAIT_VORACIOUS,
|
||||
"TRAIT_WATER_ADAPTATION" = TRAIT_WATER_ADAPTATION,
|
||||
"TRAIT_WATER_HATER" = TRAIT_WATER_HATER,
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
if(HAS_TRAIT(target, TRAIT_SIGN_LANG))
|
||||
chat_color_name_to_use = target.get_visible_name(add_id_name = FALSE) // use face name for signers too
|
||||
else
|
||||
chat_color_name_to_use = target.GetVoice() // for everything else, use the target's voice name
|
||||
chat_color_name_to_use = target.get_voice() // for everything else, use the target's voice name
|
||||
|
||||
// Calculate target color if not already present
|
||||
if (!target.chat_color || target.chat_color_name != chat_color_name_to_use)
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
if (isnull(creator))
|
||||
return
|
||||
icon_state = callout::icon_state
|
||||
color = colorize_string(creator.GetVoice(), 2, 0.9)
|
||||
color = colorize_string(creator.get_voice(), 2, 0.9)
|
||||
update_appearance()
|
||||
var/turf/target_loc = get_turf(target)
|
||||
animate(src, pixel_x = (target_loc.x - loc.x) * ICON_SIZE_X + target.pixel_x, pixel_y = (target_loc.y - loc.y) * ICON_SIZE_Y + target.pixel_y, time = 0.2 SECONDS, easing = EASE_OUT)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
RegisterSignal(user, COMSIG_HUMAN_GET_VISIBLE_NAME, PROC_REF(on_name_inquiry))
|
||||
RegisterSignal(user, COMSIG_HUMAN_GET_FORCED_NAME, PROC_REF(on_name_inquiry))
|
||||
// This forces a name update on the user, so we don't need to call name update ourselves
|
||||
ADD_TRAIT(user, TRAIT_UNKNOWN, REF(src))
|
||||
ADD_TRAIT(user, TRAIT_UNKNOWN_APPEARANCE, REF(src))
|
||||
|
||||
current_slot = slot
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
))
|
||||
current_slot = null
|
||||
user.remove_alt_appearance("sneaking_mission[REF(src)]")
|
||||
REMOVE_TRAIT(user, TRAIT_UNKNOWN, REF(src))
|
||||
REMOVE_TRAIT(user, TRAIT_UNKNOWN_APPEARANCE, REF(src))
|
||||
|
||||
///Checks if a mob is holding us, and if so we will modify our appearance to properly match w/ the mob.
|
||||
/datum/component/tactical/proc/tactical_update(obj/item/source)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
else
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.SetSpecialVoice(H.generate_random_mob_name())
|
||||
H.override_voice = H.generate_random_mob_name()
|
||||
if(scramble_language && !current_language) // Last part prevents rerolling language with small amounts of cure.
|
||||
current_language = pick(subtypesof(/datum/language) - /datum/language/common)
|
||||
H.add_blocked_language(subtypesof(/datum/language) - current_language, source = LANGUAGE_VOICECHANGE)
|
||||
@@ -64,7 +64,7 @@
|
||||
..()
|
||||
if(ishuman(A.affected_mob))
|
||||
var/mob/living/carbon/human/H = A.affected_mob
|
||||
H.UnsetSpecialVoice()
|
||||
H.override_voice = ""
|
||||
if(scramble_language)
|
||||
A.affected_mob.remove_blocked_language(subtypesof(/datum/language), source = LANGUAGE_VOICECHANGE)
|
||||
A.affected_mob.remove_all_languages(LANGUAGE_VOICECHANGE) // In case someone managed to get more than one anyway.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
if(!ishuman(examined) || source == examined)
|
||||
return NONE
|
||||
|
||||
var/id_name = examined.get_id_name("")
|
||||
var/id_name = examined.get_id_name("", honorifics = TRUE)
|
||||
name_override[1] = id_name ? "[id_name]?" : "Unknown"
|
||||
return COMPONENT_EXAMINE_NAME_OVERRIDEN
|
||||
|
||||
@@ -31,6 +31,6 @@
|
||||
if(!ishuman(hovered) || source == hovered)
|
||||
return NONE
|
||||
|
||||
var/id_name = hovered.get_id_name("")
|
||||
var/id_name = hovered.get_id_name("", honorifics = TRUE)
|
||||
returned_name[1] = id_name ? "[id_name]?" : "Unknown"
|
||||
return SCREENTIP_NAME_SET
|
||||
|
||||
@@ -266,7 +266,7 @@ Security HUDs! Basic mode shows only the job.
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/sechud_icon_state = wear_id?.get_sechud_job_icon_state()
|
||||
if(!sechud_icon_state || HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(!sechud_icon_state || HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
sechud_icon_state = "hudno_id"
|
||||
set_hud_image_state(ID_HUD, sechud_icon_state)
|
||||
sec_hud_set_security_status()
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
. = ..()
|
||||
cached_flat_icon = null
|
||||
|
||||
/// Called to get what name this card represents
|
||||
/obj/item/card/proc/get_displayed_name(honorifics = FALSE)
|
||||
return null
|
||||
|
||||
/// If no cached_flat_icon exists, this proc creates it and crops it. This proc then returns the cached_flat_icon. Intended for use displaying ID card icons in chat.
|
||||
/obj/item/card/proc/get_cached_flat_icon()
|
||||
if(!cached_flat_icon)
|
||||
@@ -146,7 +150,7 @@
|
||||
SSid_access.apply_trim_to_card(src, trim)
|
||||
else
|
||||
update_label()
|
||||
update_icon()
|
||||
update_appearance()
|
||||
|
||||
// Apply any active RETA grants to this new ID card
|
||||
// This will only do something if there are active grants, so it's safe to call always
|
||||
@@ -156,7 +160,6 @@
|
||||
register_context()
|
||||
|
||||
RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, PROC_REF(update_in_wallet))
|
||||
RegisterSignal(src, COMSIG_ID_GET_HONORIFIC, PROC_REF(return_message_name_part))
|
||||
if(prob(1))
|
||||
ADD_TRAIT(src, TRAIT_TASTEFULLY_THICK_ID_CARD, ROUNDSTART_TRAIT)
|
||||
|
||||
@@ -188,19 +191,25 @@
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_POINTED)
|
||||
return ..()
|
||||
|
||||
/obj/item/card/id/proc/return_message_name_part(datum/source, list/stored_name, mob/living/carbon/carbon_human)
|
||||
SIGNAL_HANDLER
|
||||
var/voice_name = carbon_human.GetVoice()
|
||||
var/end_string = ""
|
||||
var/return_string = ""
|
||||
if(carbon_human.name != voice_name)
|
||||
end_string += " (as [registered_name])"
|
||||
if(trim && honorific_position != HONORIFIC_POSITION_NONE && (carbon_human.name == voice_name)) //The voice and name are the same, so we display the title.
|
||||
return_string += honorific_title
|
||||
else
|
||||
return_string += voice_name //Name on the ID ain't the same as the speaker, so we display their real name with no title.
|
||||
return_string += end_string
|
||||
stored_name[NAME_PART_INDEX] = return_string
|
||||
/obj/item/card/id/equipped(mob/user, slot, initial = FALSE)
|
||||
. = ..()
|
||||
if(!(slot & ITEM_SLOT_ID))
|
||||
return
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/as_human = user
|
||||
as_human.update_visible_name()
|
||||
|
||||
/obj/item/card/id/dropped(mob/user, silent = FALSE)
|
||||
. = ..()
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/as_human = user
|
||||
as_human.update_visible_name()
|
||||
|
||||
/// Getter for the registered name, with optional honorifics
|
||||
/obj/item/card/id/get_displayed_name(honorifics = FALSE)
|
||||
if(honorifics && honorific_position != HONORIFIC_POSITION_NONE && honorific_title)
|
||||
return honorific_title
|
||||
return registered_name
|
||||
|
||||
/obj/item/card/id/proc/on_loc_equipped(datum/source, mob/equipper, slot)
|
||||
SIGNAL_HANDLER
|
||||
@@ -214,7 +223,7 @@
|
||||
|
||||
/obj/item/card/id/proc/on_pointed(mob/living/user, atom/pointed, obj/effect/temp_visual/point/point)
|
||||
SIGNAL_HANDLER
|
||||
if ((!big_pointer && !pointer_color) || HAS_TRAIT(user, TRAIT_UNKNOWN))
|
||||
if ((!big_pointer && !pointer_color) || HAS_TRAIT(user, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return
|
||||
if (point.icon_state != /obj/effect/temp_visual/point::icon_state) //it differs from the original icon_state already.
|
||||
return
|
||||
@@ -650,7 +659,7 @@
|
||||
switch(var_name)
|
||||
if(NAMEOF(src, assignment), NAMEOF(src, registered_name), NAMEOF(src, registered_age))
|
||||
update_label()
|
||||
update_icon()
|
||||
update_appearance()
|
||||
if(NAMEOF(src, trim))
|
||||
if(ispath(trim))
|
||||
SSid_access.apply_trim_to_card(src, trim)
|
||||
@@ -945,6 +954,10 @@
|
||||
|
||||
name = "[name_string] ([assignment_string])"
|
||||
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/human = loc
|
||||
human.update_visible_name()
|
||||
|
||||
/// Re-generates the honorific title. Returns the compiled honorific_title value
|
||||
/obj/item/card/id/proc/update_honorific()
|
||||
switch(honorific_position)
|
||||
@@ -1879,7 +1892,7 @@
|
||||
REMOVE_TRAIT(src, TRAIT_MAGNETIC_ID_CARD, CHAMELEON_ITEM_TRAIT)
|
||||
user.log_message("reset \the [initial(name)] named \"[src]\" to default.", LOG_GAME)
|
||||
update_label()
|
||||
update_icon()
|
||||
update_appearance()
|
||||
forged = FALSE
|
||||
to_chat(user, span_notice("You successfully reset the ID card."))
|
||||
return
|
||||
@@ -1939,7 +1952,7 @@
|
||||
ADD_TRAIT(src, TRAIT_MAGNETIC_ID_CARD, CHAMELEON_ITEM_TRAIT)
|
||||
|
||||
update_label()
|
||||
update_icon()
|
||||
update_appearance()
|
||||
forged = TRUE
|
||||
to_chat(user, span_notice("You successfully forge the ID card."))
|
||||
user.log_message("forged \the [initial(name)] with name \"[registered_name]\", occupation \"[assignment]\" and trim \"[trim?.assignment]\".", LOG_GAME)
|
||||
@@ -2057,35 +2070,8 @@
|
||||
. = ..()
|
||||
register_context()
|
||||
|
||||
/obj/item/card/cardboard/equipped(mob/user, slot, initial = FALSE)
|
||||
. = ..()
|
||||
if(slot != ITEM_SLOT_ID)
|
||||
return
|
||||
RegisterSignal(user, COMSIG_HUMAN_GET_VISIBLE_NAME, PROC_REF(return_visible_name))
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MESSAGE_GET_NAME_PART, PROC_REF(return_message_name_part))
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/as_human = user
|
||||
as_human.update_visible_name()
|
||||
|
||||
/obj/item/card/cardboard/dropped(mob/user, silent = FALSE)
|
||||
. = ..()
|
||||
UnregisterSignal(user, list(COMSIG_HUMAN_GET_VISIBLE_NAME, COMSIG_MOVABLE_MESSAGE_GET_NAME_PART))
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/as_human = user
|
||||
as_human.update_visible_name()
|
||||
|
||||
/obj/item/card/cardboard/proc/return_visible_name(mob/living/carbon/human/source, list/identity)
|
||||
SIGNAL_HANDLER
|
||||
identity[VISIBLE_NAME_ID] = scribbled_name
|
||||
|
||||
/obj/item/card/cardboard/proc/return_message_name_part(mob/living/carbon/human/source, list/stored_name, visible_name)
|
||||
SIGNAL_HANDLER
|
||||
if(visible_name)
|
||||
return
|
||||
var/voice_name = source.GetVoice()
|
||||
if(source.name != voice_name)
|
||||
voice_name += " (as [scribbled_name])"
|
||||
stored_name[NAME_PART_INDEX] = voice_name
|
||||
/obj/item/card/cardboard/get_displayed_name(honorifics = FALSE)
|
||||
return scribbled_name
|
||||
|
||||
/obj/item/card/cardboard/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
||||
if(user.can_write(tool, TRUE))
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
return
|
||||
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity,"mm:ss", NO_TIMEZONE)]\] [speaker.GetVoice()]: [raw_message]"
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity,"mm:ss", NO_TIMEZONE)]\] [speaker.get_voice()]: [raw_message]"
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/record()
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
var/prox_check = TRUE //If the emag requires you to be in range
|
||||
var/type_blacklist //List of types that require a specialized emag
|
||||
|
||||
/obj/item/card/emag/get_displayed_name(honorifics = FALSE)
|
||||
return name // That's Grey Tider (as "cryptographic sequencer")
|
||||
|
||||
/obj/item/card/emag/attack_self(mob/user) //for traitors with balls of plastitanium
|
||||
if(Adjacent(user))
|
||||
user.visible_message(span_notice("[user] shows you: [icon2html(src, viewers(user))] [name]."), span_notice("You show [src]."))
|
||||
@@ -99,6 +102,9 @@
|
||||
/// Whether we are exploding
|
||||
var/exploding = FALSE
|
||||
|
||||
/obj/item/card/emagfake/get_displayed_name(honorifics = FALSE)
|
||||
return name // That's Grey Tider (as "cryptographic sequencer")
|
||||
|
||||
/obj/item/card/emagfake/attack_self(mob/user) //for assistants with balls of plasteel
|
||||
if(Adjacent(user))
|
||||
user.visible_message(span_notice("[user] shows you: [icon2html(src, viewers(user))] [name]."), span_notice("You show [src]."))
|
||||
|
||||
@@ -1448,7 +1448,7 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/toy_talk)
|
||||
|
||||
/obj/item/toy/dummy/GetVoice()
|
||||
/obj/item/toy/dummy/get_voice()
|
||||
return doll_name
|
||||
|
||||
/obj/item/toy/seashell
|
||||
|
||||
+9
-17
@@ -149,21 +149,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
//Radio freq/name display
|
||||
var/freqpart = radio_freq ? "\[[get_radio_name(radio_freq, radio_freq_name)]\] " : ""
|
||||
//Speaker name
|
||||
var/namepart
|
||||
var/list/stored_name = list(null)
|
||||
|
||||
if(iscarbon(speaker)) //First, try to pull the modified title from a carbon's ID. This will override both visual and audible names.
|
||||
var/mob/living/carbon/carbon_human = speaker
|
||||
var/obj/item/id_slot = carbon_human.get_item_by_slot(ITEM_SLOT_ID)
|
||||
if(id_slot)
|
||||
var/obj/item/card/id/id_card = id_slot?.GetID()
|
||||
if(id_card)
|
||||
SEND_SIGNAL(id_card, COMSIG_ID_GET_HONORIFIC, stored_name, carbon_human)
|
||||
|
||||
if(!stored_name[NAME_PART_INDEX]) //Otherwise, we just use whatever the name signal gives us.
|
||||
SEND_SIGNAL(speaker, COMSIG_MOVABLE_MESSAGE_GET_NAME_PART, stored_name, visible_name)
|
||||
|
||||
namepart = stored_name[NAME_PART_INDEX] || "[speaker.GetVoice()]"
|
||||
var/namepart = speaker.get_message_voice(visible_name)
|
||||
|
||||
//End name span.
|
||||
var/endspanpart = "</span>"
|
||||
@@ -333,9 +319,15 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
return "2"
|
||||
return "0"
|
||||
|
||||
/atom/proc/GetVoice()
|
||||
/// Get what this atom sounds like when speaking
|
||||
/atom/proc/get_voice()
|
||||
return "[src]" //Returns the atom's name, prepended with 'The' if it's not a proper noun
|
||||
|
||||
/// Get what this atom appears like in chat when speaking
|
||||
/// visible_name - If TRUE, returns the visible name rather than the voice
|
||||
/atom/proc/get_message_voice(visible_name)
|
||||
return visible_name ? get_visible_name() : get_voice()
|
||||
|
||||
//HACKY VIRTUALSPEAKER STUFF BEYOND THIS POINT
|
||||
//these exist mostly to deal with the AIs hrefs and job stuff.
|
||||
|
||||
@@ -357,7 +349,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/virtualspeaker)
|
||||
radio = _radio
|
||||
source = M
|
||||
if(istype(M))
|
||||
name = radio.anonymize ? "Unknown" : M.GetVoice()
|
||||
name = radio.anonymize ? "Unknown" : M.get_voice()
|
||||
verb_say = M.get_default_say_verb()
|
||||
verb_ask = M.verb_ask
|
||||
verb_exclaim = M.verb_exclaim
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
req_human = TRUE
|
||||
|
||||
// Fake Voice
|
||||
/datum/action/changeling/mimicvoice/sting_action(mob/user)
|
||||
/datum/action/changeling/mimicvoice/sting_action(mob/living/carbon/human/user)
|
||||
var/datum/antagonist/changeling/changeling = IS_CHANGELING(user)
|
||||
if(changeling.mimicing)
|
||||
changeling.mimicing = ""
|
||||
if(user.override_voice)
|
||||
changeling.chem_recharge_slowdown -= 0.25
|
||||
user.override_voice = ""
|
||||
to_chat(user, span_notice("We return our vocal glands to their original position."))
|
||||
return
|
||||
|
||||
@@ -20,16 +20,16 @@
|
||||
if(!mimic_voice)
|
||||
return
|
||||
..()
|
||||
changeling.mimicing = mimic_voice
|
||||
changeling.chem_recharge_slowdown += 0.25
|
||||
user.override_voice = mimic_voice
|
||||
to_chat(user, span_notice("We shape our glands to take the voice of <b>[mimic_voice]</b>, this will slow down regenerating chemicals while active."))
|
||||
to_chat(user, span_notice("Use this power again to return to our original voice and return chemical production to normal levels."))
|
||||
return TRUE
|
||||
|
||||
/datum/action/changeling/mimicvoice/Remove(mob/user)
|
||||
/datum/action/changeling/mimicvoice/Remove(mob/living/carbon/human/user)
|
||||
var/datum/antagonist/changeling/changeling = IS_CHANGELING(user)
|
||||
if(changeling?.mimicing)
|
||||
changeling.chem_recharge_slowdown = max(0, changeling.chem_recharge_slowdown - 0.25)
|
||||
changeling.mimicing = ""
|
||||
if(user.override_voice)
|
||||
changeling?.chem_recharge_slowdown = max(0, changeling.chem_recharge_slowdown - 0.25)
|
||||
user.override_voice = ""
|
||||
to_chat(user, span_notice("Our vocal glands return to their original position."))
|
||||
. = ..()
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
animate(cloak_image, alpha = 255, 0.2 SECONDS)
|
||||
owner.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, id, cloak_image)
|
||||
// Add the relevant traits and modifiers
|
||||
owner.add_traits(list(TRAIT_UNKNOWN, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
owner.add_traits(list(TRAIT_UNKNOWN_APPEARANCE, TRAIT_UNKNOWN_VOICE, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
owner.add_movespeed_modifier(/datum/movespeed_modifier/shadow_cloak)
|
||||
owner.add_actionspeed_modifier(/datum/actionspeed_modifier/shadow_cloak)
|
||||
// Register signals to cause effects
|
||||
@@ -157,7 +157,7 @@
|
||||
owner.remove_alt_appearance(id)
|
||||
QDEL_NULL(cloak_image)
|
||||
// Remove traits and modifiers
|
||||
owner.remove_traits(list(TRAIT_UNKNOWN, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
owner.remove_traits(list(TRAIT_UNKNOWN_APPEARANCE, TRAIT_UNKNOWN_VOICE, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
owner.remove_movespeed_modifier(/datum/movespeed_modifier/shadow_cloak)
|
||||
owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/shadow_cloak)
|
||||
// Clear signals
|
||||
|
||||
@@ -345,11 +345,11 @@
|
||||
alert_type = /atom/movable/screen/alert/status_effect/moon_grasp_hide
|
||||
|
||||
/datum/status_effect/moon_grasp_hide/on_apply()
|
||||
owner.add_traits(list(TRAIT_UNKNOWN, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
owner.add_traits(list(TRAIT_UNKNOWN_APPEARANCE, TRAIT_UNKNOWN_VOICE, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
return TRUE
|
||||
|
||||
/datum/status_effect/moon_grasp_hide/on_remove()
|
||||
owner.remove_traits(list(TRAIT_UNKNOWN, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
owner.remove_traits(list(TRAIT_UNKNOWN_APPEARANCE, TRAIT_UNKNOWN_VOICE, TRAIT_SILENT_FOOTSTEPS), TRAIT_STATUS_EFFECT(id))
|
||||
|
||||
/atom/movable/screen/alert/status_effect/moon_grasp_hide
|
||||
name = "Blessing of The Moon"
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
listening = FALSE
|
||||
say("Activation message is '[recorded]'.", sanitize = FALSE, language = message_language)
|
||||
if(RECOGNIZER_MODE)
|
||||
recorded = speaker.GetVoice()
|
||||
recorded = speaker.get_voice()
|
||||
listening = FALSE
|
||||
say("Your voice pattern is saved.", language = message_language)
|
||||
if(VOICE_SENSOR_MODE)
|
||||
@@ -81,7 +81,7 @@
|
||||
if(raw_message == recorded)
|
||||
return TRUE
|
||||
if(RECOGNIZER_MODE)
|
||||
if(speaker.GetVoice() == recorded)
|
||||
if(speaker.get_voice() == recorded)
|
||||
return TRUE
|
||||
if(VOICE_SENSOR_MODE)
|
||||
if(length(raw_message))
|
||||
|
||||
@@ -185,12 +185,15 @@ do { \
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/mask)
|
||||
action_slots = ALL
|
||||
/// Is our voice changer enabled or disabled?
|
||||
var/voice_change = TRUE
|
||||
clothing_traits = list(TRAIT_VOICE_MATCHES_ID)
|
||||
|
||||
/obj/item/clothing/mask/chameleon/attack_self(mob/user)
|
||||
voice_change = !voice_change
|
||||
to_chat(user, span_notice("The voice changer is now [voice_change ? "on" : "off"]!"))
|
||||
var/was_on = (TRAIT_VOICE_MATCHES_ID in clothing_traits)
|
||||
if(was_on)
|
||||
attach_clothing_traits(TRAIT_VOICE_MATCHES_ID)
|
||||
else
|
||||
detach_clothing_traits(TRAIT_VOICE_MATCHES_ID)
|
||||
to_chat(user, span_notice("The voice changer is now [was_on ? "off" : "on"]!"))
|
||||
|
||||
/obj/item/clothing/mask/chameleon/broken
|
||||
|
||||
@@ -203,7 +206,7 @@ do { \
|
||||
item_flags = DROPDEL
|
||||
//Same as the drone chameleon hat, undroppable and no protection
|
||||
armor_type = /datum/armor/none
|
||||
voice_change = FALSE
|
||||
clothing_traits = null
|
||||
|
||||
/obj/item/clothing/mask/chameleon/drone/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/obj/item/skillchip/big_pointer/proc/fancier_pointer(mob/living/user, atom/pointed, obj/effect/temp_visual/point/point)
|
||||
SIGNAL_HANDLER
|
||||
if(HAS_TRAIT(user, TRAIT_UNKNOWN))
|
||||
if(HAS_TRAIT(user, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return
|
||||
point.cut_overlays()
|
||||
var/datum/action/change_pointer_color/action = locate() in actions
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
return null
|
||||
|
||||
/mob/living/carbon/examine(mob/user)
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return list(span_warning("You're struggling to make out any details..."))
|
||||
|
||||
var/t_He = p_They()
|
||||
@@ -587,7 +587,7 @@
|
||||
if(undershirt.has_sensor == BROKEN_SENSORS)
|
||||
. += list(span_notice("\The [undershirt]'s medical sensors are sparking."))
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN))
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN))
|
||||
return
|
||||
|
||||
var/limbs_text = get_mismatched_limb_text()
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
if(!same_id || (text2num(href_list["examine_time"]) + viable_time) < world.time)
|
||||
to_chat(viewer, span_notice("You don't have that good of a memory. Examine [p_them()] again."))
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
to_chat(viewer, span_notice("You can't make out that ID anymore."))
|
||||
return
|
||||
if(!isobserver(viewer) && get_dist(viewer, src) > ID_EXAMINE_DISTANCE + 1) // leeway, ignored if the viewer is a ghost
|
||||
|
||||
@@ -70,7 +70,8 @@
|
||||
var/obj/item/l_store = null
|
||||
var/obj/item/s_store = null
|
||||
|
||||
var/special_voice = "" // For changing our voice. Used by a symptom.
|
||||
/// Allows for special overrides of voice
|
||||
var/override_voice = ""
|
||||
|
||||
var/datum/physiology/physiology
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//Useful when player do something with computers
|
||||
/mob/living/carbon/human/proc/get_assignment(if_no_id = "No id", if_no_job = "No job", hand_first = TRUE)
|
||||
var/obj/item/card/id/id = get_idcard(hand_first)
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return if_no_id
|
||||
if(id)
|
||||
. = id.assignment
|
||||
@@ -25,7 +25,7 @@
|
||||
//Useful when player do something with computers
|
||||
/mob/living/carbon/human/proc/get_authentification_name(if_no_id = "Unknown")
|
||||
var/obj/item/card/id/id = get_idcard(FALSE)
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return if_no_id
|
||||
if(id)
|
||||
return id.registered_name
|
||||
@@ -48,64 +48,66 @@
|
||||
var/force_set = LAZYACCESS(identity, VISIBLE_NAME_FORCED)
|
||||
if(force_set) // our name is overriden by something
|
||||
return signal_face // no need to null-check, because force_set will always set a signal_face
|
||||
var/face_name = !isnull(signal_face) ? signal_face : get_face_name("")
|
||||
var/id_name = !isnull(signal_id) ? signal_id : get_id_name("")
|
||||
if(force_real_name)
|
||||
var/fake_name
|
||||
if (face_name && face_name != real_name)
|
||||
fake_name = face_name
|
||||
if(add_id_name && id_name && id_name != real_name)
|
||||
if (!isnull(fake_name) && id_name != face_name)
|
||||
fake_name = "[fake_name]/[id_name]"
|
||||
else
|
||||
fake_name = id_name
|
||||
if (HAS_TRAIT(src, TRAIT_UNKNOWN) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN) || (!face_name && !id_name))
|
||||
fake_name = "Unknown"
|
||||
return "[real_name][fake_name ? " (as [fake_name])" : ""]"
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN))
|
||||
return "Unknown"
|
||||
if(face_name)
|
||||
if(add_id_name && id_name && (id_name != face_name))
|
||||
return "[face_name] (as [id_name])"
|
||||
return face_name
|
||||
if(id_name)
|
||||
return id_name
|
||||
return "Unknown"
|
||||
|
||||
/// Returns "Unknown" if facially disfigured and real_name if not.
|
||||
/// Useful for setting name when Fluacided or when updating a human's name variable
|
||||
var/face_name = isnull(signal_face) ? get_face_name("") : signal_face
|
||||
var/id_name = isnull(signal_id) ? get_id_name("", honorifics = TRUE) : signal_id
|
||||
|
||||
// We need to account for real name
|
||||
if(force_real_name)
|
||||
var/disguse_name = get_visible_name(add_id_name = TRUE, force_real_name = FALSE)
|
||||
return "[real_name][disguse_name == real_name ? "" : " (as [disguse_name])"]"
|
||||
|
||||
// We're just some unknown guy
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN))
|
||||
return "Unknown"
|
||||
|
||||
// We have a face and an ID
|
||||
if(face_name && id_name)
|
||||
var/normal_id_name = get_id_name("") // need to check base ID name to avoid "John (as Captain John)"
|
||||
if(normal_id_name == face_name)
|
||||
return id_name // (this turns "John" into "Captain John")
|
||||
if(add_id_name)
|
||||
return "[face_name] (as [id_name])"
|
||||
|
||||
// Just go down the list of stuff we recorded
|
||||
return face_name || id_name || "Unknown"
|
||||
|
||||
/**
|
||||
* Gets what the face of this mob looks like
|
||||
*
|
||||
* * if_no_face - What to return if we have no face or our face is obscured/disfigured
|
||||
*/
|
||||
/mob/living/carbon/proc/get_face_name(if_no_face = "Unknown")
|
||||
return real_name
|
||||
|
||||
/mob/living/carbon/human/get_face_name(if_no_face = "Unknown")
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return if_no_face //We're Unknown, no face information for you
|
||||
if(obscured_slots & HIDEFACE)
|
||||
return if_no_face
|
||||
var/obj/item/bodypart/head = get_bodypart(BODY_ZONE_HEAD)
|
||||
if(isnull(head) || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (head.brutestate + head.burnstate) > 2 || !real_name || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN)) //disfigured. use id-name if possible
|
||||
if(isnull(head) || !real_name || HAS_TRAIT(src, TRAIT_DISFIGURED) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN)) //disfigured. use id-name if possible
|
||||
return if_no_face
|
||||
return real_name
|
||||
|
||||
//gets name from ID or PDA itself, ID inside PDA doesn't matter
|
||||
//Useful when player is being seen by other mobs
|
||||
/mob/living/carbon/proc/get_id_name(if_no_id = "Unknown")
|
||||
/**
|
||||
* Gets whatever name is in our ID or PDA
|
||||
*
|
||||
* * if_no_id - What to return if we have no ID or PDA
|
||||
* * honorifics - Whether to include honorifics in the returned name (if the found ID has any set)
|
||||
*/
|
||||
/mob/living/carbon/proc/get_id_name(if_no_id = "Unknown", honorifics = FALSE)
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/get_id_name(if_no_id = "Unknown")
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
. = if_no_id //You get NOTHING, no id name, good day sir
|
||||
/mob/living/carbon/human/get_id_name(if_no_id = "Unknown", honorifics = FALSE)
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
var/list/identity = list(null, null, null)
|
||||
SEND_SIGNAL(src, COMSIG_HUMAN_GET_FORCED_NAME, identity)
|
||||
if(identity[VISIBLE_NAME_FORCED])
|
||||
return identity[VISIBLE_NAME_FACE] // to return forced names when unknown, instead of ID
|
||||
else
|
||||
var/obj/item/card/id/id = astype(wear_id, /obj/item/card/id) \
|
||||
|| astype(wear_id, /obj/item/storage/wallet)?.front_id \
|
||||
|| astype(wear_id, /obj/item/modular_computer)?.stored_id
|
||||
. = id?.registered_name
|
||||
if(!.)
|
||||
. = if_no_id //to prevent null-names making the mob unclickable
|
||||
return identity[VISIBLE_NAME_FORCED] ? identity[VISIBLE_NAME_FACE] : if_no_id
|
||||
|
||||
// either results in an ID card, a generic card, or null
|
||||
var/obj/item/card/id = wear_id?.GetID() || astype(wear_id, /obj/item/card)
|
||||
return id?.get_displayed_name(honorifics) || if_no_id
|
||||
|
||||
/mob/living/carbon/human/get_idcard(hand_first = TRUE)
|
||||
. = ..()
|
||||
|
||||
@@ -29,40 +29,22 @@
|
||||
return "gurgles"
|
||||
return tongue.temp_say_mod || tongue.say_mod || ..()
|
||||
|
||||
/mob/living/carbon/human/GetVoice()
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
return ("Unknown")
|
||||
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
|
||||
var/obj/item/clothing/mask/chameleon/V = wear_mask
|
||||
if(V.voice_change && wear_id)
|
||||
var/obj/item/card/id/idcard = wear_id.GetID()
|
||||
if(istype(idcard))
|
||||
return idcard.registered_name
|
||||
else
|
||||
return real_name
|
||||
else
|
||||
return real_name
|
||||
|
||||
if(mind)
|
||||
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling?.mimicing)
|
||||
return changeling.mimicing
|
||||
if(GetSpecialVoice())
|
||||
return GetSpecialVoice()
|
||||
/mob/living/carbon/human/get_voice()
|
||||
if(HAS_TRAIT(src, TRAIT_UNKNOWN_VOICE))
|
||||
return "Unknown"
|
||||
var/id_name = get_id_name("")
|
||||
if(HAS_TRAIT(src, TRAIT_VOICE_MATCHES_ID) && id_name)
|
||||
return id_name
|
||||
if(override_voice)
|
||||
return override_voice
|
||||
if(real_name == id_name) // Allows for "Captain John" to have the voice "Captain Join" and not "John"
|
||||
return get_id_name("", honorifics = TRUE)
|
||||
return real_name
|
||||
|
||||
/mob/living/carbon/human/proc/SetSpecialVoice(new_voice)
|
||||
if(new_voice)
|
||||
special_voice = new_voice
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/UnsetSpecialVoice()
|
||||
special_voice = ""
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/GetSpecialVoice()
|
||||
return special_voice
|
||||
/mob/living/carbon/human/get_message_voice(visible_name)
|
||||
. = ..()
|
||||
if(. != name)
|
||||
. += " (as [get_id_name("Unknown", honorifics = TRUE)])"
|
||||
|
||||
/mob/living/carbon/human/binarycheck()
|
||||
if(stat >= SOFT_CRIT)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/mob/living/carbon/human/register_init_signals()
|
||||
. = ..()
|
||||
|
||||
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_UNKNOWN), SIGNAL_REMOVETRAIT(TRAIT_UNKNOWN)), PROC_REF(update_ID_card))
|
||||
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_UNKNOWN_APPEARANCE), SIGNAL_REMOVETRAIT(TRAIT_UNKNOWN_APPEARANCE)), PROC_REF(update_ID_card))
|
||||
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_DWARF), SIGNAL_REMOVETRAIT(TRAIT_DWARF)), PROC_REF(on_dwarf_trait))
|
||||
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_TOO_TALL), SIGNAL_REMOVETRAIT(TRAIT_TOO_TALL)), PROC_REF(on_tootall_trait))
|
||||
RegisterSignal(src, COMSIG_MOVABLE_MESSAGE_GET_NAME_PART, PROC_REF(get_name_part))
|
||||
|
||||
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_FAT), SIGNAL_REMOVETRAIT(TRAIT_FAT)), PROC_REF(on_fat))
|
||||
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_NOHUNGER), SIGNAL_REMOVETRAIT(TRAIT_NOHUNGER)), PROC_REF(on_nohunger))
|
||||
@@ -33,21 +32,6 @@
|
||||
SIGNAL_HANDLER
|
||||
update_mob_height()
|
||||
|
||||
///From compose_message(). Snowflake code converted into its own signal proc
|
||||
/mob/living/carbon/human/proc/get_name_part(datum/source, list/stored_name, visible_name)
|
||||
SIGNAL_HANDLER
|
||||
/**
|
||||
* For if the message can be seen but not heard, shows our visible identity (like when using sign language)
|
||||
* Also used by hallucinations, so it doesn't give source's identity away.
|
||||
*/
|
||||
if(visible_name)
|
||||
stored_name[NAME_PART_INDEX] = get_visible_name()
|
||||
return
|
||||
var/voice_name = GetVoice()
|
||||
if(name != voice_name)
|
||||
voice_name += " (as [get_id_name("Unknown")])"
|
||||
stored_name[NAME_PART_INDEX] = voice_name
|
||||
|
||||
/mob/living/carbon/human/proc/on_fat(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
hud_used?.hunger?.update_hunger_bar()
|
||||
|
||||
@@ -2953,7 +2953,7 @@ GLOBAL_LIST_EMPTY(fire_appearances)
|
||||
|
||||
/// Create a report string about how strong this person looks, generated in a somewhat arbitrary fashion
|
||||
/mob/living/proc/compare_fitness(mob/living/scouter)
|
||||
if (HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if (HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE))
|
||||
return span_warning("It's impossible to tell whether this person lifts.")
|
||||
|
||||
var/our_fitness_level = calculate_fitness()
|
||||
|
||||
@@ -424,7 +424,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
|
||||
if(!M.client.prefs.read_preference(/datum/preference/toggle/enable_runechat) || (SSlag_switch.measures[DISABLE_RUNECHAT] && !HAS_TRAIT(src, TRAIT_BYPASS_MEASURES)))
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
found_client = TRUE
|
||||
if(SStts.tts_enabled && voice && found_client && !message_mods[MODE_CUSTOM_SAY_ERASE_INPUT] && !HAS_TRAIT(src, TRAIT_SIGN_LANG) && !HAS_TRAIT(src, TRAIT_UNKNOWN))
|
||||
if(SStts.tts_enabled && voice && found_client && !message_mods[MODE_CUSTOM_SAY_ERASE_INPUT] && !HAS_TRAIT(src, TRAIT_SIGN_LANG) && !HAS_TRAIT(src, TRAIT_UNKNOWN_VOICE))
|
||||
var/tts_message_to_use = tts_message
|
||||
if(!tts_message_to_use)
|
||||
tts_message_to_use = message_raw
|
||||
|
||||
@@ -810,14 +810,14 @@
|
||||
var/treated_message = source.generate_messagepart(raw_translation, spans, message_mods)
|
||||
|
||||
var/start = "Relayed Speech: "
|
||||
var/namepart
|
||||
var/list/stored_name = list(null)
|
||||
SEND_SIGNAL(speaker, COMSIG_MOVABLE_MESSAGE_GET_NAME_PART, stored_name, FALSE)
|
||||
namepart = stored_name[NAME_PART_INDEX] || "[speaker.GetVoice()]"
|
||||
var/namepart = speaker.get_message_voice()
|
||||
var/hrefpart = "<a href='byond://?src=[REF(src)];track=[html_encode(namepart)]'>"
|
||||
var/jobpart = "Unknown"
|
||||
|
||||
if(!HAS_TRAIT(speaker, TRAIT_UNKNOWN)) //don't fetch the speaker's job in case they have something that conseals their identity completely
|
||||
// if voice is concealed, job is concealed
|
||||
// on the other hand we don't care about TRAIT_UNKNOWN_APPEARANCE
|
||||
// (AI can associate voice -> name -> crew record -> job)
|
||||
if(!HAS_TRAIT(speaker, TRAIT_UNKNOWN_VOICE))
|
||||
if (isliving(speaker))
|
||||
var/mob/living/living_speaker = speaker
|
||||
if(living_speaker.job)
|
||||
@@ -1092,7 +1092,7 @@
|
||||
. = ..()
|
||||
.[/datum/job/ai::title] = minutes
|
||||
|
||||
/mob/living/silicon/ai/GetVoice()
|
||||
/mob/living/silicon/ai/get_voice()
|
||||
. = ..()
|
||||
if(ai_voicechanger && ai_voicechanger.changing_voice)
|
||||
return ai_voicechanger.say_name
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
var/namepart = name
|
||||
// If carbon, use voice to account for voice changers
|
||||
if(iscarbon(src))
|
||||
namepart = GetVoice()
|
||||
namepart = get_voice()
|
||||
|
||||
// AI in carbon body should still have its real name
|
||||
var/obj/item/organ/brain/cybernetic/ai/brain = get_organ_slot(ORGAN_SLOT_BRAIN)
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
incompatible_modules = list(/obj/item/mod/module/infiltrator, /obj/item/mod/module/welding/syndicate, /obj/item/mod/module/welding, /obj/item/mod/module/headprotector)
|
||||
required_slots = list(ITEM_SLOT_FEET, ITEM_SLOT_HEAD, ITEM_SLOT_OCLOTHING)
|
||||
/// List of traits added when the suit is activated
|
||||
var/list/traits_to_add = list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN, TRAIT_HEAD_INJURY_BLOCKED)
|
||||
var/list/traits_to_add = list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN_APPEARANCE, TRAIT_UNKNOWN_VOICE, TRAIT_HEAD_INJURY_BLOCKED)
|
||||
|
||||
/obj/item/mod/module/infiltrator/on_install()
|
||||
. = ..()
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
is_dimorphic = FALSE
|
||||
should_draw_greyscale = FALSE
|
||||
bodypart_traits = list(TRAIT_DISFIGURED, TRAIT_BALD, TRAIT_SHAVED)
|
||||
head_flags = HEAD_DEBRAIN
|
||||
head_flags = HEAD_DEBRAIN | HEAD_NO_DISFIGURE // ignore disfigurement by damage, as we're always disfigured
|
||||
|
||||
/// flavorful variant of psykerizing that deals damage and sends messages before calling psykerize()
|
||||
/mob/living/carbon/human/proc/slow_psykerize(blind_them = FALSE)
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
var/unarmed_sharpness = NONE
|
||||
|
||||
/// Traits that are given to the holder of the part. This does not update automatically on life(), only when the organs are initially generated or inserted!
|
||||
var/list/bodypart_traits = list()
|
||||
var/list/bodypart_traits
|
||||
/// The name of the trait source that the organ gives. Should not be altered during the events of gameplay, and will cause problems if it is.
|
||||
var/bodypart_trait_source = BODYPART_TRAIT
|
||||
/// List of the above datums which have actually been instantiated, managed automatically
|
||||
@@ -811,15 +811,15 @@
|
||||
|
||||
if(speed_modifier)
|
||||
old_owner.update_bodypart_speed_modifier()
|
||||
if(length(bodypart_traits))
|
||||
if(LAZYLEN(bodypart_traits))
|
||||
old_owner.remove_traits(bodypart_traits, bodypart_trait_source)
|
||||
|
||||
UnregisterSignal(old_owner, list(
|
||||
SIGNAL_REMOVETRAIT(TRAIT_NOLIMBDISABLE),
|
||||
SIGNAL_ADDTRAIT(TRAIT_NOLIMBDISABLE),
|
||||
SIGNAL_ADDTRAIT(TRAIT_NOLIMBDISABLE),
|
||||
SIGNAL_REMOVETRAIT(TRAIT_NOBLOOD),
|
||||
SIGNAL_ADDTRAIT(TRAIT_NOBLOOD),
|
||||
))
|
||||
))
|
||||
|
||||
UnregisterSignal(old_owner, list(COMSIG_ATOM_RESTYLE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_LIVING_SET_BODY_POSITION))
|
||||
|
||||
@@ -831,7 +831,7 @@
|
||||
|
||||
if(speed_modifier)
|
||||
owner.update_bodypart_speed_modifier()
|
||||
if(length(bodypart_traits))
|
||||
if(LAZYLEN(bodypart_traits))
|
||||
owner.add_traits(bodypart_traits, bodypart_trait_source)
|
||||
|
||||
if(initial(can_be_disabled))
|
||||
@@ -872,7 +872,7 @@
|
||||
item_flags &= ~ABSTRACT
|
||||
REMOVE_TRAIT(src, TRAIT_NODROP, ORGAN_INSIDE_BODY_TRAIT)
|
||||
|
||||
if(!length(bodypart_traits))
|
||||
if(!LAZYLEN(bodypart_traits))
|
||||
return
|
||||
|
||||
owner.remove_traits(bodypart_traits, bodypart_trait_source)
|
||||
@@ -1488,3 +1488,17 @@
|
||||
return "metal"
|
||||
|
||||
return "error"
|
||||
|
||||
/// Add a trait to the bodypart traits list, then applies the trait if necessary
|
||||
/obj/item/bodypart/proc/add_bodypart_trait(new_trait)
|
||||
LAZYOR(bodypart_traits, new_trait)
|
||||
if(isnull(owner))
|
||||
return
|
||||
ADD_TRAIT(owner, new_trait, bodypart_trait_source)
|
||||
|
||||
/// Remove a trait from the bodypart traits list, then removes the trait if necessary
|
||||
/obj/item/bodypart/proc/remove_bodypart_trait(old_trait)
|
||||
LAZYREMOVE(bodypart_traits, old_trait)
|
||||
if(isnull(owner))
|
||||
return
|
||||
REMOVE_TRAIT(owner, old_trait, bodypart_trait_source)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
/// Replacement name
|
||||
var/real_name = ""
|
||||
/// Flags related to appearance, such as hair, lips, etc
|
||||
var/head_flags = HEAD_ALL_FEATURES
|
||||
var/head_flags = HEAD_DEFAULT_FEATURES
|
||||
|
||||
/// Hair style
|
||||
var/hairstyle = "Bald"
|
||||
@@ -210,18 +210,20 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/toy_talk)
|
||||
|
||||
/obj/item/bodypart/head/GetVoice()
|
||||
/obj/item/bodypart/head/get_voice()
|
||||
return "The head of [real_name]"
|
||||
|
||||
/obj/item/bodypart/head/update_bodypart_damage_state()
|
||||
if (!ishuman(owner))
|
||||
if (head_flags & HEAD_NO_DISFIGURE)
|
||||
return ..()
|
||||
|
||||
var/old_states = brutestate + burnstate
|
||||
. = ..()
|
||||
var/new_states = brutestate + burnstate
|
||||
var/mob/living/carbon/human/as_human = owner
|
||||
if ((old_states >= HUMAN_DISFIGURATION_HEAD_DAMAGE_STATES && new_states < HUMAN_DISFIGURATION_HEAD_DAMAGE_STATES) || (old_states < HUMAN_DISFIGURATION_HEAD_DAMAGE_STATES && new_states >= HUMAN_DISFIGURATION_HEAD_DAMAGE_STATES))
|
||||
as_human.update_visible_name()
|
||||
if(new_states >= HUMAN_DISFIGURATION_HEAD_DAMAGE_STATES)
|
||||
add_bodypart_trait(TRAIT_DISFIGURED)
|
||||
else if(old_states >= HUMAN_DISFIGURATION_HEAD_DAMAGE_STATES)
|
||||
remove_bodypart_trait(TRAIT_DISFIGURED)
|
||||
|
||||
/obj/item/bodypart/head/monkey
|
||||
icon = 'icons/mob/human/species/monkey/bodyparts.dmi'
|
||||
|
||||
@@ -53,6 +53,6 @@
|
||||
if(message_language)
|
||||
language_port.set_output(initial(message_language.name))
|
||||
speaker_port.set_output(speaker)
|
||||
speaker_name.set_output(speaker.GetVoice())
|
||||
speaker_name.set_output(speaker.get_voice())
|
||||
trigger_port.set_output(COMPONENT_SIGNAL)
|
||||
return TRUE
|
||||
|
||||
Reference in New Issue
Block a user