From 08448c809fb1943c577ec1d480c58982172b6f19 Mon Sep 17 00:00:00 2001
From: xhankaishi <159677636+xhankaishi@users.noreply.github.com>
Date: Sun, 21 Apr 2024 21:56:57 +0600
Subject: [PATCH] examine living
---
.../mob/living/carbon/human/examine.dm | 3 +
mod_celadon/human_examine/_human_examine.dm | 16 +
mod_celadon/human_examine/_human_examine.dme | 3 +
.../human_examine/code/human_examine.dm | 407 ++++++++++++++++++
mod_celadon/mod_celadon.dme | 1 +
5 files changed, 430 insertions(+)
create mode 100644 mod_celadon/human_examine/_human_examine.dm
create mode 100644 mod_celadon/human_examine/_human_examine.dme
create mode 100644 mod_celadon/human_examine/code/human_examine.dm
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 9c6b1aba5b..54f6b17625 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -1,3 +1,4 @@
+/*
/mob/living/carbon/human/examine(mob/user, distance)
. = TRUE
var/skipgloves = 0
@@ -116,6 +117,7 @@
msg += "[p_they(TRUE)] [p_have()] [r_ear.get_examine_line(user)] on [p_their()] right ear.\n"
//ID
+
if(wear_id)
msg += "[p_they(TRUE)] [p_are()] wearing [wear_id.get_examine_line(user)].\n"
@@ -404,3 +406,4 @@
HTML +="\[Done\]"
HTML += ""
show_browser(src, jointext(HTML,null), "window=flavor_changes;size=430x300")
+*/
diff --git a/mod_celadon/human_examine/_human_examine.dm b/mod_celadon/human_examine/_human_examine.dm
new file mode 100644
index 0000000000..b5671923df
--- /dev/null
+++ b/mod_celadon/human_examine/_human_examine.dm
@@ -0,0 +1,16 @@
+/datum/modpack/human_examine
+ /// A string name for the modpack. Used for looking up other modpacks in init.
+ name = "human_examine"
+ /// A string desc for the modpack. Can be used for modpack verb list as description.
+ desc = "добавлена работа и класс в строку карты при экзамайне"
+ /// A string with authors of this modpack.
+ author = "XAH"
+
+/datum/modpack/human_examine/pre_initialize()
+ . = ..()
+
+/datum/modpack/human_examine/initialize()
+ . = ..()
+
+/datum/modpack/human_examine/post_initialize()
+ . = ..()
diff --git a/mod_celadon/human_examine/_human_examine.dme b/mod_celadon/human_examine/_human_examine.dme
new file mode 100644
index 0000000000..9c307dfa3e
--- /dev/null
+++ b/mod_celadon/human_examine/_human_examine.dme
@@ -0,0 +1,3 @@
+#include "_human_examine.dm"
+
+#include "code/human_examine.dm"
diff --git a/mod_celadon/human_examine/code/human_examine.dm b/mod_celadon/human_examine/code/human_examine.dm
new file mode 100644
index 0000000000..3a7e391051
--- /dev/null
+++ b/mod_celadon/human_examine/code/human_examine.dm
@@ -0,0 +1,407 @@
+/mob/living/carbon/human/examine(mob/user, distance)
+ . = TRUE
+ var/skipgloves = 0
+ var/skipsuitstorage = 0
+ var/skipjumpsuit = 0
+ var/skipshoes = 0
+ var/skipmask = 0
+ var/skipears = 0
+ var/skipeyes = 0
+ var/skipface = 0
+
+ //Skips this for humanoid SCPS
+ if(SCP)
+ to_chat(user, "[icon2html(src, user)] That's \a [src] [suffix]")
+ to_chat(user, desc)
+ return
+
+ //exosuits and helmets obscure our view and stuff.
+ if(wear_suit)
+ skipgloves = wear_suit.flags_inv & HIDEGLOVES
+ skipsuitstorage = wear_suit.flags_inv & HIDESUITSTORAGE
+ skipjumpsuit = wear_suit.flags_inv & HIDEJUMPSUIT
+ skipshoes = wear_suit.flags_inv & HIDESHOES
+
+ if(head)
+ skipmask = head.flags_inv & HIDEMASK
+ skipeyes = head.flags_inv & HIDEEYES
+ skipears = head.flags_inv & HIDEEARS
+ skipface = head.flags_inv & HIDEFACE
+
+ if(wear_mask)
+ skipeyes |= wear_mask.flags_inv & HIDEEYES
+ skipears |= wear_mask.flags_inv & HIDEEARS
+ skipface |= wear_mask.flags_inv & HIDEFACE
+
+ //no accuately spotting headsets from across the room.
+ if(distance > 3)
+ skipears = 1
+
+ var/list/msg = list("*---------*\nThis is ")
+
+ if(!(skipjumpsuit && skipface))
+ if(icon)
+ msg += "[icon2html(icon, user)] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
+
+ msg += "[src.name]"
+
+ var/is_synth = isSynthetic()
+ if(!(skipjumpsuit && skipface))
+ var/species_name = "\improper "
+ if(is_synth && species.cyborg_noun)
+ species_name += "[species.cyborg_noun] [species.get_bodytype(src)]"
+ else
+ species_name += "[species.name]"
+ msg += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value())) ? SPAN_NOTICE(" \[?\]") : ""]"
+
+ msg += "
"
+
+ //uniform
+ if(w_uniform && !skipjumpsuit)
+ msg += "[p_they(TRUE)] [p_are()] wearing [w_uniform.get_examine_line(user)].\n"
+
+ //head
+ if(head)
+ msg += "[p_they(TRUE)] [p_are()] wearing [head.get_examine_line(user)] on [p_their()] head.\n"
+
+ //suit/armour
+ if(wear_suit)
+ msg += "[p_they(TRUE)] [p_are()] wearing [wear_suit.get_examine_line(user)].\n"
+ //suit/armour storage
+ if(s_store && !skipsuitstorage)
+ msg += "[p_they(TRUE)] [p_are()] carrying [s_store.get_examine_line(user)] on [p_their()] [wear_suit.name].\n"
+
+ //back
+ if(back)
+ msg += "[p_they(TRUE)] [p_have()] [back.get_examine_line(user)] on [p_their()] back.\n"
+
+ //left hand
+ if(l_hand)
+ msg += "[p_they(TRUE)] [p_are()] holding [l_hand.get_examine_line(user)] in [p_their()] left hand.\n"
+
+ //right hand
+ if(r_hand)
+ msg += "[p_they(TRUE)] [p_are()] holding [r_hand.get_examine_line(user)] in [p_their()] right hand.\n"
+
+ //gloves
+ if(gloves && !skipgloves)
+ msg += "[p_they(TRUE)] [p_have()] [gloves.get_examine_line(user)] on [p_their()] hands.\n"
+ else if(blood_DNA)
+ msg += "[p_they()] [p_have()] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!\n"
+
+ //belt
+ if(belt)
+ msg += "[p_they(TRUE)] [p_have()] [belt.get_examine_line(user)] about [p_their()] waist.\n"
+
+ //shoes
+ if(shoes && !skipshoes)
+ msg += "[p_they(TRUE)] [p_are()] wearing [shoes.get_examine_line(user)] on [p_their()] feet.\n"
+ else if(feet_blood_DNA)
+ msg += "[p_they()] [p_have()] [(feet_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained feet!\n"
+
+ //mask
+ if(wear_mask && !skipmask)
+ msg += "[p_they(TRUE)] [p_have()] [wear_mask.get_examine_line(user)] on [p_their()] face.\n"
+
+ //eyes
+ if(glasses && !skipeyes)
+ msg += "[p_they(TRUE)] [p_have()] [glasses.get_examine_line(user)] covering [p_their()] eyes.\n"
+
+ //left ear
+ if(l_ear && !skipears)
+ msg += "[p_they(TRUE)] [p_have()] [l_ear.get_examine_line(user)] on [p_their()] left ear.\n"
+
+ //right ear
+ if(r_ear && !skipears)
+ msg += "[p_they(TRUE)] [p_have()] [r_ear.get_examine_line(user)] on [p_their()] right ear.\n"
+
+ //ID
+ if(wear_id)
+ var/obj/item/card/id/id = GetIdCard()
+ msg += "[p_they(TRUE)] [p_are()] wearing [wear_id.get_examine_line(user)]. Job: [id.assignment], [id.class]\n "
+
+ //handcuffed?
+ if(handcuffed)
+ if(istype(handcuffed, /obj/item/handcuffs/cable))
+ msg += "[p_they(TRUE)] [p_are()] [icon2html(handcuffed, user)] restrained with cable!\n"
+ else
+ msg += "[p_they(TRUE)] [p_are()] [icon2html(handcuffed, user)] handcuffed!\n"
+
+ //buckled
+ if(buckled)
+ msg += "[p_they(TRUE)] [p_are()] [icon2html(buckled, user)] buckled to [buckled]!\n"
+
+ //Jitters
+ if(is_jittery)
+ if(jitteriness >= 300)
+ msg += "[p_they(TRUE)] [p_are()] convulsing violently!\n"
+ else if(jitteriness >= 200)
+ msg += "[p_they(TRUE)] [p_are()] extremely jittery.\n"
+ else if(jitteriness >= 100)
+ msg += "[p_they(TRUE)] [p_are()] twitching ever so slightly.\n"
+
+
+ //Disfigured face
+ if(!skipface) //Disfigurement only matters for the head currently.
+ var/obj/item/organ/external/head/E = get_organ(BP_HEAD)
+ if(E && (E.status & ORGAN_DISFIGURED)) //Check to see if we even have a head and if the head's disfigured.
+ if(E.species) //Check to make sure we have a species
+ msg += E.species.disfigure_msg(src)
+ else //Just in case they lack a species for whatever reason.
+ msg += "[p_their()] face is horribly mangled!\n"
+
+ var/obj/item/organ/internal/eyes/eyeballs = get_organ(BP_EYES)
+ // Handle the sanity if we see the face & eyes. And if we have eyes.
+ // Sanity level of the examined mob, not the user
+ var/sanityLvl = getSanityLevel()
+ if(!skipeyes && sanityLvl && eyeballs && equipment_tint_total < TINT_MODERATE)
+ switch(sanityLvl)
+ if(SL_STRESSED)
+ msg += SPAN_WARNING("[p_they(TRUE)] seem[p_s()] to drift away, lost in thought, ever so slightly.\n")
+ if(SL_DISTRESSED)
+ msg += SPAN_WARNING("[p_their(TRUE)] eyes are darting around.\n")
+ if(SL_INSANE)
+ msg += SPAN_WARNING("[p_they(TRUE)] [p_are()] staring with bloodshot eyes.\n")
+
+ //splints
+ for(var/organ in list(BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM))
+ var/obj/item/organ/external/o = get_organ(organ)
+ if(o && o.splinted && o.splinted.loc == o)
+ msg += "[p_they()] [p_have()] \a [o.splinted] on [p_their()] [o.name]!\n"
+
+ if(mSmallsize in mutations)
+ msg += "[p_they(TRUE)] [p_are()] small halfling!\n"
+
+ if(stat || status_flags & FAKEDEATH)
+ msg += "[p_they(TRUE)] [p_are()]n't responding to anything around [p_them()] and seems to be unconscious.\n"
+ if((stat == DEAD || is_asystole() || losebreath || status_flags & FAKEDEATH) && distance <= 3)
+ msg += "[p_they(TRUE)] [p_do()] not appear to be breathing.\n"
+
+ if(fire_stacks > 0)
+ msg += "[p_they(TRUE)] looks flammable.\n"
+ else if(fire_stacks < 0)
+ msg += "[p_they(TRUE)] looks wet.\n"
+ if(on_fire)
+ msg += "[p_they()] [p_are()] on fire!.\n"
+
+ var/ssd_msg = species.get_ssd(src)
+ if(ssd_msg && (!should_have_organ(BP_BRAIN) || has_brain()) && stat != DEAD)
+ if(!key)
+ msg += SPAN_DEADSAY("[p_they(TRUE)] [p_are()] [ssd_msg]. [p_they()] won't be recovering any time soon. (Ghosted)") + "\n"
+ else if(!client)
+ msg += SPAN_DEADSAY("[p_they(TRUE)] [p_are()] [ssd_msg]. (Disconnected)") + "\n"
+
+ if(admin_paralyzed)
+ msg += SPAN_DEBUG("OOC: [p_they()] [p_have()] been paralyzed by staff. Please avoid interacting with [p_them()] unless cleared to do so by staff.") + "\n"
+
+ var/obj/item/organ/external/head/H = organs_by_name[BP_HEAD]
+ if(istype(H) && H.forehead_graffiti && H.graffiti_style)
+ msg += "[p_they()] [p_have()] \"[H.forehead_graffiti]\" written on [p_their()] [H.name] in [H.graffiti_style]!\n"
+
+ if(became_younger)
+ msg += "[p_they(TRUE)] looks a lot younger than you remember.\n"
+ if(became_older)
+ msg += "[p_they(TRUE)] looks a lot older than you remember.\n"
+
+ var/extra_species_text = species.get_additional_examine_text(src)
+ if(extra_species_text)
+ msg += "[extra_species_text]\n"
+
+ var/list/wound_flavor_text = list()
+ var/applying_pressure = ""
+ var/list/shown_objects = list()
+ var/list/hidden_bleeders = list()
+
+ for(var/organ_tag in species.has_limbs)
+
+ var/list/organ_data = species.has_limbs[organ_tag]
+ var/organ_descriptor = organ_data["descriptor"]
+ var/obj/item/organ/external/E = organs_by_name[organ_tag]
+
+ if(!E)
+ wound_flavor_text[organ_descriptor] = "[p_they(TRUE)] [p_are()] missing [p_their()] [organ_descriptor].\n"
+ continue
+
+ wound_flavor_text[E.name] = ""
+
+ if(E.applied_pressure == src)
+ applying_pressure = "[p_they(TRUE)] [p_are()] applying pressure to [p_their()] [E.name].
"
+
+ var/obj/item/clothing/hidden
+ var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
+ for(var/obj/item/clothing/C in clothing_items)
+ if(istype(C) && (C.body_parts_covered & E.body_part))
+ hidden = C
+ break
+
+ if(hidden && user != src)
+ if(E.status & ORGAN_BLEEDING && !(hidden.item_flags & ITEM_FLAG_THICKMATERIAL)) //not through a spacesuit
+ if(!hidden_bleeders[hidden])
+ hidden_bleeders[hidden] = list()
+ hidden_bleeders[hidden] += E.name
+ else
+ if(E.is_stump())
+ wound_flavor_text[E.name] += "[p_they(TRUE)] [p_have()] a stump where [p_their()] [organ_descriptor] should be.\n"
+ if(LAZYLEN(E.wounds) && E.parent)
+ wound_flavor_text[E.name] += "[p_they(TRUE)] [p_have()] [E.get_wounds_desc()] on [p_their()] [E.parent.name].
"
+ else
+ if(!is_synth && BP_IS_ROBOTIC(E) && (E.parent && !BP_IS_ROBOTIC(E.parent) && !BP_IS_ASSISTED(E.parent)))
+ wound_flavor_text[E.name] = "[p_they(TRUE)] [p_have()] a [E.name].\n"
+ var/wounddesc = E.get_wounds_desc()
+ if(wounddesc != "nothing")
+ wound_flavor_text[E.name] += "[p_they(TRUE)] [p_have()] [wounddesc] on [p_their()] [E.name].
"
+ if(!hidden || distance <=1)
+ if(E.dislocated > 0)
+ wound_flavor_text[E.name] += "[p_their(TRUE)] [E.joint] is dislocated!
"
+ if(((E.status & ORGAN_BROKEN) && E.brute_dam > E.min_broken_damage) || (E.status & ORGAN_MUTATED))
+ wound_flavor_text[E.name] += "[p_their(TRUE)] [E.name] is dented and swollen!
"
+
+ for(var/datum/wound/wound in E.wounds)
+ var/list/embedlist = wound.embedded_objects
+ if(LAZYLEN(embedlist))
+ shown_objects += embedlist
+ var/parsedembed[0]
+ for(var/obj/embedded in embedlist)
+ if(!parsedembed.len || (!list_find(parsedembed, embedded.name) && !list_find(parsedembed, "multiple [embedded.name]")))
+ parsedembed.Add(embedded.name)
+ else if(!list_find(parsedembed, "multiple [embedded.name]"))
+ parsedembed.Remove(embedded.name)
+ parsedembed.Add("multiple "+embedded.name)
+ wound_flavor_text["[E.name]"] += "The [wound.desc] on [p_their()] [E.name] has \a [english_list(parsedembed, and_text = " and \a ", comma_text = ", \a ")] sticking out of it!
"
+ for(var/hidden in hidden_bleeders)
+ wound_flavor_text[hidden] = "[p_they(TRUE)] [p_have()] blood soaking through [hidden] around [p_their()] [english_list(hidden_bleeders[hidden])]!
"
+
+ msg += ""
+ for(var/limb in wound_flavor_text)
+ msg += wound_flavor_text[limb]
+ msg += ""
+
+ for(var/obj/implant in get_visible_implants(0))
+ if(implant in shown_objects)
+ continue
+ msg += "[src] [p_have()] \a [implant.name] sticking out of [p_their()] flesh!\n"
+ if(digitalcamo)
+ msg += "[p_they(TRUE)] [p_are()] repulsively uncanny!\n"
+
+ if(hasHUD(user, HUD_SECURITY))
+ var/perpname = "wot"
+ var/criminal = "None"
+
+ var/obj/item/card/id/id = GetIdCard()
+ if(istype(id))
+ perpname = id.registered_name
+ else
+ perpname = src.name
+
+ if(perpname)
+ var/datum/computer_file/report/crew_record/R = get_crewmember_record(perpname)
+ if(R)
+ criminal = R.get_criminalStatus()
+
+ msg += "Criminal status: \[[criminal]\]\n"
+ msg += "Security records: \[View\]\n"
+
+ if(GLOB.informants.is_antagonist(mind)) // hacky, but functional
+ msg += "Special information: This D-class is listed as an INFORMANT. Protect him, but do not blow his cover."
+
+ if(hasHUD(user, HUD_MEDICAL))
+ var/perpname = "wot"
+ var/medical = "None"
+
+ var/obj/item/card/id/id = GetIdCard()
+ if(istype(id))
+ perpname = id.registered_name
+ else
+ perpname = src.name
+
+ var/datum/computer_file/report/crew_record/R = get_crewmember_record(perpname)
+ if(R)
+ medical = R.get_status()
+
+ msg += "Physical status: \[[medical]\]\n"
+ msg += "Medical records: \[View\]\n"
+
+
+ if(print_flavor_text()) msg += "[print_flavor_text()]\n"
+
+ msg += "*---------*
"
+ msg += applying_pressure
+
+ if(pose)
+ if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 )
+ pose = addtext(pose,".") //Makes sure all emotes end with a period.
+ msg += "[p_they()] [pose]\n"
+
+ var/show_descs = show_descriptors_to(user)
+ if(show_descs)
+ msg += SPAN_NOTICE("[jointext(show_descs, "
")]")
+ to_chat(user, jointext(msg, null))
+
+//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
+/proc/hasHUD(mob/M as mob, hudtype)
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ var/obj/item/clothing/glasses/G = H.glasses
+ var/obj/item/card/id/ID = M.GetIdCard()
+ var/obj/item/organ/internal/augment/active/hud/AUG
+ for (var/obj/item/organ/internal/augment/active/hud/A in H.internal_organs) // Check for installed and active HUD implants
+ if(A.hud_type & hudtype)
+ AUG = A
+ break
+
+ return ((istype(G) && ((G.hud_type & hudtype) || (G.hud && (G.hud.hud_type & hudtype)))) && G.check_access(ID)) || AUG?.active && AUG.check_access(ID)
+ else if(istype(M, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = M
+ for(var/obj/item/borg/sight/sight in list(R.module_state_1, R.module_state_2, R.module_state_3))
+ if(istype(sight) && (sight.hud_type & hudtype))
+ return TRUE
+ return FALSE
+
+/mob/living/carbon/human/verb/pose()
+ set name = "Set Pose"
+ set desc = "Sets a description which will be shown when someone examines you."
+ set category = "IC"
+
+ pose = sanitize(input(usr, "This is [src]. [get_visible_gender() == MALE ? "He" : get_visible_gender() == FEMALE ? "She" : "They"]...", "Pose", null) as text)
+
+/mob/living/carbon/human/verb/set_flavor()
+ set name = "Set Flavour Text"
+ set desc = "Sets an extended description of your character's features."
+ set category = "IC"
+
+ var/list/HTML = list()
+ HTML += ""
+ HTML += ""
+ HTML += "Update Flavour Text
"
+ HTML += "
"
+ HTML += "General: "
+ HTML += TextPreview(flavor_texts["general"])
+ HTML += "
"
+ HTML += "Head: "
+ HTML += TextPreview(flavor_texts["head"])
+ HTML += "
"
+ HTML += "Face: "
+ HTML += TextPreview(flavor_texts["face"])
+ HTML += "
"
+ HTML += "Eyes: "
+ HTML += TextPreview(flavor_texts["eyes"])
+ HTML += "
"
+ HTML += "Body: "
+ HTML += TextPreview(flavor_texts["torso"])
+ HTML += "
"
+ HTML += "Arms: "
+ HTML += TextPreview(flavor_texts["arms"])
+ HTML += "
"
+ HTML += "Hands: "
+ HTML += TextPreview(flavor_texts["hands"])
+ HTML += "
"
+ HTML += "Legs: "
+ HTML += TextPreview(flavor_texts["legs"])
+ HTML += "
"
+ HTML += "Feet: "
+ HTML += TextPreview(flavor_texts["feet"])
+ HTML += "
"
+ HTML += "
"
+ HTML +="\[Done\]"
+ HTML += ""
+ show_browser(src, jointext(HTML,null), "window=flavor_changes;size=430x300")
diff --git a/mod_celadon/mod_celadon.dme b/mod_celadon/mod_celadon.dme
index f0e28b6641..379bef37b7 100644
--- a/mod_celadon/mod_celadon.dme
+++ b/mod_celadon/mod_celadon.dme
@@ -7,6 +7,7 @@
// --- MAINTENANCE --- //
#include "_components/__components.dme"
#include "outfits/_outfits.dme"
+#include "human_examine/_human_examine.dme"
// --- ICONS --- //