diff --git a/code/__DEFINES/forensics.dm b/code/__DEFINES/forensics.dm
deleted file mode 100644
index 0cda5d997a..0000000000
--- a/code/__DEFINES/forensics.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-#define IF_HAS_BLOOD_DNA(__thing) GET_COMPONENT_FROM(__FR##__thing, /datum/component/forensics, __thing); if(__FR##__thing && length(__FR##__thing.blood_DNA))
-#define IF_HAS_BLOOD_DNA_AND(__thing, __conditions...) GET_COMPONENT_FROM(__FR##__thing, /datum/component/forensics, __thing); if(__FR##__thing && length(__FR##__thing.blood_DNA) && (##__conditions))
\ No newline at end of file
diff --git a/code/datums/components/decals/blood.dm b/code/datums/components/decals/blood.dm
index d3bdf94915..18e362db5d 100644
--- a/code/datums/components/decals/blood.dm
+++ b/code/datums/components/decals/blood.dm
@@ -7,32 +7,6 @@
. = ..()
RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
-/datum/component/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
- var/obj/item/I = parent
- I.cut_overlays()
- if(!_icon)
- _icon = 'icons/effects/blood.dmi'
- if(!_icon_state)
- _icon_state = "itemblood"
- var/icon = initial(I.icon)
- var/icon_state = initial(I.icon_state)
- if(!icon || !icon_state)
- // It's something which takes on the look of other items, probably
- icon = I.icon
- icon_state = I.icon_state
- var/icon/blood_splatter_icon = icon(initial(I.icon), initial(I.icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
- blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
- blood_splatter_icon.Blend(icon(_icon, _icon_state), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
-// pic = mutable_appearance(blood_splatter_icon, initial(I.icon_state))
-
- I.blood_splatter_icon = blood_splatter_icon
- I.blood_overlay = image(I.blood_splatter_icon)
- I.blood_overlay.color = I.blood_DNA_to_color()
- I.update_icon()
- I.add_overlay(I.blood_overlay)
-
- return TRUE
-
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
var/atom/A = parent
override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm
deleted file mode 100644
index cd3cbbd8c1..0000000000
--- a/code/datums/components/forensics.dm
+++ /dev/null
@@ -1,184 +0,0 @@
-/datum/component/forensics
- dupe_mode = COMPONENT_DUPE_UNIQUE
- can_transfer = TRUE
- var/list/fingerprints //assoc print = print
- var/list/hiddenprints //assoc ckey = realname/gloves/ckey
- var/list/blood_DNA //assoc dna = bloodtype
- var/list/fibers //assoc print = print
-
-/datum/component/forensics/InheritComponent(datum/component/forensics/F, original) //Use of | and |= being different here is INTENTIONAL.
- fingerprints = fingerprints | F.fingerprints
- hiddenprints = hiddenprints | F.hiddenprints
- blood_DNA = blood_DNA | F.blood_DNA
- fibers = fibers | F.fibers
- check_blood()
- return ..()
-
-/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- fingerprints = new_fingerprints
- hiddenprints = new_hiddenprints
- blood_DNA = new_blood_DNA
- fibers = new_fibers
- check_blood()
-
-/datum/component/forensics/RegisterWithParent()
- check_blood()
- RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act)
-
-/datum/component/forensics/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_COMPONENT_CLEAN_ACT))
-
-/datum/component/forensics/PostTransfer()
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
-
-/datum/component/forensics/proc/wipe_fingerprints()
- fingerprints = null
- return TRUE
-
-/datum/component/forensics/proc/wipe_hiddenprints()
- return //no.
-
-/datum/component/forensics/proc/wipe_blood_DNA()
- blood_DNA = null
- if(isitem(parent))
- qdel(parent.GetComponent(/datum/component/decal/blood))
- return TRUE
-
-/datum/component/forensics/proc/wipe_fibers()
- fibers = null
- return TRUE
-
-/datum/component/forensics/proc/clean_act(datum/source, strength)
- if(strength >= CLEAN_STRENGTH_FINGERPRINTS)
- wipe_fingerprints()
- if(strength >= CLEAN_STRENGTH_BLOOD)
- wipe_blood_DNA()
- if(strength >= CLEAN_STRENGTH_FIBERS)
- wipe_fibers()
-
-/datum/component/forensics/proc/add_fingerprint_list(list/_fingerprints) //list(text)
- if(!length(_fingerprints))
- return
- LAZYINITLIST(fingerprints)
- for(var/i in _fingerprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
- fingerprints[i] = i
- return TRUE
-
-/datum/component/forensics/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
- if(!isliving(M))
- if(!iscameramob(M))
- return
- if(isaicamera(M))
- var/mob/camera/aiEye/ai_camera = M
- if(!ai_camera.ai)
- return
- M = ai_camera.ai
- add_hiddenprint(M)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- add_fibers(H)
- if(H.gloves) //Check if the gloves (if any) hide fingerprints
- var/obj/item/clothing/gloves/G = H.gloves
- if(G.transfer_prints)
- ignoregloves = TRUE
- if(!ignoregloves)
- H.gloves.add_fingerprint(H, TRUE) //ignoregloves = 1 to avoid infinite loop.
- return
- var/full_print = md5(H.dna.uni_identity)
- LAZYSET(fingerprints, full_print, full_print)
- return TRUE
-
-/datum/component/forensics/proc/add_fiber_list(list/_fibertext) //list(text)
- if(!length(_fibertext))
- return
- LAZYINITLIST(fibers)
- for(var/i in _fibertext) //We use an associative list, make sure we don't just merge a non-associative list into ours.
- fibers[i] = i
- return TRUE
-
-/datum/component/forensics/proc/add_fibers(mob/living/carbon/human/M)
- var/fibertext
- var/item_multiplier = isitem(src)?1.2:1
- if(M.wear_suit)
- fibertext = "Material from \a [M.wear_suit]."
- if(prob(10*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- if(!(M.wear_suit.body_parts_covered & CHEST))
- if(M.w_uniform)
- fibertext = "Fibers from \a [M.w_uniform]."
- if(prob(12*item_multiplier) && !LAZYACCESS(fibers, fibertext)) //Wearing a suit means less of the uniform exposed.
- LAZYSET(fibers, fibertext, fibertext)
- if(!(M.wear_suit.body_parts_covered & HANDS))
- if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- else if(M.w_uniform)
- fibertext = "Fibers from \a [M.w_uniform]."
- if(prob(15*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- // "Added fibertext: [fibertext]"
- LAZYSET(fibers, fibertext, fibertext)
- if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- else if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- return TRUE
-
-/datum/component/forensics/proc/add_hiddenprint_list(list/_hiddenprints) //list(ckey = text)
- if(!length(_hiddenprints))
- return
- LAZYINITLIST(hiddenprints)
- for(var/i in _hiddenprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
- hiddenprints[i] = _hiddenprints[i]
- return TRUE
-
-/datum/component/forensics/proc/add_hiddenprint(mob/M)
- if(!isliving(M))
- if(!iscameramob(M))
- return
- if(isaicamera(M))
- var/mob/camera/aiEye/ai_camera = M
- if(!ai_camera.ai)
- return
- M = ai_camera.ai
- if(!M.key)
- return
- var/hasgloves = ""
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.gloves)
- hasgloves = "(gloves)"
- var/current_time = TIME_STAMP("hh:mm:ss", FALSE)
- if(!LAZYACCESS(hiddenprints, M.key))
- LAZYSET(hiddenprints, M.key, "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]")
- else
- var/laststamppos = findtext(LAZYACCESS(hiddenprints, M.key), " Last: ")
- if(laststamppos)
- LAZYSET(hiddenprints, M.key, copytext(hiddenprints[M.key], 1, laststamppos))
- hiddenprints[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]" //made sure to be existing by if(!LAZYACCESS);else
- var/atom/A = parent
- A.fingerprintslast = M.ckey
- return TRUE
-
-/datum/component/forensics/proc/add_blood_DNA(list/dna) //list(dna_enzymes = type)
- if(!length(dna))
- return
- LAZYINITLIST(blood_DNA)
- for(var/i in dna)
- blood_DNA[i] = dna[i]
- check_blood()
- return TRUE
-
-/datum/component/forensics/proc/check_blood()
- if(!isitem(parent))
- return
- if(!length(blood_DNA))
- return
- parent.LoadComponent(/datum/component/decal/blood)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index a708418258..6c068e7d5e 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -37,6 +37,10 @@
var/rad_insulation = RAD_NO_INSULATION
var/icon/blood_splatter_icon
+ var/list/fingerprints
+ var/list/fingerprintshidden
+ var/list/blood_DNA
+ var/list/suit_fibers
/atom/New(loc, ...)
//atom creation method that preloads variables at creation
@@ -350,12 +354,23 @@
var/new_blood_dna = L.get_blood_dna_list()
if(!new_blood_dna)
return FALSE
- var/old_length = blood_DNA_length()
+ LAZYINITLIST(blood_DNA) //if our list of DNA doesn't exist yet, initialise it.
+ var/old_length = length(blood_DNA)
add_blood_DNA(new_blood_dna)
- if(blood_DNA_length() == old_length)
+ if(length(blood_DNA) == old_length)
return FALSE
return TRUE
+//to add blood dna info to the object's blood_DNA list
+/atom/proc/transfer_blood_dna(list/blood_dna, list/datum/disease/diseases)
+ LAZYINITLIST(blood_DNA)
+ var/old_length = length(blood_DNA)
+ blood_DNA |= blood_dna
+ if(length(blood_DNA) == old_length)
+ return FALSE
+ return TRUE
+
+
//to add blood from a mob onto something, and transfer their dna info
/atom/proc/add_mob_blood(mob/living/M)
var/list/blood_dna = M.get_blood_dna_list()
@@ -363,6 +378,111 @@
return FALSE
return add_blood_DNA(blood_dna)
+//to add blood onto something, with blood dna info to include.
+/atom/proc/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ return FALSE
+
+/obj/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ return transfer_blood_dna(blood_dna)
+
+/obj/item/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ . = ..()
+ if(!.)
+ return
+ add_blood_overlay()
+
+/obj/item/proc/add_blood_overlay()
+ if(!length(blood_DNA))
+ return
+ if(initial(icon) && initial(icon_state))
+ blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
+ blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
+ blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
+
+ blood_overlay = image(blood_splatter_icon)
+ blood_overlay.color = blood_DNA_to_color()
+ add_overlay(blood_overlay)
+
+/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ . = ..()
+ transfer_blood = rand(2, 4)
+
+/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
+ if(!B)
+ B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
+ B.transfer_blood_dna(blood_dna) //give blood info to the blood decal.
+ return TRUE //we bloodied the floor
+
+/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ if(wear_suit)
+ wear_suit.add_blood_DNA(blood_dna)
+ update_inv_wear_suit()
+ else if(w_uniform)
+ w_uniform.add_blood_DNA(blood_dna)
+ update_inv_w_uniform()
+ if(gloves)
+ var/obj/item/clothing/gloves/G = gloves
+ G.add_blood_DNA(blood_dna)
+ else if(length(blood_dna))
+ transfer_blood_dna(blood_dna)
+ bloody_hands = rand(2, 4)
+ if(head)
+ head.add_blood_DNA(blood_dna)
+ update_inv_head()
+ else if(wear_mask)
+ wear_mask.add_blood_DNA(blood_dna)
+ update_inv_wear_mask()
+ if(wear_neck)
+ wear_neck.add_blood_DNA(blood_dna)
+ update_inv_neck()
+ update_inv_gloves() //handles bloody hands overlays and updating
+ return TRUE
+
+/atom/proc/blood_DNA_to_color()
+ var/list/colors = list()//first we make a list of all bloodtypes present
+ for(var/bloop in blood_DNA)
+ if(colors[blood_DNA[bloop]])
+ colors[blood_DNA[bloop]]++
+ else
+ colors[blood_DNA[bloop]] = 1
+
+ var/final_rgb = BLOOD_COLOR_HUMAN //a default so we don't have white blood graphics if something messed up
+
+ if(colors.len)
+ var/sum = 0 //this is all shitcode, but it works; trust me
+ final_rgb = bloodtype_to_color(colors[1])
+ sum = colors[colors[1]]
+ if(colors.len > 1)
+ var/i = 2
+ while(i <= colors.len)
+ var/tmp = colors[colors[i]]
+ final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum))
+ sum += tmp
+ i++
+
+ return final_rgb
+
+/atom/proc/clean_blood(datum/source, strength)
+ if(strength < CLEAN_STRENGTH_BLOOD)
+ return
+ if(strength >= CLEAN_STRENGTH_FINGERPRINTS)
+ if(islist(fingerprints))
+ fingerprints = null
+ if(strength >= CLEAN_STRENGTH_BLOOD)
+ if(islist(blood_DNA))
+ blood_DNA = null
+ if(strength >= CLEAN_STRENGTH_FIBERS)
+ if(islist(suit_fibers))
+ suit_fibers = null
+ return TRUE
+
+/obj/item/clean_blood(datum/source, strength)
+ . = ..()
+ if(.)
+ if(blood_splatter_icon)
+ cut_overlay(blood_splatter_icon)
+
/atom/proc/wash_cream()
return TRUE
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 5e8515d3d5..3eda412a84 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -13,7 +13,7 @@
/obj/machinery/washing_machine/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /obj/machinery/washing_machine/clean_blood)))
/obj/machinery/washing_machine/examine(mob/user)
..()
@@ -59,7 +59,8 @@
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
-/obj/machinery/washing_machine/proc/clean_blood()
+/obj/machinery/washing_machine/clean_blood()
+ . = ..()
if(!busy)
bloody_mess = FALSE
update_icon()
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index d35e353170..c03e8a2473 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -81,7 +81,8 @@
add_blood = bloodiness
bloodiness -= add_blood
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
- S.add_blood_DNA(return_blood_DNA())
+ if(blood_DNA && blood_DNA.len)
+ S.add_blood_DNA(blood_DNA)
S.blood_state = blood_state
update_icon()
H.update_inv_shoes()
diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm
index e1c92a83c1..45d3757921 100644
--- a/code/game/objects/effects/decals/cleanable/aliens.dm
+++ b/code/game/objects/effects/decals/cleanable/aliens.dm
@@ -35,7 +35,7 @@
if(infective)
diseases = infective.diseases
var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
- splat.add_blood_DNA(return_blood_DNA())
+ splat.transfer_blood_dna(blood_DNA)
if(!step_to(src, get_step(src, direction), 0))
break
diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm
index 85edcfbea8..627723b110 100644
--- a/code/game/objects/effects/decals/cleanable/gibs.dm
+++ b/code/game/objects/effects/decals/cleanable/gibs.dm
@@ -21,9 +21,6 @@
/obj/effect/decal/cleanable/blood/gibs/update_icon()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- Blood_DNA = D.blood_DNA
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]_guts")
@@ -60,7 +57,7 @@
if(infective)
diseases = infective.diseases
var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
- splat.add_blood_DNA(return_blood_DNA())
+ splat.transfer_blood_dna(blood_DNA)
if(!step_to(src, get_step(src, direction), 0))
break
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 16efe12bf0..c0ae223751 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -7,12 +7,10 @@
blood_state = BLOOD_STATE_BLOOD
bloodiness = MAX_SHOE_BLOODINESS
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
- var/list/Blood_DNA = list()
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
- C.add_blood_DNA(return_blood_DNA())
- if(C.Blood_DNA.len)
- Blood_DNA |= C.Blood_DNA.Copy()
+ if (C.blood_DNA)
+ blood_DNA |= C.blood_DNA.Copy()
if (bloodiness)
if (C.bloodiness < MAX_SHOE_BLOODINESS)
C.bloodiness += bloodiness
@@ -28,9 +26,6 @@
update_icon()
/obj/effect/decal/cleanable/blood/update_icon()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- Blood_DNA = D.blood_DNA
color = blood_DNA_to_color()
/obj/effect/decal/cleanable/blood/old
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 23580bf37a..72a01d6a09 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -389,9 +389,9 @@
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
- add_blood_DNA(from.return_blood_DNA())
- add_fingerprint_list(from.return_fingerprints())
- add_hiddenprint_list(from.return_hiddenprints())
+ blood_DNA = from.blood_DNA
+ fingerprints = from.fingerprints
+ fingerprintshidden = from.fingerprintshidden
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 08e00ea0f4..90581e9911 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -324,14 +324,11 @@
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
- possible = list()
+ LAZYINITLIST(possible)
if(!voodoo_link)
return
- var/list/prints = voodoo_link.return_fingerprints()
- if(!length(prints))
- return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(prints[md5(H.dna.uni_identity)])
+ if(md5(H.dna.uni_identity) in voodoo_link.fingerprints)
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index d7586fb6a0..9cdbdcf03f 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -344,12 +344,7 @@ BLIND // can't see anything
else
..()
-/obj/item/clothing/transfer_blood_dna(list/blood_dna)
- ..()
- var/list/blood_list
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- blood_list = D.blood_DNA
- if(blood_list.len)
- last_bloodtype = blood_list[blood_list[blood_list.len]]//trust me this works
- last_blood_DNA = blood_list[blood_list.len]
+/obj/item/clothing/transfer_blood_dna(list/blood_dna, list/datum/disease/diseases)
+ if(length(blood_DNA))
+ last_bloodtype = blood_DNA[blood_DNA[blood_DNA.len]]//trust me this works
+ last_blood_DNA = blood_DNA[blood_DNA.len]
diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm
index 0ae04c1f7a..9d75fc6ce4 100644
--- a/code/modules/clothing/gloves/_gloves.dm
+++ b/code/modules/clothing/gloves/_gloves.dm
@@ -14,11 +14,10 @@
/obj/item/clothing/gloves/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /obj/item/clothing/gloves/clean_blood)))
-/obj/item/clothing/gloves/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
- return
+/obj/item/clothing/gloves/clean_blood(datum/source, strength)
+ . = ..()
transfer_blood = 0
/obj/item/clothing/gloves/suicide_act(mob/living/carbon/user)
@@ -30,7 +29,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color())
/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE)
@@ -41,4 +40,4 @@
// Called just before an attack_hand(), in mob/UnarmedAttack()
/obj/item/clothing/gloves/proc/Touch(atom/A, proximity)
- return 0 // return 1 to cancel attack_hand()
\ No newline at end of file
+ return FALSE // return TRUE to cancel attack_hand()
\ No newline at end of file
diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm
index 98bb3aec13..ccc167dcbc 100644
--- a/code/modules/clothing/head/_head.dm
+++ b/code/modules/clothing/head/_head.dm
@@ -46,7 +46,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color())
/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE)
diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm
index 362ab9b3bd..c00e6f72e0 100644
--- a/code/modules/clothing/masks/_masks.dm
+++ b/code/modules/clothing/masks/_masks.dm
@@ -59,7 +59,7 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE)
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index 0bb7c8ebfd..2356bb16eb 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -12,7 +12,7 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
/obj/item/clothing/neck/tie
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index bb68f69ea0..df7415eace 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -21,7 +21,7 @@
/obj/item/clothing/shoes/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /obj/item/clothing/shoes/clean_blood)))
/obj/item/clothing/shoes/suicide_act(mob/living/carbon/user)
if(rand(2)>1)
@@ -46,7 +46,7 @@
. = list()
if(!isinhands)
var/bloody = FALSE
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
bloody = TRUE
else
bloody = bloody_shoes[BLOOD_STATE_BLOOD]
@@ -93,9 +93,9 @@
var/mob/M = loc
M.update_inv_shoes()
-/obj/item/clothing/shoes/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
- return
+/obj/item/clothing/shoes/clean_blood(datum/source, strength)
+ . = ..()
+
bloody_shoes = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
blood_state = BLOOD_STATE_NOT_BLOODY
if(ismob(loc))
diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm
index c3ddf99365..2ad1bba042 100644
--- a/code/modules/clothing/suits/_suits.dm
+++ b/code/modules/clothing/suits/_suits.dm
@@ -53,7 +53,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
if(taurmode >= SNEK_TAURIC)
. += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
else
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index 5f123cd745..eda0e31e93 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -22,7 +22,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
if(accessory_overlay)
. += accessory_overlay
diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm
index e219ffc570..2b916ffc27 100644
--- a/code/modules/detectivework/detective_work.dm
+++ b/code/modules/detectivework/detective_work.dm
@@ -1,158 +1,107 @@
//CONTAINS: Suit fibers and Detective's Scanning Computer
-/atom/proc/return_fingerprints()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.fingerprints
+/atom/proc/add_fibers(mob/living/carbon/human/M)
+ if(M.gloves && istype(M.gloves, /obj/item/clothing/))
+ var/obj/item/clothing/gloves/G = M.gloves
+ if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
+ if(add_blood_DNA(G.blood_DNA)) //only reduces the bloodiness of our gloves if the item wasn't already bloody
+ G.transfer_blood--
+ else if(M.bloody_hands > 1)
+ if(add_blood_DNA(M.blood_DNA))
+ M.bloody_hands--
+ if(!suit_fibers)
+ suit_fibers = list()
+ var/fibertext
+ var/item_multiplier = isitem(src)?1.2:1
+ if(M.wear_suit)
+ fibertext = "Material from \a [M.wear_suit]."
+ if(prob(10*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += fibertext
+ if(!(M.wear_suit.body_parts_covered & CHEST))
+ if(M.w_uniform)
+ fibertext = "Fibers from \a [M.w_uniform]."
+ if(prob(12*item_multiplier) && !(fibertext in suit_fibers)) //Wearing a suit means less of the uniform exposed.
+ suit_fibers += fibertext
+ if(!(M.wear_suit.body_parts_covered & HANDS))
+ if(M.gloves)
+ fibertext = "Material from a pair of [M.gloves.name]."
+ if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += fibertext
+ else if(M.w_uniform)
+ fibertext = "Fibers from \a [M.w_uniform]."
+ if(prob(15*item_multiplier) && !(fibertext in suit_fibers))
+ // "Added fibertext: [fibertext]"
+ suit_fibers += fibertext
+ if(M.gloves)
+ fibertext = "Material from a pair of [M.gloves.name]."
+ if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += "Material from a pair of [M.gloves.name]."
+ else if(M.gloves)
+ fibertext = "Material from a pair of [M.gloves.name]."
+ if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += "Material from a pair of [M.gloves.name]."
-/atom/proc/return_hiddenprints()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.hiddenprints
-/atom/proc/return_blood_DNA()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.blood_DNA
+/atom/proc/add_hiddenprint(mob/living/M)
+ if(!M || !M.key)
+ return
-/atom/proc/blood_DNA_length()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = length(D.blood_DNA)
+ if(!fingerprintshidden) //Add the list if it does not exist
+ fingerprintshidden = list()
-/atom/proc/return_fibers()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.fibers
+ var/hasgloves = ""
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H.gloves)
+ hasgloves = "(gloves)"
+
+ var/current_time = TIME_STAMP("hh:mm:ss", FALSE)
+ if(!fingerprintshidden[M.key])
+ fingerprintshidden[M.key] = "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
+ else
+ var/laststamppos = findtext(fingerprintshidden[M.key], " Last: ")
+ if(laststamppos)
+ fingerprintshidden[M.key] = copytext(fingerprintshidden[M.key], 1, laststamppos)
+ fingerprintshidden[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
+
+ fingerprintslast = M.ckey
-/atom/proc/add_fingerprint_list(list/fingerprints) //ASSOC LIST FINGERPRINT = FINGERPRINT
- if(length(fingerprints))
- . = AddComponent(/datum/component/forensics, fingerprints)
//Set ignoregloves to add prints irrespective of the mob having gloves on.
/atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
- var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
- . = D.add_fingerprint(M, ignoregloves)
+ if(!M || !M.key)
+ return
-/atom/proc/add_fiber_list(list/fibertext) //ASSOC LIST FIBERTEXT = FIBERTEXT
- if(length(fibertext))
- . = AddComponent(/datum/component/forensics, null, null, null, fibertext)
+ add_hiddenprint(M)
-/atom/proc/add_fibers(mob/living/carbon/human/M)
- var/old = 0
- if(M.gloves && istype(M.gloves, /obj/item/clothing))
- var/obj/item/clothing/gloves/G = M.gloves
- old = length(G.return_blood_DNA())
- if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
- if(add_blood_DNA(G.return_blood_DNA()) && length(G.return_blood_DNA()) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
- G.transfer_blood--
- else if(M.bloody_hands > 1)
- old = length(M.return_blood_DNA())
- if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
- M.bloody_hands--
- var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
- . = D.add_fibers(M)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
-/atom/proc/add_hiddenprint_list(list/hiddenprints) //NOTE: THIS IS FOR ADMINISTRATION FINGERPRINTS, YOU MUST CUSTOM SET THIS TO INCLUDE CKEY/REAL NAMES! CHECK FORENSICS.DM
- if(length(hiddenprints))
- . = AddComponent(/datum/component/forensics, null, hiddenprints)
+ add_fibers(H)
-/atom/proc/add_hiddenprint(mob/living/M)
- var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
- . = D.add_hiddenprint(M)
+ if(H.gloves) //Check if the gloves (if any) hide fingerprints
+ var/obj/item/clothing/gloves/G = H.gloves
+ if(G.transfer_prints)
+ ignoregloves = TRUE
-/atom/proc/add_blood_DNA(list/dna) //ASSOC LIST DNA = BLOODTYPE
- return FALSE
+ if(!ignoregloves)
+ H.gloves.add_fingerprint(H, TRUE) //ignoregloves = TRUE to avoid infinite loop.
+ return
-/obj/add_blood_DNA(list/dna)
- . = ..()
- if(length(dna))
- . = AddComponent(/datum/component/forensics, null, null, dna)
-
-/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
- . = ..()
- transfer_blood = rand(2, 4)
-
-/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
- var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
- if(!B)
- B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
- B.add_blood_DNA(blood_dna) //give blood info to the blood decal.
- B.update_icon()
- return TRUE //we bloodied the floor
-
-/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
- if(wear_suit)
- wear_suit.add_blood_DNA(blood_dna)
- update_inv_wear_suit()
- else if(w_uniform)
- w_uniform.add_blood_DNA(blood_dna)
- update_inv_w_uniform()
- if(gloves)
- var/obj/item/clothing/gloves/G = gloves
- G.add_blood_DNA(blood_dna)
- else if(length(blood_dna))
- AddComponent(/datum/component/forensics, null, null, blood_dna)
- bloody_hands = rand(2, 4)
- if(head)
- head.add_blood_DNA(blood_dna)
- update_inv_head()
- else if(wear_mask)
- wear_mask.add_blood_DNA(blood_dna)
- update_inv_wear_mask()
- if(wear_neck)
- wear_neck.add_blood_DNA(blood_dna)
- update_inv_neck()
- update_inv_gloves() //handles bloody hands overlays and updating
- return TRUE
+ LAZYINITLIST(fingerprints) //Add the list if it does not exist
+ var/full_print = md5(H.dna.uni_identity)
+ fingerprints[full_print] = full_print
/atom/proc/transfer_fingerprints_to(atom/A)
- A.add_fingerprint_list(return_fingerprints())
- A.add_hiddenprint_list(return_hiddenprints())
- A.fingerprintslast = fingerprintslast
+ // Make sure everything are lists.
+ LAZYINITLIST(A.fingerprints)
+ LAZYINITLIST(A.fingerprintshidden)
+ LAZYINITLIST(fingerprints)
+ LAZYINITLIST(fingerprintshidden)
-//to add blood dna info to the object's blood_DNA list
-/atom/proc/transfer_blood_dna(list/blood_dna)
- var/list/blood_DNA
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- blood_DNA = D.blood_DNA
- if(!blood_DNA)
- blood_DNA = list()
- var/old_length = blood_DNA.len
- blood_DNA |= blood_dna
- if(blood_DNA.len > old_length)
- return TRUE//some new blood DNA was added
-
-/atom/proc/blood_DNA_to_color()
- return
-
-/obj/effect/decal/cleanable/blood/blood_DNA_to_color()
- var/list/colors = list()//first we make a list of all bloodtypes present
- for(var/bloop in Blood_DNA)
- if(colors[Blood_DNA[bloop]])
- colors[Blood_DNA[bloop]]++
- else
- colors[Blood_DNA[bloop]] = 1
-
- var/final_rgb = BLOOD_COLOR_HUMAN
-
- if(colors.len)
- var/sum = 0 //this is all shitcode, but it works; trust me
- final_rgb = bloodtype_to_color(colors[1])
- sum = colors[colors[1]]
- if(colors.len > 1)
- var/i = 2
- while(i <= colors.len)
- var/tmp = colors[colors[i]]
- final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum))
- sum += tmp
- i++
-
- return final_rgb
-
-/obj/item/clothing/blood_DNA_to_color()
- var/final_rgb = BLOOD_COLOR_HUMAN
- if(last_bloodtype)
- final_rgb = bloodtype_to_color(last_bloodtype)
- return final_rgb
+ // Transfer
+ if(fingerprints)
+ A.fingerprints |= fingerprints.Copy() //detective
+ if(fingerprintshidden)
+ A.fingerprintshidden |= fingerprintshidden.Copy() //admin
+ A.fingerprintslast = fingerprintslast
\ No newline at end of file
diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm
index a3b17a4c1f..5b4a75a36c 100644
--- a/code/modules/detectivework/evidence.dm
+++ b/code/modules/detectivework/evidence.dm
@@ -16,7 +16,7 @@
/obj/item/evidencebag/attackby(obj/item/I, mob/user, params)
if(evidencebagEquip(I, user))
- return 1
+ return TRUE
/obj/item/evidencebag/handle_atom_del(atom/A)
cut_overlays()
@@ -25,12 +25,12 @@
desc = initial(desc)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
- if(!istype(I) || I.anchored == 1)
+ if(!istype(I) || I.anchored == TRUE)
return
if(istype(I, /obj/item/evidencebag))
to_chat(user, "You find putting an evidence bag in another evidence bag to be slightly absurd.")
- return 1 //now this is podracing
+ return TRUE //now this is podracing
if(I.w_class > WEIGHT_CLASS_NORMAL)
to_chat(user, "[I] won't fit in [src].")
@@ -62,7 +62,7 @@
desc = "An evidence bag containing [I]. [I.desc]"
I.forceMove(src)
w_class = I.w_class
- return 1
+ return TRUE
/obj/item/evidencebag/attack_self(mob/user)
if(contents.len)
diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm
index 5940c3328d..c578d5b4d4 100644
--- a/code/modules/detectivework/scanner.dm
+++ b/code/modules/detectivework/scanner.dm
@@ -14,7 +14,7 @@
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
- var/scanning = 0
+ var/scanning = FALSE
var/list/log = list()
var/range = 8
var/view_check = TRUE
@@ -30,7 +30,7 @@
/obj/item/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
- scanning = 1
+ scanning = TRUE
to_chat(user, "Printing report, please wait...")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
@@ -56,7 +56,7 @@
// Clear the logs
log = list()
- scanning = 0
+ scanning = FALSE
/obj/item/detective_scanner/afterattack(atom/A, mob/user, params)
. = ..()
@@ -70,7 +70,7 @@
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
- scanning = 1
+ scanning = TRUE
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "You scan \the [A]. The scanner is now analysing the results...")
@@ -80,14 +80,20 @@
//Make our lists
var/list/fingerprints = list()
- var/list/blood = A.return_blood_DNA()
- var/list/fibers = A.return_fibers()
+ var/list/blood = list()
+ var/list/fibers = list()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
+ if(A.blood_DNA && A.blood_DNA.len)
+ blood = A.blood_DNA.Copy()
+
+ if(A.suit_fibers && A.suit_fibers.len)
+ fibers = A.suit_fibers.Copy()
+
if(ishuman(A))
var/mob/living/carbon/human/H = A
@@ -96,7 +102,8 @@
else if(!ismob(A))
- fingerprints = A.return_fingerprints()
+ if(A.fingerprints && A.fingerprints.len)
+ fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
@@ -115,40 +122,40 @@
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
- var/found_something = 0
+ var/found_something = FALSE
add_log("[STATION_TIME_TIMESTAMP("hh:mm:ss")][get_timestamp()] - [target_name]", 0)
// Fingerprints
if(length(fingerprints))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Prints:")
for(var/finger in fingerprints)
add_log("[finger]")
- found_something = 1
+ found_something = TRUE
// Blood
if (length(blood))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Blood:")
- found_something = 1
+ found_something = TRUE
for(var/B in blood)
add_log("Type: [blood[B]] DNA: [B]")
//Fibers
if(length(fibers))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Fibers:")
for(var/fiber in fibers)
add_log("[fiber]")
- found_something = 1
+ found_something = TRUE
//Reagents
if(length(reagents))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Reagents:")
for(var/R in reagents)
add_log("Reagent: [R] Volume: [reagents[R]]")
- found_something = 1
+ found_something = TRUE
// Get a new user
var/mob/holder = null
@@ -164,10 +171,10 @@
to_chat(holder, "You finish scanning \the [target_name].")
add_log("---------------------------------------------------------", 0)
- scanning = 0
+ scanning = FALSE
return
-/obj/item/detective_scanner/proc/add_log(msg, broadcast = 1)
+/obj/item/detective_scanner/proc/add_log(msg, broadcast = TRUE)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 732afdf1e5..333941791c 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -285,7 +285,8 @@
drop.transfer_mob_blood_dna(src)
return
else
- temp_blood_DNA = drop.return_blood_DNA() //we transfer the dna from the drip to the splatter
+ LAZYINITLIST(temp_blood_DNA)
+ temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
qdel(drop)//the drip is replaced by a bigger splatter
else
drop = new(T, get_static_viruses())
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 632281bb23..f4084c9561 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -56,11 +56,10 @@
if(!(I.item_flags & ABSTRACT))
msg += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
- var/datum/component/forensics/FR = GetComponent(/datum/component/forensics)
//gloves
if(gloves && !(SLOT_GLOVES in obscured))
msg += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands.\n"
- else if(FR && length(FR.blood_DNA))
+ else if(length(blood_DNA))
var/hand_number = get_num_arms(FALSE)
if(hand_number)
msg += "[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]!\n"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index f6d06c2d07..98ef403751 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -32,7 +32,7 @@
if(CONFIG_GET(flag/disable_stambuffer))
togglesprint()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /mob/living/carbon/human/clean_blood)))
/mob/living/carbon/human/ComponentInitialize()
@@ -689,9 +689,9 @@
if(..())
dropItemToGround(I)
-/mob/living/carbon/human/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
- return
+/mob/living/carbon/human/clean_blood(datum/source, strength)
+ . = ..()
+ // we've made our strength check already
if(gloves)
if(SEND_SIGNAL(gloves, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
update_inv_gloves()
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 8bbf2f4a47..f03b75cf11 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -65,9 +65,8 @@
FP.entered_dirs |= dir
FP.bloodiness = S.bloody_shoes[S.blood_state]
if(S.last_blood_DNA && S.last_bloodtype)
- FP.shoe_printer += list(S.last_blood_DNA = S.last_bloodtype)
+ FP.blood_DNA += list(S.last_blood_DNA = S.last_bloodtype)
//hacky as heck; we need to move the LAST entry to there, otherwise we mix all the blood
- FP.add_blood_DNA(S.return_blood_DNA())
FP.update_icon()
update_inv_shoes()
//End bloody footprints
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 9e598cff5f..8d125a72b0 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -474,7 +474,8 @@
if(isturf(next))
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
- B.add_blood_DNA(return_blood_DNA())
+ if(blood_DNA && blood_DNA.len)
+ B.blood_DNA |= blood_DNA.Copy()
var/newdir = get_dir(next, loc)
if(newdir == dir)
B.setDir(newdir)
diff --git a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm
index 7a2dd8702d..b397271c5a 100644
--- a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm
+++ b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm
@@ -39,8 +39,9 @@
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/semen/replace_decal(obj/effect/decal/cleanable/semen/S)
- S.add_blood_DNA(return_blood_DNA())
- return ..()
+ if(S.blood_DNA)
+ blood_DNA |= S.blood_DNA.Copy()
+ ..()
/datum/reagent/consumable/femcum
name = "Female Ejaculate"
@@ -72,8 +73,9 @@
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F)
- F.add_blood_DNA(return_blood_DNA())
- return ..()
+ if(F.blood_DNA)
+ blood_DNA |= F.blood_DNA.Copy()
+ ..()
/datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume)
if(!istype(T))
diff --git a/tgstation.dme b/tgstation.dme
index 9a03e5838d..af166504da 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -46,7 +46,6 @@
#include "code\__DEFINES\flags.dm"
#include "code\__DEFINES\food.dm"
#include "code\__DEFINES\footsteps.dm"
-#include "code\__DEFINES\forensics.dm"
#include "code\__DEFINES\hud.dm"
#include "code\__DEFINES\integrated_electronics.dm"
#include "code\__DEFINES\interaction_flags.dm"
@@ -352,7 +351,6 @@
#include "code\datums\components\empprotection.dm"
#include "code\datums\components\footstep.dm"
#include "code\datums\components\forced_gravity.dm"
-#include "code\datums\components\forensics.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"
#include "code\datums\components\knockoff.dm"