// DNA machine /obj/machinery/dnaforensics name = "\improper DNA analyzer" desc = "A high-tech machine that is designed to sequence DNA samples." icon = 'icons/obj/forensics/forensics.dmi' icon_state = "dna-open" anchored = TRUE density = TRUE var/obj/item/forensics/swab = null /// is currently scanning var/scanning = FALSE /// Global number of reports ran from that machine type var/report_num = FALSE /obj/machinery/dnaforensics/Initialize(mapload) . = ..() component_parts = list() component_parts += new /obj/item/circuitboard/dnaforensics(null) component_parts += new /obj/item/stock_parts/micro_laser(null) component_parts += new /obj/item/stock_parts/manipulator(null) component_parts += new /obj/item/stock_parts/micro_laser(null) RefreshParts() /obj/machinery/dnaforensics/examine(mob/user) . = ..() . += "Click while holding a sample to insert a sample." . += "Alt-Click to eject the current sample." . += "Click with an empty hand to analyze the current sample." /obj/machinery/dnaforensics/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(!istype(used, /obj/item/forensics)) return ..() if(panel_open) to_chat(user, "You must close the panel!") return ITEM_INTERACT_COMPLETE if(swab) to_chat(user, "There is already a sample inside the scanner.") return ITEM_INTERACT_COMPLETE if(istype(used, /obj/item/forensics/swab)) to_chat(user, "You insert [used] into [src].") user.unequip(used) used.forceMove(src) swab = used update_icon() else to_chat(user, "This is not a compatible sample!") return ITEM_INTERACT_COMPLETE /obj/machinery/dnaforensics/attack_hand(mob/user) if(!swab) to_chat(user, "The scanner is empty!") return scanning = TRUE update_appearance(UPDATE_ICON) to_chat(user, "The scanner begins to hum as you analyze [swab].") if(!do_after(user, 2.5 SECONDS, src) || QDELETED(swab)) to_chat(user, "You have stopped analyzing [swab || "the swab"].") scanning = FALSE update_appearance(UPDATE_ICON) return to_chat(user, "Printing report...") var/obj/item/paper/report = new(get_turf(src)) report.stamped = list(/obj/item/stamp) report_num++ var/obj/item/forensics/swab/bloodswab = swab report.name = ("DNA scanner report no. [++report_num]: [bloodswab.name]") // dna data itself var/data = "No analysis data available." if(!isnull(bloodswab.dna)) data = "Spectrometric analysis on the provided sample determined the presence of DNA. DNA String(s) found: [length(bloodswab.dna)].

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

" else data += "\nNo DNA found.
" report.info = "Report number: [report_num]
" report.info += "\nAnalyzed object:
[bloodswab.name]
[bloodswab.desc]

