Forensics Datum (#17796)

* forensics datum initial work

* typo fix

* glove recursion fix

* missing bloodtype on organ data

* removed frustrating and unneeded b_type var from humans

* no leaky

* listcheck

* documenting

* documentation
This commit is contained in:
Will
2025-06-06 02:30:11 -04:00
committed by GitHub
parent be6680da62
commit ae718f07e3
62 changed files with 603 additions and 400 deletions
@@ -140,7 +140,7 @@
clothing_slots += list(H.l_store, H.r_store)
for(var/obj/item/clothing/C in clothing_slots)
if(C.blood_DNA && C.blood_color && C.blood_color != SYNTH_BLOOD_COLOUR)
if(C.forensic_data?.has_blooddna() && C.blood_color && C.blood_color != SYNTH_BLOOD_COLOUR)
human_blood_fear_amount += 1
// This is divided, since humans can wear so many items at once.
@@ -150,7 +150,7 @@
// Bloody objects are also bad.
if(istype(thing, /obj))
var/obj/O = thing
if(O.blood_DNA && O.blood_color && O.blood_color != SYNTH_BLOOD_COLOUR)
if(O.forensic_data?.has_blooddna() && O.blood_color && O.blood_color != SYNTH_BLOOD_COLOUR)
fear_amount++
return fear_amount
+13 -13
View File
@@ -123,14 +123,14 @@
accessory_descs += "<a href='byond://?src=\ref[src];lookitem_desc_only=\ref[A]'>\a [A]</a>"
tie_msg += " [lowertext(english_list(accessory_descs))]."
if(w_uniform.blood_DNA)
if(w_uniform.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.is] wearing [icon2html(w_uniform,user.client)] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[w_uniform]'>[w_uniform.name]</a>![tie_msg]")
else
msg += "[T.He] [T.is] wearing [icon2html(w_uniform,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[w_uniform]'>\a [w_uniform]</a>.[tie_msg]"
//head
if(head && !(skip_gear & EXAMINE_SKIPHELMET) && head.show_examine)
if(head.blood_DNA)
if(head.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.is] wearing [icon2html(head,user.client)] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[head]'>[head.name]</a> on [T.his] head!")
else
msg += "[T.He] [T.is] wearing [icon2html(head,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[head]'>\a [head]</a> on [T.his] head."
@@ -147,35 +147,35 @@
accessory_descs += "<a href='byond://?src=\ref[src];lookitem_desc_only=\ref[accessory]'>\a [accessory]</a>"
tie_msg += " [lowertext(english_list(accessory_descs))]."
if(wear_suit.blood_DNA)
if(wear_suit.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.is] wearing [icon2html(wear_suit,user.client)] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[wear_suit]'>[wear_suit.name]</a>![tie_msg]")
else
msg += "[T.He] [T.is] wearing [icon2html(wear_suit,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[wear_suit]'>\a [wear_suit]</a>.[tie_msg]"
//suit/armour storage
if(s_store && !(skip_gear & EXAMINE_SKIPSUITSTORAGE) && s_store.show_examine)
if(s_store.blood_DNA)
if(s_store.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.is] carrying [icon2html(s_store,user.client)] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[s_store]'>[s_store.name]</a> on [T.his] [wear_suit.name]!")
else
msg += "[T.He] [T.is] carrying [icon2html(s_store,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[s_store]'>\a [s_store]</a> on [T.his] [wear_suit.name]."
//back
if(back && !(skip_gear & EXAMINE_SKIPBACKPACK) && back.show_examine)
if(back.blood_DNA)
if(back.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.has] [icon2html(back,user.client)] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[back]'>[back]</a> on [T.his] back.")
else
msg += "[T.He] [T.has] [icon2html(back,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[back]'>\a [back]</a> on [T.his] back."
//left hand
if(l_hand && l_hand.show_examine)
if(l_hand.blood_DNA)
if(l_hand.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.is] holding [icon2html(l_hand,user.client)] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[l_hand]'>[l_hand.name]</a> in [T.his] left hand!")
else
msg += "[T.He] [T.is] holding [icon2html(l_hand,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[l_hand]'>\a [l_hand]</a> in [T.his] left hand."
//right hand
if(r_hand && r_hand.show_examine)
if(r_hand.blood_DNA)
if(r_hand.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.is] holding [icon2html(r_hand,user.client)] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[r_hand]'>[r_hand.name]</a> in [T.his] right hand!")
else
msg += "[T.He] [T.is] holding [icon2html(r_hand,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[r_hand]'>\a [r_hand]</a> in [T.his] right hand."
@@ -192,12 +192,12 @@
accessory_descs += "<a href='byond://?src=\ref[src];lookitem_desc_only=\ref[A]'>\a [A]</a>"
gloves_acc_msg += " [lowertext(english_list(accessory_descs))]."
if(gloves.blood_DNA)
if(gloves.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.has] [icon2html(gloves,user.client)] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[gloves]'>[gloves.name]</a> on [T.his] hands![gloves_acc_msg]")
else
msg += "[T.He] [T.has] [icon2html(gloves,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[gloves]'>\a [gloves]</a> on [T.his] hands.[gloves_acc_msg]"
else if(blood_DNA && !(skip_body & EXAMINE_SKIPHANDS))
else if(forensic_data?.has_blooddna() && !(skip_body & EXAMINE_SKIPHANDS))
msg += span_warning("[T.He] [T.has] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!")
//handcuffed?
@@ -213,14 +213,14 @@
//belt
if(belt && !(skip_gear & EXAMINE_SKIPBELT) && belt.show_examine)
if(belt.blood_DNA)
if(belt.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.has] [icon2html(belt,user.client)] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[belt]'>[belt.name]</a> about [T.his] waist!")
else
msg += "[T.He] [T.has] [icon2html(belt,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[belt]'>\a [belt]</a> about [T.his] waist."
//shoes
if(shoes && !(skip_gear & EXAMINE_SKIPSHOES) && shoes.show_examine)
if(shoes.blood_DNA)
if(shoes.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.is] wearing [icon2html(shoes,user.client)] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[shoes]'>[shoes.name]</a> on [T.his] feet!")
else
msg += "[T.He] [T.is] wearing [icon2html(shoes,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[shoes]'>\a [shoes]</a> on [T.his] feet."
@@ -233,14 +233,14 @@
if(istype(wear_mask, /obj/item/grenade) && check_has_mouth())
descriptor = "in [T.his] mouth"
if(wear_mask.blood_DNA)
if(wear_mask.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.has] [icon2html(wear_mask,user.client)] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[wear_mask]'>[wear_mask.name]</a> [descriptor]!")
else
msg += "[T.He] [T.has] [icon2html(wear_mask,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[wear_mask]'>\a [wear_mask]</a> [descriptor]."
//eyes
if(glasses && !(skip_gear & EXAMINE_SKIPEYEWEAR) && glasses.show_examine)
if(glasses.blood_DNA)
if(glasses.forensic_data?.has_blooddna())
msg += span_warning("[T.He] [T.has] [icon2html(glasses,user.client)] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[glasses]'>[glasses]</a> covering [T.his] eyes!")
else
msg += "[T.He] [T.has] [icon2html(glasses,user.client)] <a href='byond://?src=\ref[src];lookitem_desc_only=\ref[glasses]'>\a [glasses]</a> covering [T.his] eyes."
@@ -1137,8 +1137,7 @@
return 0
//if this blood isn't already in the list, add it
if(istype(M))
if(!blood_DNA[M.dna.unique_enzymes])
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
add_blooddna(M.dna,M)
hand_blood_color = blood_color
update_bloodied()
add_verb(src, /mob/living/carbon/human/proc/bloody_doodle)
@@ -1152,8 +1151,6 @@
/mob/living/carbon/human/wash(clean_types)
. = ..()
gunshot_residue = null
//Always do hands (or whatever's on our hands)
if(gloves)
gloves.wash(clean_types)
@@ -577,11 +577,9 @@ emp_act
var/obj/item/clothing/gloves/gl = gloves
gl.add_blood(source)
gl.transfer_blood = amount
gl.bloody_hands_mob = source
else
add_blood(source)
bloody_hands = amount
bloody_hands_mob = source
update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
/mob/living/carbon/human/proc/bloody_body(var/mob/living/source)
@@ -46,7 +46,6 @@
var/age = 30 //Player's age (pure fluff)
var/b_type = "A+" //Player's bloodtype
var/datum/robolimb/synthetic //If they are a synthetic (aka synthetic torso). Also holds the datum for the type of robolimb.
var/list/all_underwear = list()
@@ -92,7 +91,6 @@
var/hand_blood_color
var/list/flavor_texts = list()
var/gunshot_residue
var/pulling_punches // Are you trying not to hurt your opponent?
var/robolimb_count = 0 // Total number of external robot parts.
var/robobody_count = 0 // Counts torso, groin, and head, if they're robotic
@@ -161,7 +161,7 @@ var/static/icon/ingame_hud_med_vr = icon('icons/mob/hud_med_vr.dmi')
grad_style = character.grad_style
f_style = character.f_style
grad_style = character.grad_style
b_type = character.b_type
dna?.b_type = character.dna ? character.dna.b_type : DEFAULT_BLOOD_TYPE
synth_color = character.synth_color
r_synth = character.r_synth
g_synth = character.g_synth
@@ -362,8 +362,8 @@
return FALSE
log_admin("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast].")
message_admins("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast]. (<A href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)", 1)
log_admin("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.forensic_data?.get_lastprint()].")
message_admins("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.forensic_data?.get_lastprint()]. (<A href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)", 1)
// start the dephase
phase_in(T)
shadekin_adjust_energy(-20) // loss of energy for the interception
@@ -239,8 +239,7 @@ var/datum/species/shapeshifter/promethean/prometheans
H.feet_blood_color = null
H.adjust_nutrition(rand(3, 10))
if(H.bloody_hands)
LAZYCLEARLIST(H.blood_DNA)
H.blood_DNA = null
H.forensic_data?.clear_blooddna()
H.hand_blood_color = null
H.bloody_hands = 0
H.adjust_nutrition(rand(3, 10))
@@ -388,13 +388,14 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //see UpdateDamageIcon()
return
remove_layer(BLOOD_LAYER)
if(!blood_DNA && !feet_blood_DNA)
var/bloody_mess = forensic_data?.get_blooddna()
if(!bloody_mess && !feet_blood_DNA)
return
var/image/both = image(icon = 'icons/effects/effects.dmi', icon_state = "nothing", layer = BODY_LAYER+BLOOD_LAYER)
//Bloody hands
if(blood_DNA)
if(bloody_mess)
var/image/bloodsies = image(icon = species.get_blood_mask(src), icon_state = "bloodyhands", layer = BODY_LAYER+BLOOD_LAYER)
bloodsies.color = hand_blood_color
both.add_overlay(bloodsies)