From b73fc0c29bb45fc5db81db99f0e4e85f21e3f537 Mon Sep 17 00:00:00 2001
From: SabreML <57483089+SabreML@users.noreply.github.com>
Date: Sun, 20 Sep 2020 04:04:07 +0100
Subject: [PATCH] Adds a 'Clear Scanner Records' action for Forensic Scanners
(#14274)
* Adds clear_scanner as a verb
* Changed 'spawn()' to 'addtimer()'.
Also made the 'ding' sound a bit quieter.
* Some 'attack_self()' refactoring
* Some 'print_scanner_report()' refactoring
* Some 'scan()' refactoring
* Changes 1 & 0 to TRUE & FALSE
* and the rest of them
* Review fixes
Moved 'lowertext()', removed implied src,
changed '\the [target_name]' to '[A]'.
* Changed 'clear_scanner' from a verb to an action
* Made 'print_forensic_report' its own action
Don't want reagent scanners getting the same icon
* More cleanup
---
code/datums/action.dm | 8 +
code/modules/detective_work/scanner.dm | 201 +++++++++++++------------
icons/mob/actions/actions.dmi | Bin 123170 -> 123693 bytes
3 files changed, 112 insertions(+), 97 deletions(-)
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 1a146467b5a..84702757e86 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -162,6 +162,14 @@
/datum/action/item_action/print_report
name = "Print Report"
+/datum/action/item_action/print_forensic_report
+ name = "Print Report"
+ button_icon_state = "scanner_print"
+ use_itemicon = FALSE
+
+/datum/action/item_action/clear_records
+ name = "Clear Scanner Records"
+
/datum/action/item_action/toggle_gunlight
name = "Toggle Gunlight"
diff --git a/code/modules/detective_work/scanner.dm b/code/modules/detective_work/scanner.dm
index dea08c602f9..d043c3e1263 100644
--- a/code/modules/detective_work/scanner.dm
+++ b/code/modules/detective_work/scanner.dm
@@ -12,17 +12,17 @@
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
origin_tech = "engineering=4;biotech=2;programming=5"
- var/scanning = 0
+ var/scanning = FALSE
var/list/log = list()
- actions_types = list(/datum/action/item_action/print_report)
+ actions_types = list(/datum/action/item_action/print_forensic_report, /datum/action/item_action/clear_records)
-/obj/item/detective_scanner/attack_self(var/mob/user)
+/obj/item/detective_scanner/attack_self(mob/user)
var/search = input(user, "Enter name, fingerprint or blood DNA.", "Find record", "")
if(!search || user.stat || user.incapacitated())
return
- search = lowertext(search)
+ search = lowertext(search) //This is here so that it doesn't run 'lowertext()' until the checks have passed.
var/name
var/fingerprint = "FINGERPRINT NOT FOUND"
@@ -30,85 +30,95 @@
// I really, really wish I didn't have to split this into two seperate loops. But the datacore is awful.
- for(var/record in GLOB.data_core.general)
+ for(var/record in GLOB.data_core.general) // Search in the 'general' datacore
var/datum/data/record/S = record
- if(S && (search == lowertext(S.fields["fingerprint"]) || search == lowertext(S.fields["name"])))
+ if(S && (search == lowertext(S.fields["fingerprint"]) || search == lowertext(S.fields["name"]))) // Get Fingerprint and Name
name = S.fields["name"]
fingerprint = S.fields["fingerprint"]
- continue
+ break
- for(var/record in GLOB.data_core.medical)
+ for(var/record in GLOB.data_core.medical) // Then search in the 'medical' datacore
var/datum/data/record/M = record
- if(M && ( search == lowertext(M.fields["b_dna"]) || name == M.fields["name"]) )
+ if(M && (search == lowertext(M.fields["b_dna"]) || name == M.fields["name"])) // Get Blood DNA
dna = M.fields["b_dna"]
- if(fingerprint == "FINGERPRINT NOT FOUND") // We have searched by DNA, and do not have the relevant information from the fingerprint records.
+ if(fingerprint == "FINGERPRINT NOT FOUND") // We have searched for DNA, and so do not have the relevant information from the fingerprint records.
name = M.fields["name"]
for(var/gen_record in GLOB.data_core.general)
var/datum/data/record/S = gen_record
if(S && (name == S.fields["name"]))
fingerprint = S.fields["fingerprint"]
- continue
- continue
+ break
+ else //Eveything's been set, break the loop
+ break
if(name)
to_chat(user, "Match found in station records: [name]
\
Fingerprint: [fingerprint]
\
Blood DNA: [dna]")
- return
+ else
+ to_chat(user, "No match found in station records.")
- to_chat(user, "No match found in station records.")
-
-/obj/item/detective_scanner/ui_action_click()
- print_scanner_report()
+/obj/item/detective_scanner/ui_action_click(mob/user, actiontype)
+ if(actiontype == /datum/action/item_action/print_forensic_report)
+ print_scanner_report()
+ else
+ clear_scanner()
/obj/item/detective_scanner/proc/print_scanner_report()
- if(log.len && !scanning)
- scanning = 1
+ if(length(log) && !scanning)
+ scanning = TRUE
to_chat(usr, "Printing report, please wait...")
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
- spawn(100)
- // Create our paper
- var/obj/item/paper/P = new(get_turf(src))
- P.name = "paper- 'Scanner Report'"
- P.info = "
Scanner Report
"
- P.info += jointext(log, "
")
- P.info += "
Notes:
"
- P.info_links = P.info
-
- if(ismob(loc))
- var/mob/M = loc
- M.put_in_hands(P)
- to_chat(M, "Report printed. Log cleared.")
-
- // Clear the logs
- log = list()
- scanning = 0
+ addtimer(CALLBACK(src, .proc/make_paper, log), 10 SECONDS) // Create our paper
+ log = list() // Clear the logs
+ scanning = FALSE
else
- to_chat(usr, "The scanner has no logs or is in use.")
+ to_chat(usr, "The scanner has no logs or is in use.")
+
+/obj/item/detective_scanner/proc/make_paper(log) // Moved to a proc because 'spawn()' is evil
+ var/obj/item/paper/P = new(get_turf(src))
+ P.name = "paper- 'Scanner Report'"
+ P.info = "Scanner Report
"
+ P.info += jointext(log, "
")
+ P.info += "
Notes:
"
+ P.info_links = P.info
+
+ if(ismob(loc))
+ var/mob/M = loc
+ M.put_in_hands(P)
+ to_chat(M, "Report printed. Log cleared.")
-/obj/item/detective_scanner/attack(mob/living/M as mob, mob/user as mob)
+/obj/item/detective_scanner/proc/clear_scanner()
+ if(length(log) && !scanning)
+ log = list()
+ playsound(loc, 'sound/machines/ding.ogg', 40)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, usr, "Scanner logs cleared."), 1.5 SECONDS) //Timer so that it clears on the 'ding'
+ else
+ to_chat(usr, "The scanner has no logs or is in use.")
+
+
+/obj/item/detective_scanner/attack()
return
-
-/obj/item/detective_scanner/afterattack(atom/A, mob/user as mob, proximity)
+/obj/item/detective_scanner/afterattack(atom/A, mob/user)
scan(A, user)
-/obj/item/detective_scanner/proc/scan(var/atom/A, var/mob/user)
+/obj/item/detective_scanner/proc/scan(atom/A, mob/user)
if(!scanning)
// Can remotely scan objects and mobs.
- if(!in_range(A, user) && !(A in view(world.view, user)))
+ if(!(A in view(world.view, user)))
return
if(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...")
+ user.visible_message("[user] points [src] at [A] and performs a forensic scan.",
+ "You scan [A]. The scanner is now analysing the results...")
// GATHER INFORMATION
@@ -123,10 +133,10 @@
// Start gathering
- if(A.blood_DNA && A.blood_DNA.len)
+ if(length(A.blood_DNA))
blood = A.blood_DNA.Copy()
- if(A.suit_fibers && A.suit_fibers.len)
+ if(length(A.suit_fibers))
fibers = A.suit_fibers.Copy()
if(ishuman(A))
@@ -137,11 +147,11 @@
else if(!ismob(A))
- if(A.fingerprints && A.fingerprints.len)
+ if(length(A.fingerprints))
fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
- if(A.reagents && A.reagents.reagent_list.len)
+ if(A.reagents && length(A.reagents.reagent_list))
for(var/datum/reagent/R in A.reagents.reagent_list)
reagents[R.name] = R.volume
@@ -154,63 +164,60 @@
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)
+ // We gathered everything. Slowly display the results to the holder of the scanner.
+ var/found_something = FALSE
+ add_log("[station_time_timestamp()][get_timestamp()] - [target_name]", FALSE)
- var/found_something = 0
- add_log("[station_time_timestamp()][get_timestamp()] - [target_name]", 0)
+ // Fingerprints
+ if(length(fingerprints))
+ sleep(30)
+ add_log("Prints:")
+ for(var/finger in fingerprints)
+ add_log("[finger]")
+ found_something = TRUE
- // Fingerprints
- if(fingerprints && fingerprints.len)
- sleep(30)
- add_log("Prints:")
- for(var/finger in fingerprints)
- add_log("[finger]")
- found_something = 1
+ // Blood
+ if(length(blood))
+ sleep(30)
+ add_log("Blood:")
+ found_something = TRUE
+ for(var/B in blood)
+ add_log("Type: [blood[B]] DNA: [B]")
- // 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(length(fibers))
+ sleep(30)
+ add_log("Fibers:")
+ for(var/fiber in fibers)
+ add_log("[fiber]")
+ found_something = TRUE
- //Fibers
- if(fibers && fibers.len)
- sleep(30)
- add_log("Fibers:")
- for(var/fiber in fibers)
- add_log("[fiber]")
- found_something = 1
+ //Reagents
+ if(length(reagents))
+ sleep(30)
+ add_log("Reagents:")
+ for(var/R in reagents)
+ add_log("Reagent: [R] Volume: [reagents[R]]")
+ found_something = TRUE
- //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(loc))
+ holder = loc
- // Get a new user
- var/mob/holder = null
- if(ismob(src.loc))
- holder = src.loc
+ if(!found_something)
+ add_log("# No forensic traces found #", FALSE) // Don't display this to the holder user
+ if(holder)
+ to_chat(holder, "Unable to locate any fingerprints, materials, fibers, or blood on [A]!")
+ else
+ if(holder)
+ to_chat(holder, "You finish scanning [A].")
- if(!found_something)
- add_log("# No forensic traces found #", 0) // Don't display this to the holder user
- if(holder)
- to_chat(holder, "Unable to locate any fingerprints, materials, fibers, or blood on \the [target_name]!")
- else
- if(holder)
- to_chat(holder, "You finish scanning \the [target_name].")
+ add_log("---------------------------------------------------------", FALSE)
+ scanning = FALSE
- add_log("---------------------------------------------------------", 0)
- scanning = 0
- return
-
-/obj/item/detective_scanner/proc/add_log(var/msg, var/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/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi
index 80a5dbe5b04642cf2a0bbc39d59fcc2cf18becb1..011baf1e4ac90611cd64b7c3ece6309a4251e51e 100644
GIT binary patch
delta 42340
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