Revert "PLASE"

This reverts commit 8af225e6e3.
This commit is contained in:
Fermi
2019-11-24 03:06:08 +00:00
parent aeb8606ce0
commit ba4fa1ef67
2145 changed files with 1387321 additions and 5257 deletions
@@ -0,0 +1,107 @@
//CONTAINS: Suit fibers and Detective's Scanning Computer
/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.diseases))
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/add_hiddenprint(mob/living/M)
if(!M || !M.key)
return
if(!fingerprintshidden) //Add the list if it does not exist
fingerprintshidden = list()
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
//Set ignoregloves to add prints irrespective of the mob having gloves on.
/atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
if(!M || !M.key)
return
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 = TRUE to avoid infinite loop.
return
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)
// Make sure everything are lists.
LAZYINITLIST(A.fingerprints)
LAZYINITLIST(A.fingerprintshidden)
LAZYINITLIST(fingerprints)
LAZYINITLIST(fingerprintshidden)
// Transfer
if(fingerprints)
A.fingerprints |= fingerprints.Copy() //detective
if(fingerprintshidden)
A.fingerprintshidden |= fingerprintshidden.Copy() //admin
A.fingerprintslast = fingerprintslast
+95
View File
@@ -0,0 +1,95 @@
//CONTAINS: Evidence bags
/obj/item/evidencebag
name = "evidence bag"
desc = "An empty evidence bag."
icon = 'icons/obj/storage.dmi'
icon_state = "evidenceobj"
item_state = ""
w_class = WEIGHT_CLASS_TINY
/obj/item/evidencebag/afterattack(obj/item/I, mob/user,proximity)
. = ..()
if(!proximity || loc == I)
return
evidencebagEquip(I, user)
/obj/item/evidencebag/attackby(obj/item/I, mob/user, params)
if(evidencebagEquip(I, user))
return TRUE
/obj/item/evidencebag/handle_atom_del(atom/A)
cut_overlays()
w_class = initial(w_class)
icon_state = initial(icon_state)
desc = initial(desc)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
if(!istype(I) || I.anchored == TRUE)
return
if(istype(I, /obj/item/evidencebag))
to_chat(user, "<span class='notice'>You find putting an evidence bag in another evidence bag to be slightly absurd.</span>")
return TRUE //now this is podracing
if(I.w_class > WEIGHT_CLASS_NORMAL)
to_chat(user, "<span class='notice'>[I] won't fit in [src].</span>")
return
if(contents.len)
to_chat(user, "<span class='notice'>[src] already has something inside it.</span>")
return
if(!isturf(I.loc)) //If it isn't on the floor. Do some checks to see if it's in our hands or a box. Otherwise give up.
if(SEND_SIGNAL(I.loc, COMSIG_CONTAINS_STORAGE)) //in a container.
SEND_SIGNAL(I.loc, COMSIG_TRY_STORAGE_TAKE, I, src)
if(!user.dropItemToGround(I))
return
user.visible_message("[user] puts [I] into [src].", "<span class='notice'>You put [I] inside [src].</span>",\
"<span class='italics'>You hear a rustle as someone puts something into a plastic bag.</span>")
icon_state = "evidence"
var/mutable_appearance/in_evidence = new(I)
in_evidence.plane = FLOAT_PLANE
in_evidence.layer = FLOAT_LAYER
in_evidence.pixel_x = 0
in_evidence.pixel_y = 0
add_overlay(in_evidence)
add_overlay("evidence") //should look nicer for transparent stuff. not really that important, but hey.
desc = "An evidence bag containing [I]. [I.desc]"
I.forceMove(src)
w_class = I.w_class
return TRUE
/obj/item/evidencebag/attack_self(mob/user)
if(contents.len)
var/obj/item/I = contents[1]
user.visible_message("[user] takes [I] out of [src].", "<span class='notice'>You take [I] out of [src].</span>",\
"<span class='italics'>You hear someone rustle around in a plastic bag, and remove something.</span>")
cut_overlays() //remove the overlays
user.put_in_hands(I)
w_class = WEIGHT_CLASS_TINY
icon_state = "evidenceobj"
desc = "An empty evidence bag."
else
to_chat(user, "[src] is empty.")
icon_state = "evidenceobj"
return
/obj/item/storage/box/evidence
name = "evidence bag box"
desc = "A box claiming to contain evidence bags."
/obj/item/storage/box/evidence/New()
new /obj/item/evidencebag(src)
new /obj/item/evidencebag(src)
new /obj/item/evidencebag(src)
new /obj/item/evidencebag(src)
new /obj/item/evidencebag(src)
new /obj/item/evidencebag(src)
..()
return
+217
View File
@@ -0,0 +1,217 @@
//CONTAINS: Detective's Scanner
// TODO: Split everything into easy to manage procs.
/obj/item/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 = 'icons/obj/device.dmi'
icon_state = "forensicnew"
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
var/scanning = FALSE
var/list/log = list()
var/range = 8
var/view_check = TRUE
actions_types = list(/datum/action/item_action/displayDetectiveScanResults)
/datum/action/item_action/displayDetectiveScanResults
name = "Display Forensic Scanner Results"
/datum/action/item_action/displayDetectiveScanResults/Trigger()
var/obj/item/detective_scanner/scanner = target
if(istype(scanner))
scanner.displayDetectiveScanResults(usr)
/obj/item/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
scanning = TRUE
to_chat(user, "<span class='notice'>Printing report, please wait...</span>")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
to_chat(user, "<span class='notice'>The scanner has no logs or is in use.</span>")
/obj/item/detective_scanner/attack(mob/living/M, mob/user)
return
/obj/item/detective_scanner/proc/PrintReport()
// Create our paper
var/obj/item/paper/P = new(get_turf(src))
P.name = "paper- 'Scanner Report'"
P.info = "<center><font size='6'><B>Scanner Report</B></font></center><HR><BR>"
P.info += jointext(log, "<BR>")
P.info += "<HR><B>Notes:</B><BR>"
P.info_links = P.info
P.updateinfolinks()
if(ismob(loc))
var/mob/M = loc
M.put_in_hands(P)
to_chat(M, "<span class='notice'>Report printed. Log cleared.</span>")
// Clear the logs
log = list()
scanning = FALSE
/obj/item/detective_scanner/afterattack(atom/A, mob/user, params)
. = ..()
scan(A, user)
return FALSE
/obj/item/detective_scanner/proc/scan(atom/A, mob/user)
set waitfor = 0
if(!scanning)
// Can remotely scan objects and mobs.
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
scanning = TRUE
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "<span class='notice'>You scan \the [A]. The scanner is now analysing the results...</span>")
// 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(!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"]
LAZYINITLIST(blood)
blood[blood_DNA] = blood_type
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
var/found_something = FALSE
add_log("<B>[STATION_TIME_TIMESTAMP("hh:mm:ss")][get_timestamp()] - [target_name]</B>", 0)
// Fingerprints
if(length(fingerprints))
sleep(3 SECONDS)
add_log("<span class='info'><B>Prints:</B></span>")
for(var/finger in fingerprints)
add_log("[finger]")
found_something = TRUE
// Blood
if (length(blood))
sleep(3 SECONDS)
add_log("<span class='info'><B>Blood:</B></span>")
found_something = TRUE
for(var/B in blood)
add_log("Type: <font color='red'>[blood[B]]</font> DNA: <font color='red'>[B]</font>")
//Fibers
if(length(fibers))
sleep(3 SECONDS)
add_log("<span class='info'><B>Fibers:</B></span>")
for(var/fiber in fibers)
add_log("[fiber]")
found_something = TRUE
//Reagents
if(length(reagents))
sleep(3 SECONDS)
add_log("<span class='info'><B>Reagents:</B></span>")
for(var/R in reagents)
add_log("Reagent: <font color='red'>[R]</font> Volume: <font color='red'>[reagents[R]]</font>")
found_something = TRUE
// Get a new user
var/mob/holder = null
if(ismob(src.loc))
holder = src.loc
if(!found_something)
add_log("<I># No forensic traces found #</I>", 0) // Don't display this to the holder user
if(holder)
to_chat(holder, "<span class='warning'>Unable to locate any fingerprints, materials, fibers, or blood on \the [target_name]!</span>")
else
if(holder)
to_chat(holder, "<span class='notice'>You finish scanning \the [target_name].</span>")
add_log("---------------------------------------------------------", 0)
scanning = FALSE
return
/obj/item/detective_scanner/proc/add_log(msg, broadcast = TRUE)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
to_chat(M, msg)
log += "&nbsp;&nbsp;[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")
/obj/item/detective_scanner/AltClick(mob/living/user)
// Best way for checking if a player can use while not incapacitated, etc
if(!user.canUseTopic(src, be_close=TRUE))
return
if(!LAZYLEN(log))
to_chat(user, "<span class='notice'>Cannot clear logs, the scanner has no logs.</span>")
return
if(scanning)
to_chat(user, "<span class='notice'>Cannot clear logs, the scanner is in use.</span>")
return
to_chat(user, "<span class='notice'>The scanner logs are cleared.</span>")
log = list()
/obj/item/detective_scanner/examine(mob/user)
..()
if(LAZYLEN(log) && !scanning)
to_chat(user, "<span class='notice'>Alt-click to clear scanner logs.</span>")
/obj/item/detective_scanner/proc/displayDetectiveScanResults(mob/living/user)
// No need for can-use checks since the action button should do proper checks
if(!LAZYLEN(log))
to_chat(user, "<span class='notice'>Cannot display logs, the scanner has no logs.</span>")
return
if(scanning)
to_chat(user, "<span class='notice'>Cannot display logs, the scanner is in use.</span>")
return
to_chat(user, "<span class='notice'><B>Scanner Report</B></span>")
for(var/iterLog in log)
to_chat(user, iterLog)