mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 16:18:01 +01:00
Refactors the forensics component into a datum (#66809)
About The Pull Request
This was doing things component really shouldn't be doing, and now all
of its behaviour is contained onto a datum, as it should've been the
whole time
Why It's Good For The CODEBASE
some things just really shouldn't be components, this was made back when DCS was first implemented and just thrown in because it was the new hot thing i guess, but datumized forensics makes far more sense, AND doesn't use GetComponent
TODO:
More thorough testing to make sure nothing broke
Changelog
🆑
refactor: Turned the forensics component into a datum.
/🆑
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
/// Checks if an object is covered in blood
|
||||
#define HAS_BLOOD_DNA(thing) (length(thing.GetComponent(/datum/component/forensics)?.blood_DNA))
|
||||
|
||||
//Bloody shoes/footprints
|
||||
/// Minimum alpha of footprints
|
||||
#define BLOODY_FOOTPRINT_BASE_ALPHA 20
|
||||
@@ -20,5 +17,5 @@
|
||||
#define BLOOD_STATE_XENO "xeno"
|
||||
/// Black robot oil
|
||||
#define BLOOD_STATE_OIL "oil"
|
||||
/// No blood is present
|
||||
/// No blood is present
|
||||
#define BLOOD_STATE_NOT_BLOODY "no blood whatsoever"
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/// Returns the fingerprints on this atom
|
||||
#define GET_ATOM_FINGERPRINTS(atom) atom.forensics?.fingerprints
|
||||
/// Returns the hidden prints on this atom
|
||||
#define GET_ATOM_HIDDENPRINTS(atom) atom.forensics?.hiddenprints
|
||||
/// Returns the blood dna on this atom
|
||||
#define GET_ATOM_BLOOD_DNA(atom) atom.forensics?.blood_DNA
|
||||
/// Returns the fibers on this atom
|
||||
#define GET_ATOM_FIBRES(atom) atom.forensics?.fibers
|
||||
/// Returns the number of unique blood dna sources on this atom
|
||||
#define GET_ATOM_BLOOD_DNA_LENGTH(atom) (isnull(atom.forensics) ? 0 : length(atom.forensics.blood_DNA))
|
||||
@@ -48,13 +48,13 @@
|
||||
var/list/seen_atoms = view(7, owner)
|
||||
if(LAZYLEN(trigger_objs))
|
||||
for(var/obj/O in seen_atoms)
|
||||
if(is_type_in_typecache(O, trigger_objs) || (phobia_type == "blood" && HAS_BLOOD_DNA(O)))
|
||||
if(is_type_in_typecache(O, trigger_objs) || (phobia_type == "blood" && GET_ATOM_BLOOD_DNA_LENGTH(O)))
|
||||
freak_out(O)
|
||||
return
|
||||
for(var/mob/living/carbon/human/HU in seen_atoms) //check equipment for trigger items
|
||||
for(var/X in HU.get_all_worn_items() | HU.held_items)
|
||||
var/obj/I = X
|
||||
if(!QDELETED(I) && (is_type_in_typecache(I, trigger_objs) || (phobia_type == "blood" && HAS_BLOOD_DNA(I))))
|
||||
if(!QDELETED(I) && (is_type_in_typecache(I, trigger_objs) || (phobia_type == "blood" && GET_ATOM_BLOOD_DNA_LENGTH(I))))
|
||||
freak_out(I)
|
||||
return
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
if(HAS_TRAIT(parent_atom, TRAIT_LIGHT_STEP)) //the character is agile enough to don't mess their clothing and hands just from one blood splatter at floor
|
||||
return TRUE
|
||||
|
||||
parent_atom.add_blood_DNA(pool.return_blood_DNA())
|
||||
parent_atom.add_blood_DNA(GET_ATOM_BLOOD_DNA(pool))
|
||||
update_icon()
|
||||
|
||||
/**
|
||||
@@ -156,7 +156,7 @@
|
||||
oldLocFP.exited_dirs |= wielder.dir
|
||||
add_parent_to_footprint(oldLocFP)
|
||||
oldLocFP.bloodiness = half_our_blood
|
||||
oldLocFP.add_blood_DNA(parent_atom.return_blood_DNA())
|
||||
oldLocFP.add_blood_DNA(GET_ATOM_BLOOD_DNA(parent_atom))
|
||||
oldLocFP.update_appearance()
|
||||
|
||||
half_our_blood = bloody_shoes[last_blood_state] / 2
|
||||
@@ -176,7 +176,7 @@
|
||||
FP.entered_dirs |= wielder.dir
|
||||
add_parent_to_footprint(FP)
|
||||
FP.bloodiness = half_our_blood
|
||||
FP.add_blood_DNA(parent_atom.return_blood_DNA())
|
||||
FP.add_blood_DNA(GET_ATOM_BLOOD_DNA(parent_atom))
|
||||
FP.update_appearance()
|
||||
|
||||
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/datum/component/forensics
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE
|
||||
can_transfer = TRUE
|
||||
var/list/fingerprints //assoc print = print
|
||||
var/list/hiddenprints //assoc ckey = realname/gloves/ckey
|
||||
var/list/blood_DNA //assoc dna = bloodtype
|
||||
var/list/fibers //assoc print = print
|
||||
|
||||
/datum/component/forensics/InheritComponent(datum/component/forensics/F, original) //Use of | and |= being different here is INTENTIONAL.
|
||||
fingerprints = LAZY_LISTS_OR(fingerprints, F.fingerprints)
|
||||
hiddenprints = LAZY_LISTS_OR(hiddenprints, F.hiddenprints)
|
||||
blood_DNA = LAZY_LISTS_OR(blood_DNA, F.blood_DNA)
|
||||
fibers = LAZY_LISTS_OR(fibers, F.fibers)
|
||||
check_blood()
|
||||
return ..()
|
||||
|
||||
/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
fingerprints = new_fingerprints
|
||||
hiddenprints = new_hiddenprints
|
||||
blood_DNA = new_blood_DNA
|
||||
fibers = new_fibers
|
||||
check_blood()
|
||||
|
||||
/datum/component/forensics/RegisterWithParent()
|
||||
check_blood()
|
||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act)
|
||||
|
||||
/datum/component/forensics/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(COMSIG_COMPONENT_CLEAN_ACT))
|
||||
|
||||
/datum/component/forensics/PostTransfer()
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
/datum/component/forensics/proc/wipe_fingerprints()
|
||||
fingerprints = null
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/wipe_hiddenprints()
|
||||
return //no.
|
||||
|
||||
/datum/component/forensics/proc/wipe_blood_DNA()
|
||||
blood_DNA = null
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/wipe_fibers()
|
||||
fibers = null
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/clean_act(datum/source, clean_types)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
. = NONE
|
||||
if(clean_types & CLEAN_TYPE_FINGERPRINTS)
|
||||
wipe_fingerprints()
|
||||
. = COMPONENT_CLEANED
|
||||
if(clean_types & CLEAN_TYPE_BLOOD)
|
||||
wipe_blood_DNA()
|
||||
. = COMPONENT_CLEANED
|
||||
if(clean_types & CLEAN_TYPE_FIBERS)
|
||||
wipe_fibers()
|
||||
. = COMPONENT_CLEANED
|
||||
|
||||
/datum/component/forensics/proc/add_fingerprint_list(list/_fingerprints) //list(text)
|
||||
if(!length(_fingerprints))
|
||||
return
|
||||
LAZYINITLIST(fingerprints)
|
||||
for(var/i in _fingerprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
|
||||
fingerprints[i] = i
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
|
||||
if(!isliving(M))
|
||||
if(!iscameramob(M))
|
||||
return
|
||||
if(isaicamera(M))
|
||||
var/mob/camera/ai_eye/ai_camera = M
|
||||
if(!ai_camera.ai)
|
||||
return
|
||||
M = ai_camera.ai
|
||||
add_hiddenprint(M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
add_fibers(H)
|
||||
var/obj/item/gloves = H.gloves
|
||||
if(gloves) //Check if the gloves (if any) hide fingerprints
|
||||
if(!(gloves.body_parts_covered & HANDS) || HAS_TRAIT(gloves, TRAIT_FINGERPRINT_PASSTHROUGH) || HAS_TRAIT(H, TRAIT_FINGERPRINT_PASSTHROUGH))
|
||||
ignoregloves = TRUE
|
||||
if(!ignoregloves)
|
||||
H.gloves.add_fingerprint(H, TRUE) //ignoregloves = 1 to avoid infinite loop.
|
||||
return
|
||||
var/full_print = md5(H.dna.unique_identity)
|
||||
LAZYSET(fingerprints, full_print, full_print)
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/add_fiber_list(list/_fibertext) //list(text)
|
||||
if(!length(_fibertext))
|
||||
return
|
||||
LAZYINITLIST(fibers)
|
||||
for(var/i in _fibertext) //We use an associative list, make sure we don't just merge a non-associative list into ours.
|
||||
fibers[i] = i
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/add_fibers(mob/living/carbon/human/M)
|
||||
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) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, 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) && !LAZYACCESS(fibers, fibertext)) //Wearing a suit means less of the uniform exposed.
|
||||
LAZYSET(fibers, fibertext, 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) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
else if(M.w_uniform)
|
||||
fibertext = "Fibers from \a [M.w_uniform]."
|
||||
if(prob(15*item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
// "Added fibertext: [fibertext]"
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
if(M.gloves)
|
||||
fibertext = "Material from a pair of [M.gloves.name]."
|
||||
if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
else if(M.gloves)
|
||||
fibertext = "Material from a pair of [M.gloves.name]."
|
||||
if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/add_hiddenprint_list(list/_hiddenprints) //list(ckey = text)
|
||||
if(!length(_hiddenprints))
|
||||
return
|
||||
LAZYINITLIST(hiddenprints)
|
||||
for(var/i in _hiddenprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
|
||||
hiddenprints[i] = _hiddenprints[i]
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/add_hiddenprint(mob/M)
|
||||
if(!isliving(M))
|
||||
if(!iscameramob(M))
|
||||
return
|
||||
if(isaicamera(M))
|
||||
var/mob/camera/ai_eye/ai_camera = M
|
||||
if(!ai_camera.ai)
|
||||
return
|
||||
M = ai_camera.ai
|
||||
if(!M.key)
|
||||
return
|
||||
var/hasgloves = ""
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.gloves)
|
||||
hasgloves = "(gloves)"
|
||||
var/current_time = time_stamp()
|
||||
if(!LAZYACCESS(hiddenprints, M.key))
|
||||
LAZYSET(hiddenprints, M.key, "First: \[[current_time]\] \"[M.real_name]\"[hasgloves]. Ckey: [M.ckey]")
|
||||
else
|
||||
var/laststamppos = findtext(LAZYACCESS(hiddenprints, M.key), "\nLast: ")
|
||||
if(laststamppos)
|
||||
LAZYSET(hiddenprints, M.key, copytext(hiddenprints[M.key], 1, laststamppos))
|
||||
hiddenprints[M.key] += "\nLast: \[[current_time]\] \"[M.real_name]\"[hasgloves]. Ckey: [M.ckey]" //made sure to be existing by if(!LAZYACCESS);else
|
||||
var/atom/A = parent
|
||||
A.fingerprintslast = M.ckey
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/add_blood_DNA(list/dna) //list(dna_enzymes = type)
|
||||
if(!length(dna))
|
||||
return
|
||||
LAZYINITLIST(blood_DNA)
|
||||
for(var/i in dna)
|
||||
blood_DNA[i] = dna[i]
|
||||
check_blood()
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/check_blood()
|
||||
if(!isitem(parent))
|
||||
return
|
||||
if(!length(blood_DNA))
|
||||
return
|
||||
parent.AddElement(/datum/element/decal/blood)
|
||||
@@ -53,7 +53,7 @@
|
||||
if(sniffed)
|
||||
var/old_target = tracking_target
|
||||
possible = list()
|
||||
var/list/prints = sniffed.return_fingerprints()
|
||||
var/list/prints = GET_ATOM_FINGERPRINTS(sniffed)
|
||||
if(prints)
|
||||
for(var/mob/living/carbon/C in GLOB.carbon_list)
|
||||
if(prints[md5(C.dna.unique_identity)])
|
||||
|
||||
+7
-2
@@ -159,6 +159,8 @@
|
||||
var/damage_deflection = 0
|
||||
|
||||
var/resistance_flags = NONE // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF
|
||||
/// forensics datum, contains fingerprints, fibres, blood_dna and hiddenprints on this atom
|
||||
var/datum/forensics/forensics
|
||||
|
||||
/**
|
||||
* Called when an atom is created in byond (built in engine proc)
|
||||
@@ -309,6 +311,9 @@
|
||||
if(reagents)
|
||||
QDEL_NULL(reagents)
|
||||
|
||||
if(forensics)
|
||||
QDEL_NULL(forensics)
|
||||
|
||||
orbiters = null // The component is attached to us normaly and will be deleted elsewhere
|
||||
|
||||
LAZYCLEARLIST(overlays)
|
||||
@@ -888,9 +893,9 @@
|
||||
var/new_blood_dna = injected_mob.get_blood_dna_list()
|
||||
if(!new_blood_dna)
|
||||
return FALSE
|
||||
var/old_length = blood_DNA_length()
|
||||
var/old_length = GET_ATOM_BLOOD_DNA_LENGTH(src)
|
||||
add_blood_DNA(new_blood_dna)
|
||||
if(blood_DNA_length() == old_length)
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src) == old_length)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
|
||||
C.add_blood_DNA(return_blood_DNA())
|
||||
C.add_blood_DNA(GET_ATOM_BLOOD_DNA(src))
|
||||
if (bloodiness)
|
||||
C.bloodiness = min((C.bloodiness + bloodiness), BLOOD_AMOUNT_PER_DECAL)
|
||||
return ..()
|
||||
|
||||
@@ -567,9 +567,9 @@
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
|
||||
add_blood_DNA(from.return_blood_DNA())
|
||||
add_fingerprint_list(from.return_fingerprints())
|
||||
add_hiddenprint_list(from.return_hiddenprints())
|
||||
add_blood_DNA(GET_ATOM_BLOOD_DNA(from))
|
||||
add_fingerprint_list(GET_ATOM_FINGERPRINTS(from))
|
||||
add_hiddenprint_list(GET_ATOM_HIDDENPRINTS(from))
|
||||
fingerprintslast = from.fingerprintslast
|
||||
//TODO bloody overlay
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
return
|
||||
|
||||
var/interface = "A log of every player who has touched [victim], sorted by last touch.<br><br><ol>"
|
||||
var/victim_hiddenprints = victim.return_hiddenprints()
|
||||
var/victim_hiddenprints = GET_ATOM_HIDDENPRINTS(victim)
|
||||
|
||||
if(!islist(victim_hiddenprints))
|
||||
victim_hiddenprints = list()
|
||||
|
||||
@@ -373,7 +373,7 @@
|
||||
/datum/heretic_knowledge/curse/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
|
||||
fingerprints = list()
|
||||
for(var/atom/requirements as anything in atoms)
|
||||
fingerprints[requirements.return_fingerprints()] = 1
|
||||
fingerprints[GET_ATOM_FINGERPRINTS(requirements)] = 1
|
||||
list_clear_nulls(fingerprints)
|
||||
|
||||
// No fingerprints? No ritual
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
|
||||
if(HAS_BLOOD_DNA(src))
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands")
|
||||
|
||||
/obj/item/clothing/gloves/update_clothes_damaged_state(damaged_state = CLOTHING_DAMAGED)
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
|
||||
if(HAS_BLOOD_DNA(src))
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
if(clothing_flags & LARGE_WORN_ICON)
|
||||
. += mutable_appearance('icons/effects/64x64.dmi', "helmetblood_large")
|
||||
else
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
if(body_parts_covered & HEAD)
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
|
||||
if(HAS_BLOOD_DNA(src))
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
|
||||
|
||||
/obj/item/clothing/mask/update_clothes_damaged_state(damaged_state = CLOTHING_DAMAGED)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
if(body_parts_covered & HEAD)
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
|
||||
if(HAS_BLOOD_DNA(src))
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
|
||||
|
||||
/obj/item/clothing/neck/tie
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe")
|
||||
if(HAS_BLOOD_DNA(src))
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
if(clothing_flags & LARGE_WORN_ICON)
|
||||
. += mutable_appearance('icons/effects/64x64.dmi', "shoeblood_large")
|
||||
else
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
|
||||
if(HAS_BLOOD_DNA(src))
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood")
|
||||
|
||||
var/mob/living/carbon/human/M = loc
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
|
||||
if(HAS_BLOOD_DNA(src))
|
||||
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood")
|
||||
if(accessory_overlay)
|
||||
. += accessory_overlay
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
//CONTAINS: Suit fibers and Detective's Scanning Computer
|
||||
|
||||
/atom/proc/return_fingerprints()
|
||||
var/datum/component/forensics/D = GetComponent(/datum/component/forensics)
|
||||
if(D)
|
||||
. = D.fingerprints
|
||||
|
||||
/atom/proc/return_hiddenprints()
|
||||
var/datum/component/forensics/D = GetComponent(/datum/component/forensics)
|
||||
if(D)
|
||||
. = D.hiddenprints
|
||||
|
||||
/atom/proc/return_blood_DNA()
|
||||
var/datum/component/forensics/D = GetComponent(/datum/component/forensics)
|
||||
if(D)
|
||||
. = D.blood_DNA
|
||||
|
||||
/atom/proc/blood_DNA_length()
|
||||
var/datum/component/forensics/D = GetComponent(/datum/component/forensics)
|
||||
if(D)
|
||||
. = length(D.blood_DNA)
|
||||
|
||||
/atom/proc/return_fibers()
|
||||
var/datum/component/forensics/D = GetComponent(/datum/component/forensics)
|
||||
if(D)
|
||||
. = D.fibers
|
||||
|
||||
/atom/proc/add_fingerprint_list(list/fingerprints) //ASSOC LIST FINGERPRINT = FINGERPRINT
|
||||
if(length(fingerprints))
|
||||
. = AddComponent(/datum/component/forensics, fingerprints)
|
||||
|
||||
//Set ignoregloves to add prints irrespective of the mob having gloves on.
|
||||
/atom/proc/add_fingerprint(mob/M, ignoregloves = FALSE)
|
||||
if (QDELING(src))
|
||||
return
|
||||
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
|
||||
. = D?.add_fingerprint(M, ignoregloves)
|
||||
|
||||
/atom/proc/add_fiber_list(list/fibertext) //ASSOC LIST FIBERTEXT = FIBERTEXT
|
||||
if(length(fibertext))
|
||||
. = AddComponent(/datum/component/forensics, null, null, null, fibertext)
|
||||
|
||||
/atom/proc/add_fibers(mob/living/carbon/human/M)
|
||||
var/old = 0
|
||||
if(M.gloves && istype(M.gloves, /obj/item/clothing))
|
||||
var/obj/item/clothing/gloves/G = M.gloves
|
||||
old = length(G.return_blood_DNA())
|
||||
if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
|
||||
if(add_blood_DNA(G.return_blood_DNA()) && length(G.return_blood_DNA()) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
|
||||
G.transfer_blood--
|
||||
else if(M.blood_in_hands > 1)
|
||||
old = length(M.return_blood_DNA())
|
||||
if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
|
||||
M.blood_in_hands--
|
||||
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
|
||||
. = D.add_fibers(M)
|
||||
|
||||
/atom/proc/add_hiddenprint_list(list/hiddenprints) //NOTE: THIS IS FOR ADMINISTRATION FINGERPRINTS, YOU MUST CUSTOM SET THIS TO INCLUDE CKEY/REAL NAMES! CHECK FORENSICS.DM
|
||||
if(length(hiddenprints))
|
||||
. = AddComponent(/datum/component/forensics, null, hiddenprints)
|
||||
|
||||
/atom/proc/add_hiddenprint(mob/M)
|
||||
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
|
||||
. = D.add_hiddenprint(M)
|
||||
|
||||
/atom/proc/add_blood_DNA(list/dna) //ASSOC LIST DNA = BLOODTYPE
|
||||
return FALSE
|
||||
|
||||
/obj/add_blood_DNA(list/dna)
|
||||
. = ..()
|
||||
if(length(dna))
|
||||
. = AddComponent(/datum/component/forensics, null, null, dna)
|
||||
|
||||
/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
||||
. = ..()
|
||||
transfer_blood = rand(2, 4)
|
||||
|
||||
/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
||||
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
|
||||
if(!B)
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
|
||||
if(!QDELETED(B))
|
||||
B.add_blood_DNA(blood_dna) //give blood info to the blood decal.
|
||||
return TRUE //we bloodied the floor
|
||||
|
||||
/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
||||
if(wear_suit)
|
||||
wear_suit.add_blood_DNA(blood_dna)
|
||||
update_inv_wear_suit()
|
||||
else if(w_uniform)
|
||||
w_uniform.add_blood_DNA(blood_dna)
|
||||
update_inv_w_uniform()
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
G.add_blood_DNA(blood_dna)
|
||||
else if(length(blood_dna))
|
||||
AddComponent(/datum/component/forensics, null, null, blood_dna)
|
||||
blood_in_hands = rand(2, 4)
|
||||
update_inv_gloves() //handles bloody hands overlays and updating
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* Transfer all the fingerprints and hidden prints from [src] to [transfer_to].
|
||||
*/
|
||||
/atom/proc/transfer_fingerprints_to(atom/transfer_to)
|
||||
transfer_to.add_fingerprint_list(return_fingerprints())
|
||||
transfer_to.add_hiddenprint_list(return_hiddenprints())
|
||||
transfer_to.fingerprintslast = fingerprintslast
|
||||
|
||||
/*
|
||||
* Transfer all the fibers from [src] to [transfer_to].
|
||||
*/
|
||||
/atom/proc/transfer_fibers_to(atom/transfer_to)
|
||||
transfer_to.add_fiber_list(return_fibers())
|
||||
@@ -86,8 +86,8 @@
|
||||
|
||||
//Make our lists
|
||||
var/list/fingerprints = list()
|
||||
var/list/blood = A.return_blood_DNA()
|
||||
var/list/fibers = A.return_fibers()
|
||||
var/list/blood = GET_ATOM_BLOOD_DNA(A)
|
||||
var/list/fibers = GET_ATOM_FIBRES(A)
|
||||
var/list/reagents = list()
|
||||
|
||||
var/target_name = A.name
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
else if(!ismob(A))
|
||||
|
||||
fingerprints = A.return_fingerprints()
|
||||
fingerprints = GET_ATOM_FINGERPRINTS(A)
|
||||
|
||||
// Only get reagents from non-mobs.
|
||||
if(A.reagents && A.reagents.reagent_list.len)
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* Forensics datum
|
||||
*
|
||||
* Placed onto atoms, and contains:
|
||||
* * List of fingerprints on the atom
|
||||
* * List of hidden prints (used for admins)
|
||||
* * List of blood on the atom
|
||||
* * List of clothing fibers on the atom
|
||||
*/
|
||||
/datum/forensics
|
||||
/// Weakref to the parent owning this datum
|
||||
var/datum/weakref/parent
|
||||
/**
|
||||
* List of fingerprints on this atom
|
||||
*
|
||||
* Formatting:
|
||||
* * print = print
|
||||
*/
|
||||
var/list/fingerprints
|
||||
/**
|
||||
* List of hiddenprints on this atom
|
||||
*
|
||||
* Formatting:
|
||||
* * ckey = realname/gloves/ckey
|
||||
*/
|
||||
var/list/hiddenprints
|
||||
/**
|
||||
* List of blood dna on this atom
|
||||
*
|
||||
* Formatting:
|
||||
* * dna = bloodtype
|
||||
*/
|
||||
var/list/blood_DNA
|
||||
/**
|
||||
* List of clothing fibers on this atom
|
||||
*
|
||||
* Formatting:
|
||||
* * fiber = fiber
|
||||
*/
|
||||
var/list/fibers
|
||||
|
||||
/datum/forensics/New(atom/parent, fingerprints, hiddenprints, blood_DNA, fibers)
|
||||
if(!isatom(parent))
|
||||
stack_trace("We tried adding a forensics datum to something that isnt an atom. What the hell are you doing?")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act)
|
||||
|
||||
src.parent = WEAKREF(parent)
|
||||
src.fingerprints = fingerprints
|
||||
src.hiddenprints = hiddenprints
|
||||
src.blood_DNA = blood_DNA
|
||||
src.fibers = fibers
|
||||
check_blood()
|
||||
|
||||
/// Merges the given lists into the preexisting values
|
||||
/datum/forensics/proc/inherit_new(list/fingerprints, list/hiddenprints, list/blood_DNA, list/fibers) //Use of | and |= being different here is INTENTIONAL.
|
||||
if (fingerprints)
|
||||
src.fingerprints = LAZY_LISTS_OR(src.fingerprints, fingerprints)
|
||||
if (hiddenprints)
|
||||
src.hiddenprints = LAZY_LISTS_OR(src.hiddenprints, hiddenprints)
|
||||
if (blood_DNA)
|
||||
src.blood_DNA = LAZY_LISTS_OR(src.blood_DNA, blood_DNA)
|
||||
if (fibers)
|
||||
src.fibers = LAZY_LISTS_OR(src.fibers, fibers)
|
||||
check_blood()
|
||||
|
||||
/datum/forensics/Destroy(force, ...)
|
||||
var/atom/parent_atom = parent.resolve()
|
||||
if (!isnull(parent_atom))
|
||||
UnregisterSignal(parent_atom, list(COMSIG_COMPONENT_CLEAN_ACT))
|
||||
return ..()
|
||||
|
||||
/// Empties the fingerprints list
|
||||
/datum/forensics/proc/wipe_fingerprints()
|
||||
fingerprints = null
|
||||
return TRUE
|
||||
|
||||
/// Empties the blood_DNA list
|
||||
/datum/forensics/proc/wipe_blood_DNA()
|
||||
blood_DNA = null
|
||||
return TRUE
|
||||
|
||||
/// Empties the fibers list
|
||||
/datum/forensics/proc/wipe_fibers()
|
||||
fibers = null
|
||||
return TRUE
|
||||
|
||||
/// Handles cleaning up the various forensic types
|
||||
/datum/forensics/proc/clean_act(datum/source, clean_types)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(clean_types & CLEAN_TYPE_FINGERPRINTS)
|
||||
wipe_fingerprints()
|
||||
if(clean_types & CLEAN_TYPE_BLOOD)
|
||||
wipe_blood_DNA()
|
||||
if(clean_types & CLEAN_TYPE_FIBERS)
|
||||
wipe_fibers()
|
||||
|
||||
/// Adds the given list into fingerprints
|
||||
/datum/forensics/proc/add_fingerprint_list(list/fingerprints)
|
||||
if(!length(fingerprints))
|
||||
return
|
||||
LAZYINITLIST(src.fingerprints)
|
||||
for(var/fingerprint in fingerprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
|
||||
src.fingerprints[fingerprint] = fingerprint
|
||||
return TRUE
|
||||
|
||||
/// Adds a single fingerprint
|
||||
/datum/forensics/proc/add_fingerprint(mob/living/suspect, ignoregloves = FALSE)
|
||||
if(!isliving(suspect))
|
||||
if(!iscameramob(suspect))
|
||||
return
|
||||
if(isaicamera(suspect))
|
||||
var/mob/camera/ai_eye/ai_camera = suspect
|
||||
if(!ai_camera.ai)
|
||||
return
|
||||
suspect = ai_camera.ai
|
||||
add_hiddenprint(suspect)
|
||||
if(ishuman(suspect))
|
||||
var/mob/living/carbon/human/human_suspect = suspect
|
||||
add_fibers(human_suspect)
|
||||
var/obj/item/gloves = human_suspect.gloves
|
||||
if(gloves) //Check if the gloves (if any) hide fingerprints
|
||||
if(!(gloves.body_parts_covered & HANDS) || HAS_TRAIT(gloves, TRAIT_FINGERPRINT_PASSTHROUGH) || HAS_TRAIT(human_suspect, TRAIT_FINGERPRINT_PASSTHROUGH))
|
||||
ignoregloves = TRUE
|
||||
if(!ignoregloves)
|
||||
human_suspect.gloves.add_fingerprint(human_suspect, ignoregloves = TRUE) //ignoregloves = TRUE to avoid infinite loop.
|
||||
return
|
||||
var/full_print = md5(human_suspect.dna.unique_identity)
|
||||
LAZYSET(fingerprints, full_print, full_print)
|
||||
return TRUE
|
||||
|
||||
/// Adds the given list into fibers
|
||||
/datum/forensics/proc/add_fiber_list(list/fibers)
|
||||
if(!length(fibers))
|
||||
return
|
||||
LAZYINITLIST(src.fibers)
|
||||
for(var/fiber in fibers) //We use an associative list, make sure we don't just merge a non-associative list into ours.
|
||||
src.fibers[fiber] = fiber
|
||||
return TRUE
|
||||
|
||||
#define ITEM_FIBER_MULTIPLIER 1.2
|
||||
#define NON_ITEM_FIBER_MULTIPLIER 1
|
||||
|
||||
/// Adds a single fiber
|
||||
/datum/forensics/proc/add_fibers(mob/living/carbon/human/suspect)
|
||||
var/fibertext
|
||||
var/item_multiplier = isitem(src) ? ITEM_FIBER_MULTIPLIER : NON_ITEM_FIBER_MULTIPLIER
|
||||
if(suspect.wear_suit)
|
||||
fibertext = "Material from \a [suspect.wear_suit]."
|
||||
if(prob(10 * item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
if(!(suspect.wear_suit.body_parts_covered & CHEST))
|
||||
if(suspect.w_uniform)
|
||||
fibertext = "Fibers from \a [suspect.w_uniform]."
|
||||
if(prob(12 * item_multiplier) && !LAZYACCESS(fibers, fibertext)) //Wearing a suit means less of the uniform exposed.
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
if(!(suspect.wear_suit.body_parts_covered & HANDS))
|
||||
if(suspect.gloves)
|
||||
fibertext = "Material from a pair of [suspect.gloves.name]."
|
||||
if(prob(20 * item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
else if(suspect.w_uniform)
|
||||
fibertext = "Fibers from \a [suspect.w_uniform]."
|
||||
if(prob(15 * item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
if(suspect.gloves)
|
||||
fibertext = "Material from a pair of [suspect.gloves.name]."
|
||||
if(prob(20 * item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
else if(suspect.gloves)
|
||||
fibertext = "Material from a pair of [suspect.gloves.name]."
|
||||
if(prob(20 * item_multiplier) && !LAZYACCESS(fibers, fibertext))
|
||||
LAZYSET(fibers, fibertext, fibertext)
|
||||
return TRUE
|
||||
|
||||
#undef ITEM_FIBER_MULTIPLIER
|
||||
#undef NON_ITEM_FIBER_MULTIPLIER
|
||||
|
||||
/// Adds the given list into hiddenprints
|
||||
/datum/forensics/proc/add_hiddenprint_list(list/hiddenprints) //list(ckey = text)
|
||||
if(!length(hiddenprints))
|
||||
return
|
||||
LAZYINITLIST(src.hiddenprints)
|
||||
for(var/hidden_print in hiddenprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
|
||||
src.hiddenprints[hidden_print] = hiddenprints[hidden_print]
|
||||
return TRUE
|
||||
|
||||
/// Adds a single hiddenprint
|
||||
/datum/forensics/proc/add_hiddenprint(mob/suspect)
|
||||
if(!isliving(suspect))
|
||||
if(!iscameramob(suspect))
|
||||
return
|
||||
if(isaicamera(suspect))
|
||||
var/mob/camera/ai_eye/ai_camera = suspect
|
||||
if(!ai_camera.ai)
|
||||
return
|
||||
suspect = ai_camera.ai
|
||||
if(!suspect.key)
|
||||
return
|
||||
var/has_gloves = ""
|
||||
if(ishuman(suspect))
|
||||
var/mob/living/carbon/human/human_suspect = suspect
|
||||
if(human_suspect.gloves)
|
||||
has_gloves = "(gloves)"
|
||||
var/current_time = time_stamp()
|
||||
if(!LAZYACCESS(hiddenprints, suspect.key))
|
||||
LAZYSET(hiddenprints, suspect.key, "First: \[[current_time]\] \"[suspect.real_name]\"[has_gloves]. Ckey: [suspect.ckey]")
|
||||
else
|
||||
var/last_stamp_pos = findtext(LAZYACCESS(hiddenprints, suspect.key), "\nLast: ")
|
||||
if(last_stamp_pos)
|
||||
LAZYSET(hiddenprints, suspect.key, copytext(hiddenprints[suspect.key], 1, last_stamp_pos))
|
||||
hiddenprints[suspect.key] += "\nLast: \[[current_time]\] \"[suspect.real_name]\"[has_gloves]. Ckey: [suspect.ckey]" //made sure to be existing by if(!LAZYACCESS);else
|
||||
var/atom/parent_atom = parent.resolve()
|
||||
parent_atom.fingerprintslast = suspect.ckey
|
||||
return TRUE
|
||||
|
||||
/// Adds the given list into blood_DNA
|
||||
/datum/forensics/proc/add_blood_DNA(list/blood_DNA)
|
||||
if(!length(blood_DNA))
|
||||
return
|
||||
LAZYINITLIST(src.blood_DNA)
|
||||
for(var/gene in blood_DNA)
|
||||
src.blood_DNA[gene] = blood_DNA[gene]
|
||||
check_blood()
|
||||
return TRUE
|
||||
|
||||
/// Updates the blood displayed on parent
|
||||
/datum/forensics/proc/check_blood()
|
||||
if(!isitem(parent.resolve()))
|
||||
return
|
||||
if(!length(blood_DNA))
|
||||
return
|
||||
var/atom/parent_atom = parent.resolve()
|
||||
parent_atom.AddElement(/datum/element/decal/blood)
|
||||
@@ -0,0 +1,122 @@
|
||||
/// Adds a list of fingerprints to the atom
|
||||
/atom/proc/add_fingerprint_list(list/fingerprints_to_add) //ASSOC LIST FINGERPRINT = FINGERPRINT
|
||||
if (isnull(fingerprints_to_add))
|
||||
return
|
||||
if (forensics)
|
||||
forensics.inherit_new(fingerprints = fingerprints_to_add)
|
||||
else
|
||||
forensics = new(src, fingerprints = fingerprints_to_add)
|
||||
return TRUE
|
||||
|
||||
/// Adds a single fingerprint to the atom
|
||||
/atom/proc/add_fingerprint(mob/suspect, ignoregloves = FALSE) //Set ignoregloves to add prints irrespective of the mob having gloves on.
|
||||
if (QDELING(src))
|
||||
return
|
||||
if (isnull(forensics))
|
||||
forensics = new(src)
|
||||
forensics.add_fingerprint(suspect, ignoregloves)
|
||||
return TRUE
|
||||
|
||||
/// Add a list of fibers to the atom
|
||||
/atom/proc/add_fiber_list(list/fibers_to_add) //ASSOC LIST FIBERTEXT = FIBERTEXT
|
||||
if (isnull(fibers_to_add))
|
||||
return
|
||||
if (forensics)
|
||||
forensics.inherit_new(fibers = fibers_to_add)
|
||||
else
|
||||
forensics = new(src, fibers = fibers_to_add)
|
||||
return TRUE
|
||||
|
||||
/// Adds a single fiber to the atom
|
||||
/atom/proc/add_fibers(mob/living/carbon/human/suspect)
|
||||
var/old = 0
|
||||
if(suspect.gloves && istype(suspect.gloves, /obj/item/clothing))
|
||||
var/obj/item/clothing/gloves/suspect_gloves = suspect.gloves
|
||||
old = length(GET_ATOM_BLOOD_DNA(suspect_gloves))
|
||||
if(suspect_gloves.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
|
||||
if(add_blood_DNA(GET_ATOM_BLOOD_DNA(suspect_gloves)) && GET_ATOM_BLOOD_DNA_LENGTH(suspect_gloves) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
|
||||
suspect_gloves.transfer_blood -= 1
|
||||
else if(suspect.blood_in_hands > 1)
|
||||
old = length(GET_ATOM_BLOOD_DNA(suspect))
|
||||
if(add_blood_DNA(GET_ATOM_BLOOD_DNA(suspect)) && GET_ATOM_BLOOD_DNA_LENGTH(suspect) > old)
|
||||
suspect.blood_in_hands -= 1
|
||||
if (isnull(forensics))
|
||||
forensics = new(src)
|
||||
forensics.add_fibers(suspect)
|
||||
return TRUE
|
||||
|
||||
/// Adds a list of hiddenprints to the atom
|
||||
/atom/proc/add_hiddenprint_list(list/hiddenprints_to_add) //NOTE: THIS IS FOR ADMINISTRATION FINGERPRINTS, YOU MUST CUSTOM SET THIS TO INCLUDE CKEY/REAL NAMES! CHECK FORENSICS.DM
|
||||
if (isnull(hiddenprints_to_add))
|
||||
return
|
||||
if (forensics)
|
||||
forensics.inherit_new(hiddenprints = hiddenprints_to_add)
|
||||
else
|
||||
forensics = new(src, hiddenprints = hiddenprints_to_add)
|
||||
return TRUE
|
||||
|
||||
/// Adds a single hiddenprint to the atom
|
||||
/atom/proc/add_hiddenprint(mob/suspect)
|
||||
if (isnull(forensics))
|
||||
forensics = new(src)
|
||||
forensics.add_hiddenprint(suspect)
|
||||
return TRUE
|
||||
|
||||
/// Adds blood dna to the atom
|
||||
/atom/proc/add_blood_DNA(list/blood_DNA_to_add) //ASSOC LIST DNA = BLOODTYPE
|
||||
return FALSE
|
||||
|
||||
/obj/add_blood_DNA(list/blood_DNA_to_add)
|
||||
. = ..()
|
||||
if (isnull(blood_DNA_to_add))
|
||||
return .
|
||||
if (forensics)
|
||||
forensics.inherit_new(blood_DNA = blood_DNA_to_add)
|
||||
else
|
||||
forensics = new(src, blood_DNA = blood_DNA_to_add)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
||||
transfer_blood = rand(2, 4)
|
||||
return ..()
|
||||
|
||||
/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
||||
var/obj/effect/decal/cleanable/blood/splatter/blood_splatter = locate() in src
|
||||
if(!blood_splatter)
|
||||
blood_splatter = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
|
||||
if(!QDELETED(blood_splatter))
|
||||
blood_splatter.add_blood_DNA(blood_dna) //give blood info to the blood decal.
|
||||
return TRUE //we bloodied the floor
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/add_blood_DNA(list/blood_DNA_to_add, list/datum/disease/diseases)
|
||||
if(wear_suit)
|
||||
wear_suit.add_blood_DNA(blood_DNA_to_add)
|
||||
update_inv_wear_suit()
|
||||
else if(w_uniform)
|
||||
w_uniform.add_blood_DNA(blood_DNA_to_add)
|
||||
update_inv_w_uniform()
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/mob_gloves = gloves
|
||||
mob_gloves.add_blood_DNA(blood_DNA_to_add)
|
||||
else if(length(blood_DNA_to_add))
|
||||
if (isnull(forensics))
|
||||
forensics = new(src)
|
||||
forensics.inherit_new(blood_DNA = blood_DNA_to_add)
|
||||
blood_in_hands = rand(2, 4)
|
||||
update_inv_gloves()
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* Transfer all the fingerprints and hidden prints from [src] to [transfer_to].
|
||||
*/
|
||||
/atom/proc/transfer_fingerprints_to(atom/transfer_to)
|
||||
transfer_to.add_fingerprint_list(GET_ATOM_FINGERPRINTS(src))
|
||||
transfer_to.add_hiddenprint_list(GET_ATOM_HIDDENPRINTS(src))
|
||||
transfer_to.fingerprintslast = fingerprintslast
|
||||
|
||||
/*
|
||||
* Transfer all the fibers from [src] to [transfer_to].
|
||||
*/
|
||||
/atom/proc/transfer_fibers_to(atom/transfer_to)
|
||||
transfer_to.add_fiber_list(GET_ATOM_FIBRES(src))
|
||||
@@ -326,7 +326,7 @@
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = drop.return_blood_DNA() //we transfer the dna from the drip to the splatter
|
||||
temp_blood_DNA = GET_ATOM_BLOOD_DNA(drop) //we transfer the dna from the drip to the splatter
|
||||
qdel(drop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
drop = new(T, get_static_viruses())
|
||||
|
||||
@@ -1398,7 +1398,7 @@
|
||||
if(!isturf(loc))
|
||||
return
|
||||
var/obj/effect/decal/cleanable/blood/hitsplatter/our_splatter = new(loc)
|
||||
our_splatter.add_blood_DNA(return_blood_DNA())
|
||||
our_splatter.add_blood_DNA(GET_ATOM_BLOOD_DNA(src))
|
||||
our_splatter.blood_dna_info = get_blood_dna_list()
|
||||
var/turf/targ = get_ranged_target_turf(src, splatter_direction, splatter_strength)
|
||||
our_splatter.fly_towards(targ, splatter_strength)
|
||||
|
||||
@@ -46,11 +46,10 @@
|
||||
if(!(I.item_flags & ABSTRACT) && !(I.item_flags & EXAMINE_SKIP))
|
||||
. += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))]."
|
||||
|
||||
var/datum/component/forensics/FR = GetComponent(/datum/component/forensics)
|
||||
//gloves
|
||||
if(gloves && !(obscured & ITEM_SLOT_GLOVES) && !(gloves.item_flags & EXAMINE_SKIP))
|
||||
. += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands."
|
||||
else if(FR && length(FR.blood_DNA))
|
||||
else if(GET_ATOM_BLOOD_DNA_LENGTH(src))
|
||||
if(num_hands)
|
||||
. += span_warning("[t_He] [t_has] [num_hands > 1 ? "" : "a"] blood-stained hand[num_hands > 1 ? "s" : ""]!")
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@
|
||||
for(var/X in list(ITEM_SLOT_HEAD, ITEM_SLOT_MASK, ITEM_SLOT_ICLOTHING, ITEM_SLOT_OCLOTHING, ITEM_SLOT_FEET))
|
||||
|
||||
var/obj/item/I = L.get_item_by_slot(X)
|
||||
if(I && HAS_BLOOD_DNA(I))
|
||||
if(I && GET_ATOM_BLOOD_DNA_LENGTH(I))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@
|
||||
if(!last_move || isspaceturf(oldLoc)) //if we didn't sucessfully move, or if our old location was a spaceturf.
|
||||
return
|
||||
var/obj/effect/decal/cleanable/blood/tracks/B = new(oldLoc)
|
||||
B.add_blood_DNA(return_blood_DNA())
|
||||
B.add_blood_DNA(GET_ATOM_BLOOD_DNA(src))
|
||||
B.setDir(direct)
|
||||
bloodiness--
|
||||
|
||||
|
||||
+3
-2
@@ -290,6 +290,7 @@
|
||||
#include "code\__HELPERS\dna.dm"
|
||||
#include "code\__HELPERS\files.dm"
|
||||
#include "code\__HELPERS\filters.dm"
|
||||
#include "code\__HELPERS\forensics.dm"
|
||||
#include "code\__HELPERS\game.dm"
|
||||
#include "code\__HELPERS\global_lists.dm"
|
||||
#include "code\__HELPERS\guid.dm"
|
||||
@@ -724,7 +725,6 @@
|
||||
#include "code\datums\components\explodable.dm"
|
||||
#include "code\datums\components\faction_granter.dm"
|
||||
#include "code\datums\components\force_move.dm"
|
||||
#include "code\datums\components\forensics.dm"
|
||||
#include "code\datums\components\fov_handler.dm"
|
||||
#include "code\datums\components\fullauto.dm"
|
||||
#include "code\datums\components\gas_leaker.dm"
|
||||
@@ -2693,7 +2693,6 @@
|
||||
#include "code\modules\clothing\under\jobs\Plasmaman\engineering.dm"
|
||||
#include "code\modules\clothing\under\jobs\Plasmaman\medsci.dm"
|
||||
#include "code\modules\clothing\under\jobs\Plasmaman\security.dm"
|
||||
#include "code\modules\detectivework\detective_work.dm"
|
||||
#include "code\modules\detectivework\evidence.dm"
|
||||
#include "code\modules\detectivework\scanner.dm"
|
||||
#include "code\modules\discord\accountlink.dm"
|
||||
@@ -2860,6 +2859,8 @@
|
||||
#include "code\modules\food_and_drinks\restaurant\custom_order.dm"
|
||||
#include "code\modules\food_and_drinks\restaurant\generic_venues.dm"
|
||||
#include "code\modules\food_and_drinks\restaurant\customers\_customer.dm"
|
||||
#include "code\modules\forensics\_forensics.dm"
|
||||
#include "code\modules\forensics\forensics_helpers.dm"
|
||||
#include "code\modules\holiday\easter.dm"
|
||||
#include "code\modules\holiday\foreign_calendar.dm"
|
||||
#include "code\modules\holiday\holidays.dm"
|
||||
|
||||
Reference in New Issue
Block a user