From 9e732afe6300a608f571067fbae187adc048ccfc Mon Sep 17 00:00:00 2001 From: Casper3667 <8396443+Casper3667@users.noreply.github.com> Date: Mon, 17 Jan 2022 16:51:52 +0100 Subject: [PATCH] Changes how forensic machine reports works (#12868) --- code/modules/clothing/clothing.dm | 4 +- .../detectivework/microscope/dnascanner.dm | 12 ++-- .../detectivework/microscope/microscope.dm | 47 ++++++++----- .../detectivework/tools/evidencebag.dm | 4 +- .../detectivework/tools/sample_kits.dm | 67 ++++++++++++++----- code/modules/detectivework/tools/swabs.dm | 14 ++-- code/modules/mob/living/carbon/human/human.dm | 2 +- .../mob/living/carbon/human/human_defines.dm | 2 +- code/modules/projectiles/guns/projectile.dm | 4 +- html/changelogs/ForensicReports.yml | 10 +++ 10 files changed, 113 insertions(+), 53 deletions(-) create mode 100644 html/changelogs/ForensicReports.yml diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 11f90e3a2a4..ed6f0910b7c 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -6,7 +6,7 @@ var/flash_protection = FLASH_PROTECTION_NONE // Sets the item's level of flash protection. var/tint = TINT_NONE // Sets the item's level of visual impairment tint. var/list/species_restricted = null //Only these species can wear this kit. - var/gunshot_residue //Used by forensics. + var/list/gunshot_residue //Used by forensics. var/list/accessories var/list/valid_accessory_slots @@ -56,7 +56,7 @@ // Aurora forensics port. /obj/item/clothing/clean_blood() . = ..() - gunshot_residue = null + LAZYCLEARLIST(gunshot_residue) /obj/item/proc/negates_gravity() return 0 diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm index 6ce527e22a1..3eba6060a12 100644 --- a/code/modules/detectivework/microscope/dnascanner.dm +++ b/code/modules/detectivework/microscope/dnascanner.dm @@ -99,7 +99,7 @@ last_process_worldtime = world.time /obj/machinery/dnaforensics/proc/complete_scan() - visible_message("[icon2html(src, viewers(get_turf(src)))] makes an insistent chime.", range = 2) + visible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] makes an insistent chime."), range = 2) update_icon() if(bloodsamp) var/obj/item/paper/P = new() @@ -110,13 +110,15 @@ //dna data itself var/data = "No scan information available." if(bloodsamp.dna != null) - data = "Spectometric analysis on provided sample has determined the presence of [bloodsamp.dna.len] strings of DNA.

" + data = "Spectometric analysis on provided sample has determined the presence of [length(bloodsamp.dna)] string\s of DNA.

" for(var/blood in bloodsamp.dna) - data += "Blood type: [bloodsamp.dna[blood]]
\nDNA: [blood]

" + if(bloodsamp.dna[blood]) + data += "Blood type: [bloodsamp.dna[blood]]
" + data += "DNA: [blood]

" else data += "No DNA found.
" - info = "[src] analysis report #[report_num]
" - info += "Scanned item:
[bloodsamp.name]
[bloodsamp.desc]

" + data + info = "[src] analysis report #[report_num]
" + info += "Scanned item: [bloodsamp.name]

" + data P.set_content_unsafe(pname, info) print(P) scanning = 0 diff --git a/code/modules/detectivework/microscope/microscope.dm b/code/modules/detectivework/microscope/microscope.dm index 91a4536ae6c..fd735214aef 100644 --- a/code/modules/detectivework/microscope/microscope.dm +++ b/code/modules/detectivework/microscope/microscope.dm @@ -10,7 +10,9 @@ density = 1 var/obj/item/sample = null - var/report_num = 0 + var/report_fiber_num = 0 + var/report_print_num = 0 + var/report_gsr_num = 0 /obj/machinery/microscope/attackby(obj/item/W as obj, mob/user as mob) @@ -43,47 +45,56 @@ var/info report.stamped = list(/obj/item/stamp) report.overlays = list("paper_stamped") - report_num++ if(istype(sample, /obj/item/forensics/slide)) var/obj/item/forensics/slide/slide = sample if(slide.has_swab) var/obj/item/forensics/swab/swab = slide.has_swab - - pname = "GSR report #[report_num]" - info = "Scanned item:
[swab.name]

" - - if(swab.gsr) - info += "Residue from a [swab.gsr] bullet detected." + report_gsr_num++ + pname = "GSR report #[report_gsr_num]" + info = "GSR anaylsis report #[report_gsr_num]
" + if(length(swab.gsr)) + info += "Residue analysis of the [swab.name] has determined the presence of the following residues." else info += "No gunpowder residue found." else if(slide.has_sample) var/obj/item/sample/fibers/fibers = slide.has_sample - pname = "Fiber report #[report_num]" - info = "Scanned item:
[initial(fibers.name)]

" + report_fiber_num++ + pname = "Fiber report #[report_fiber_num]" if(fibers.evidence) - info = "Molecular analysis on [fibers.name] has determined the presence of unique fiber strings.

" + info = "Fiber anaylsis report #[report_fiber_num]
" + info += "Source locations: " + info += "[english_list(fibers.source, "no sources were found", ", ", ", ", "")].

" + info += "Molecular analysis on [fibers.name] has determined the presence of unique fiber strings." else info += "No fibers found." else - pname = "Empty slide report #[report_num]" + pname = "Empty slide report #[report_fiber_num]" info = "Evidence suggests that there's nothing in this slide." else if(istype(sample, /obj/item/sample/print)) - pname = "Fingerprint report #[report_num]" - info = "Fingerprint analysis report #[report_num]: [sample.name]
" + report_print_num++ + pname = "Fingerprint report #[report_print_num]" var/obj/item/sample/print/card = sample + info = "Fingerprint analysis report #[report_print_num]
" + info += "Source locations: " + info += "[english_list(card.source, "no sources were found", ", ", ", ", "")].

" if(card.evidence && card.evidence.len) - info += "Surface analysis has determined unique fingerprint strings:

" + info += "Surface analysis has determined unique fingerprint strings:" else info += "No information available." diff --git a/code/modules/detectivework/tools/evidencebag.dm b/code/modules/detectivework/tools/evidencebag.dm index cbf2c097253..1073821072e 100644 --- a/code/modules/detectivework/tools/evidencebag.dm +++ b/code/modules/detectivework/tools/evidencebag.dm @@ -102,8 +102,8 @@ /obj/item/evidencebag/attackby(obj/item/W as obj, mob/user as mob) if(W.ispen() || istype(W, /obj/item/device/flashlight/pen)) var/tmp_label = sanitizeSafe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN) - if(length(tmp_label) > 15) - to_chat(user, "The label can be at most 15 characters long.") + if(length(tmp_label) > MAX_NAME_LEN) + to_chat(user, SPAN_NOTICE("The label can be at most [MAX_NAME_LEN] characters long.")) else to_chat(user, "You set the label to \"[tmp_label]\".") label_text = tmp_label diff --git a/code/modules/detectivework/tools/sample_kits.dm b/code/modules/detectivework/tools/sample_kits.dm index bcd08995e72..15ce1012a1c 100644 --- a/code/modules/detectivework/tools/sample_kits.dm +++ b/code/modules/detectivework/tools/sample_kits.dm @@ -2,28 +2,32 @@ name = "forensic sample" icon = 'icons/obj/forensics.dmi' w_class = ITEMSIZE_TINY - var/list/evidence = list() + var/list/evidence + var/list/source + var/label_text = "" -/obj/item/sample/New(var/newloc, var/atom/supplied) +/obj/item/sample/Initialize(var/newloc, var/atom/supplied) ..(newloc) if(supplied) copy_evidence(supplied) - name = "[initial(name)] (\the [initial(supplied.name)])" + name = "[initial(name)] ([supplied.get_swab_name()])" + LAZYADD(source, supplied.get_swab_name()) -/obj/item/sample/print/New(var/newloc, var/atom/supplied) +/obj/item/sample/print/Initialize(var/newloc, var/atom/supplied) ..(newloc, supplied) - if(evidence && evidence.len) + if(LAZYLEN(evidence)) icon_state = "fingerprint1" /obj/item/sample/proc/copy_evidence(var/atom/supplied) if(supplied.suit_fibers && supplied.suit_fibers.len) - evidence = supplied.suit_fibers.Copy() + LAZYADD(evidence, supplied.suit_fibers.Copy()) supplied.suit_fibers.Cut() /obj/item/sample/proc/merge_evidence(var/obj/item/sample/supplied, var/mob/user) if(!supplied.evidence || !supplied.evidence.len) return 0 - evidence |= supplied.evidence + LAZYDISTINCTADD(evidence, supplied.evidence) + LAZYDISTINCTADD(source, supplied.source) name = "[initial(name)] (combined)" to_chat(user, SPAN_NOTICE("You transfer the contents of \the [initial(supplied.name)] into \the [src].")) return 1 @@ -32,10 +36,11 @@ if(!supplied.evidence || !supplied.evidence.len) return 0 for(var/print in supplied.evidence) - if(evidence[print]) - evidence[print] = stringmerge(evidence[print],supplied.evidence[print]) + if(LAZYISIN(evidence, print)) + LAZYSET(evidence, print, stringmerge(evidence[print],supplied.evidence[print])) else - evidence[print] = supplied.evidence[print] + LAZYSET(evidence, print, supplied.evidence[print]) + LAZYDISTINCTADD(source, supplied.source) name = "[initial(name)] (combined)" to_chat(user, SPAN_NOTICE("You overlay \the [src] and \the [initial(supplied.name)], combining the print records.")) return 1 @@ -46,8 +51,38 @@ if(merge_evidence(O, user)) qdel(O) return 1 + else if (O.ispen()) + var/tmp_label = sanitizeSafe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN) + if(length(tmp_label) > MAX_NAME_LEN) + to_chat(user, SPAN_WARNING("The label can be at most [MAX_NAME_LEN] characters long.")) + else + to_chat(user, SPAN_NOTICE("You set the label to \"[tmp_label]\".")) + label_text = tmp_label + update_name_label() + return return ..() +/obj/item/sample/proc/update_name_label() + if(label_text == null) + name = initial(name) + else + name = "[initial(name)] ([label_text])" + +/obj/item/sample/Initialize(var/newloc, var/atom/supplied) + ..(newloc) + if(supplied) + copy_evidence(supplied) + name = "[initial(name)] ([supplied.get_swab_name()])" + LAZYADD(source, supplied.get_swab_name()) + +/atom/proc/get_swab_name() + return "\the [initial(name)]" + +/obj/machinery/door/get_swab_name() + if(name != initial(name)) + return "\the [initial(name)]: [name]" + return ..() + /obj/item/sample/fibers name = "fiber bag" desc = "Used to hold fiber evidence for the detective." @@ -65,7 +100,7 @@ item_state = "paper" /obj/item/sample/print/attack_self(var/mob/user) - if(evidence && evidence.len) + if(LAZYLEN(evidence)) return if(!ishuman(user)) return @@ -76,7 +111,8 @@ to_chat(user, SPAN_NOTICE("You firmly press your fingertips onto the card.")) var/fullprint = H.get_full_print() - evidence[fullprint] = fullprint + LAZYSET(evidence, fullprint, fullprint) + LAZYADD(source, "[H.name]") name = "[initial(name)] (\the [H])" icon_state = "fingerprint1" @@ -85,7 +121,7 @@ if(!ishuman(M)) return ..() - if(evidence && evidence.len) + if(LAZYLEN(evidence)) return 0 var/mob/living/carbon/human/H = M @@ -112,8 +148,9 @@ return 1 user.visible_message("[user] takes a copy of \the [H]'s fingerprints.") var/fullprint = H.get_full_print() - evidence[fullprint] = fullprint + LAZYSET(evidence, fullprint, fullprint) copy_evidence(src) + LAZYADD(source, "[H.name]") name = "[initial(name)] (\the [H])" icon_state = "fingerprint1" return 1 @@ -122,7 +159,7 @@ /obj/item/sample/print/copy_evidence(var/atom/supplied) if(supplied.fingerprints && supplied.fingerprints.len) for(var/print in supplied.fingerprints) - evidence[print] = supplied.fingerprints[print] + LAZYSET(evidence, print, supplied.fingerprints[print]) supplied.fingerprints.Cut() /obj/item/forensics/sample_kit diff --git a/code/modules/detectivework/tools/swabs.dm b/code/modules/detectivework/tools/swabs.dm index 2608803356e..c17890e0dd6 100644 --- a/code/modules/detectivework/tools/swabs.dm +++ b/code/modules/detectivework/tools/swabs.dm @@ -14,7 +14,7 @@ \n\nGSR samples are put in a slide and examined in a microscope. \ \nBlood and DNA samples are checked in the DNA analyzer" icon_state = "swab" - var/gsr = 0 + var/list/gsr var/list/dna var/used drop_sound = 'sound/items/drop/glass.ogg' @@ -70,17 +70,17 @@ return if(H.gloves) var/obj/item/clothing/B = H.gloves - if(!B.gunshot_residue) + if(!LAZYLEN(B.gunshot_residue)) to_chat(user, SPAN_WARNING("There is no residue on [H]'s [B].")) return user.visible_message("[user] swabs [H]'s [B] for a sample.") - gsr = B.gunshot_residue + LAZYADD(gsr, B.gunshot_residue) else - if(!H.gunshot_residue) + if(!LAZYLEN(H.gunshot_residue)) to_chat(user, SPAN_WARNING("There is no residue on [H]'s palms.")) return user.visible_message("[user] swabs [H]'s palm for a sample.") - gsr = H.gunshot_residue + LAZYADD(gsr, H.gunshot_residue) sample_type = "GSR" else return @@ -134,10 +134,10 @@ if (EVIDENCE_TYPE_GSR) var/obj/item/clothing/B = A - if(!istype(B) || !B.gunshot_residue) + if(!istype(B) || !LAZYLEN(B.gunshot_residue)) to_chat(user, SPAN_WARNING("There is no residue on \the [A].")) return - gsr = B.gunshot_residue + LAZYADD(gsr, B.gunshot_residue) sample_type = "residue" if (EVIDENCE_TYPE_SALIVA) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 003517cdd9d..b2692cf7fa1 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1291,7 +1291,7 @@ update_inv_gloves(1) germ_level = 0 - gunshot_residue = null + LAZYCLEARLIST(gunshot_residue) if(clean_feet && !shoes) footprint_color = null feet_blood_DNA = null diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index e8f1e24542e..79cb756fe8c 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -95,7 +95,7 @@ var/hand_blood_color var/list/flavor_texts = list() - var/gunshot_residue + var/list/gunshot_residue var/pulling_punches // Are you trying not to hurt your opponent? mob_bump_flag = HUMAN diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 7bd1e49757b..a16f8309807 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -101,10 +101,10 @@ var/mob/living/carbon/human/H = loc if(istype(H)) if(!istype(H.gloves, /obj/item/clothing)) - H.gunshot_residue = chambered.caliber + LAZYDISTINCTADD(H.gunshot_residue, chambered.caliber) else var/obj/item/clothing/G = H.gloves - G.gunshot_residue = chambered.caliber + LAZYDISTINCTADD(G.gunshot_residue, chambered.caliber) switch(handle_casings) if(DELETE_CASINGS) diff --git a/html/changelogs/ForensicReports.yml b/html/changelogs/ForensicReports.yml new file mode 100644 index 00000000000..c524c832e29 --- /dev/null +++ b/html/changelogs/ForensicReports.yml @@ -0,0 +1,10 @@ +author: TheGreyWolf + +delete-after: True + +changes: + - rscadd: "Fingerprint & fiber reports now show all source locations, even when combined and doors will have the door's name attached." + - rscadd: "Added the ability to rename fingerprint cards & fiber bags." + - tweak: "Changed the layout of the various forensic machine reports." + - tweak: "Each report from the forensic machines are now numbered per evidence type (fiber, fingerprint, GSR, DNA) rather than combined amount of reports." + - bugfix: "Gunshot residue now shows all residue on something rather than only the most recent."