//CONTAINS: Detective's Scanner // TODO: Split everything into easy to manage procs. /obj/item/device/detective_scanner name = "forensic scanner" desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings." icon_state = "forensic1" w_class = 3.0 item_state = "electronic" flags = CONDUCT | NOBLUDGEON slot_flags = SLOT_BELT var/scanning = 0 var/list/log = list() /obj/item/device/detective_scanner/attack_self(var/mob/user) if(log.len && !scanning) scanning = 1 user << "Printing report, please wait..." spawn(100) // Create our paper var/obj/item/weapon/paper/P = new(get_turf(src)) P.name = "paper- 'Scanner Report'" P.info = "
Scanner Report


" P.info += list2text(log, "
") P.info += "
Notes:
" P.info_links = P.info if(ismob(loc)) var/mob/M = loc M.put_in_hands(P) M << "Report printed. Log cleared." // Clear the logs log = list() scanning = 0 else user << "The scanner has no logs or is in use." /obj/item/device/detective_scanner/attack(mob/living/M as mob, mob/user as mob) return /obj/item/device/detective_scanner/afterattack(atom/A, mob/user as mob, proximity) scan(A, user) /obj/item/device/detective_scanner/proc/scan(var/atom/A, var/mob/user) if(!scanning) // Can remotely scan objects and mobs. if(!in_range(A, user) && !(A in view(world.view, user))) return if(loc != user) return scanning = 1 user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.") user << "You scan \the [A]. The scanner is now analysing the results..." // GATHER INFORMATION //Make our lists var/list/fingerprints = list() 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 if (istype(H.dna, /datum/dna) && !H.gloves) fingerprints += md5(H.dna.uni_identity) else if(!ismob(A)) if(A.fingerprints && A.fingerprints.len) fingerprints = A.fingerprints.Copy() // Only get reagents from non-mobs. if(A.reagents && A.reagents.reagent_list.len) for(var/datum/reagent/R in A.reagents.reagent_list) reagents[R.name] = R.volume // Get blood data from the blood reagent. if(istype(R, /datum/reagent/blood)) if(R.data["blood_DNA"] && R.data["blood_type"]) var/blood_DNA = R.data["blood_DNA"] var/blood_type = R.data["blood_type"] blood[blood_DNA] = blood_type // We gathered everything. Create a fork and slowly display the results to the holder of the scanner. spawn(0) var/found_something = 0 add_log("[worldtime2text()][get_timestamp()] - [target_name]", 0) // Fingerprints if(fingerprints && fingerprints.len) sleep(30) add_log("Prints:") for(var/finger in fingerprints) add_log("[finger]") found_something = 1 // Blood if (blood && blood.len) sleep(30) add_log("Blood:") found_something = 1 for(var/B in blood) add_log("Type: [blood[B]] DNA: [B]") //Fibers if(fibers && fibers.len) sleep(30) add_log("Fibers:") for(var/fiber in fibers) add_log("[fiber]") found_something = 1 //Reagents if(reagents && reagents.len) sleep(30) add_log("Reagents:") for(var/R in reagents) add_log("Reagent: [R] Volume: [reagents[R]]") found_something = 1 // Get a new user var/mob/holder = null if(ismob(src.loc)) holder = src.loc if(!found_something) add_log("# No forensic traces found #", 0) // Don't display this to the holder user if(holder) holder << "Unable to locate any fingerprints, materials, fibers, or blood on \the [target_name]!" else if(holder) holder << "You finish scanning \the [target_name]." add_log("---------------------------------------------------------", 0) scanning = 0 return /obj/item/device/detective_scanner/proc/add_log(var/msg, var/broadcast = 1) if(scanning) if(broadcast && ismob(loc)) var/mob/M = loc M << msg log += "  [msg]" else CRASH("[src] \ref[src] is adding a log when it was never put in scanning mode!") /proc/get_timestamp() return time2text(world.time + 432000, ":ss")