From 088bc484e32b131b7e75ffe816279e2ef529d358 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Sat, 17 Aug 2019 02:43:59 -0500 Subject: [PATCH] Forensics re-destroyed, but better this time. All lists are LAZYINITLIST, cleaning code is preserved, examine is preserved. We should be back in buisness, but this is just a 'holy fuck finally' commit --- code/__DEFINES/forensics.dm | 2 - code/datums/components/decals/blood.dm | 26 -- code/datums/components/forensics.dm | 184 -------------- code/game/atoms.dm | 124 +++++++++- code/game/machinery/washing_machine.dm | 5 +- code/game/objects/effects/decals/cleanable.dm | 3 +- .../effects/decals/cleanable/aliens.dm | 2 +- .../objects/effects/decals/cleanable/gibs.dm | 5 +- .../effects/decals/cleanable/humans.dm | 9 +- code/game/objects/items/stacks/stack.dm | 6 +- .../antagonists/wizard/equipment/artefact.dm | 7 +- code/modules/clothing/clothing.dm | 13 +- code/modules/clothing/gloves/_gloves.dm | 11 +- code/modules/clothing/head/_head.dm | 2 +- code/modules/clothing/masks/_masks.dm | 2 +- code/modules/clothing/neck/_neck.dm | 2 +- code/modules/clothing/shoes/_shoes.dm | 10 +- code/modules/clothing/suits/_suits.dm | 2 +- code/modules/clothing/under/_under.dm | 2 +- code/modules/detectivework/detective_work.dm | 227 +++++++----------- code/modules/detectivework/evidence.dm | 8 +- code/modules/detectivework/scanner.dm | 43 ++-- code/modules/mob/living/blood.dm | 3 +- .../mob/living/carbon/human/examine.dm | 3 +- code/modules/mob/living/carbon/human/human.dm | 8 +- .../mob/living/carbon/human/human_movement.dm | 3 +- .../mob/living/simple_animal/bot/mulebot.dm | 3 +- .../modules/reagents/reagents/cit_reagents.dm | 10 +- tgstation.dme | 2 - 29 files changed, 288 insertions(+), 439 deletions(-) delete mode 100644 code/__DEFINES/forensics.dm delete mode 100644 code/datums/components/forensics.dm 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"