" + data report.forceMove(get_turf(src)) report.update_icon() scanning = FALSE update_appearance(UPDATE_ICON) /obj/machinery/dnaforensics/proc/remove_sample(mob/living/remover) if(!istype(remover) || HAS_TRAIT(remover, TRAIT_HANDS_BLOCKED) || !Adjacent(remover)) return if(!swab) to_chat(remover, "There is no sample inside the scanner!") return to_chat(remover, "You remove [swab] from the scanner.") swab.forceMove(get_turf(src)) remover.put_in_hands(swab) swab = null update_appearance(UPDATE_ICON_STATE) /obj/machinery/dnaforensics/AltClick() remove_sample(usr) /obj/machinery/dnaforensics/MouseDrop(atom/other) if(usr == other) remove_sample(usr) return return ..() /obj/machinery/dnaforensics/update_icon_state() if(scanning) icon_state = "dna-working" else if(swab) icon_state = "dna-closed" else icon_state = "dna-open" /obj/machinery/dnaforensics/screwdriver_act(mob/user, obj/item/I) if(swab) return . = TRUE default_deconstruction_screwdriver(user, "dna-open-unpowered", "dna-open", I) /obj/machinery/dnaforensics/wrench_act(mob/user, obj/item/I) . = TRUE default_unfasten_wrench(user, I) /obj/machinery/dnaforensics/crowbar_act(mob/user, obj/item/I) if(swab) return . = TRUE default_deconstruction_crowbar(user, I) // Microscope code itself /obj/machinery/microscope name = "microscope" desc = "A microscope capable of magnifying images up to 3000 times." icon = 'icons/obj/forensics/forensics.dmi' icon_state = "microscope" anchored = TRUE density = TRUE var/obj/item/sample = null var/report_num = 0 var/fingerprint_complete = 6 /obj/machinery/microscope/Initialize(mapload) . = ..() component_parts = list() component_parts += new /obj/item/circuitboard/microscope(null) component_parts += new /obj/item/stock_parts/micro_laser(null) component_parts += new /obj/item/stack/sheet/glass(null) RefreshParts() /obj/machinery/microscope/examine(mob/user) . = ..() . += "Click while holding a sample to insert a sample." . += "Alt-Click to eject the current sample." . += "Click with an empty hand to study the current sample." /obj/machinery/microscope/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(!istype(used, /obj/item/forensics/swab) && !istype(used, /obj/item/sample)) return ..() if(panel_open) to_chat(user, "You must close the panel!") return ITEM_INTERACT_COMPLETE if(sample) to_chat(user, "There is already a sample in the microscope!") return ITEM_INTERACT_COMPLETE if(istype(used, /obj/item/forensics/swab)|| istype(used, /obj/item/sample/fibers) || istype(used, /obj/item/sample/print)) add_fingerprint(user) to_chat(user, "You insert [used] into the microscope.") user.unequip(used) used.forceMove(src) sample = used update_appearance(UPDATE_ICON_STATE) return ITEM_INTERACT_COMPLETE /obj/machinery/microscope/attack_hand(mob/user) if(!sample) to_chat(user, "There is no sample in the microscope to study.") return add_fingerprint(user) to_chat(user, "The microscope buzzes as you study [sample].") if(!do_after(user, 2.5 SECONDS, src) || !sample) to_chat(user, "You stop studying [sample].") return to_chat(user, "Printing Report...") var/obj/item/paper/report = new(get_turf(src)) report.stamped = list(/obj/item/stamp) report_num++ if(istype(sample, /obj/item/forensics/swab)) var/obj/item/forensics/swab/swab = sample report.name = ("Forensic report no. [++report_num]: [swab.name]") report.info = "Report number: [report_num]
" report.info += "Analyzed object:
[swab.name]

" if(swab.gsr) report.info += "Gunpowder residue found. Caliber: [swab.gsr]." else report.info += "Powder residue from the bullet was not found." else if(istype(sample, /obj/item/sample/fibers)) var/obj/item/sample/fibers/fibers = sample report.name = ("Report on fiber sample no. [++report_num]: [fibers.name]") report.info = "Report number: [report_num]
" report.info += "Analyzed object:
[fibers.name]

" if(fibers.evidence) report.info += "Molecular analysis on the provided sample determined the presence of the following unique fiber strands:

" for(var/fiber in fibers.evidence) report.info += "Most Likely Match: [fiber]

" else report.info += "No fibers found." else if(istype(sample, /obj/item/sample/print)) report.name = ("Fingerprint Analysis Report No. [report_num]: [sample.name]") report.info = "Report number: [report_num]
" report.info += "Fingerprint Analysis Report No. [report_num]: [sample.name]
" var/obj/item/sample/print/card = sample if(card.evidence && card.evidence.len) report.info += "
Surface analysis identified the following unique fingerprints:

" for(var/prints in card.evidence) report.info += "Fingerprint: " if(!is_complete_print(prints)) report.info += "INCOMPLETE PRINT" else report.info += "[prints]" report.info += "
" else report.info += "No analysis information available." if(report) report.update_icon() if(report.info) to_chat(user, report.info) return /obj/machinery/microscope/proc/remove_sample(mob/living/remover) if(!istype(remover) || remover.incapacitated() || !Adjacent(remover)) return if(!sample) to_chat(remover, "There is no sample inside the microscope!") return to_chat(remover, "you removed [sample] from the microscope.") sample.forceMove(get_turf(src)) remover.put_in_hands(sample) sample = null update_appearance(UPDATE_ICON_STATE) /obj/machinery/microscope/proc/is_complete_print(print) return stringpercent(print) <= fingerprint_complete /obj/machinery/microscope/AltClick() remove_sample(usr) /obj/machinery/microscope/MouseDrop(atom/other) if(usr == other) remove_sample(usr) else return ..() /obj/machinery/microscope/update_icon_state() icon_state = "microscope" if(sample) icon_state += "slide" /obj/machinery/microscope/screwdriver_act(mob/user, obj/item/I) if(sample) return . = TRUE default_deconstruction_screwdriver(user, "microscope_off", "microscope", I) /obj/machinery/microscope/wrench_act(mob/user, obj/item/I) . = TRUE default_unfasten_wrench(user, I) /obj/machinery/microscope/crowbar_act(mob/user, obj/item/I) if(sample) return . = TRUE default_deconstruction_crowbar(user, I)