[READY]Component Forensics and Item Blood OverlayS!

This commit is contained in:
oranges
2017-12-28 10:18:11 +13:00
committed by CitadelStationBot
parent a034383e15
commit 269208f687
57 changed files with 523 additions and 362 deletions
+24 -104
View File
@@ -5,10 +5,6 @@
var/flags_1 = 0
var/flags_2 = 0
var/list/fingerprints
var/list/fingerprintshidden
var/list/blood_DNA
var/container_type = NONE
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
var/datum/reagents/reagents = null
@@ -232,21 +228,22 @@
/atom/proc/in_contents_of(container)//can take class or object instance as argument
if(ispath(container))
if(istype(src.loc, container))
return 1
return TRUE
else if(src in container)
return 1
return TRUE
return FALSE
/atom/proc/get_examine_name(mob/user)
. = "\a [src]"
var/list/override = list(gender == PLURAL? "some" : "a" , " ", "[name]")
if(SendSignal(COMSIG_ATOM_GET_EXAMINE_NAME, user, override) & COMPONENT_EXNAME_CHANGED)
. = override.Join("")
/atom/proc/get_examine_string(mob/user, thats = FALSE)
. = "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]"
/atom/proc/examine(mob/user)
//This reformat names to get a/an properly working on item descriptions when they are bloody
var/f_name = "\a [src]."
if(src.blood_DNA && !istype(src, /obj/effect/decal))
if(gender == PLURAL)
f_name = "some "
else
f_name = "a "
f_name += "<span class='danger'>blood-stained</span> [name]!"
to_chat(user, "[icon2html(src, user)] That's [f_name]")
to_chat(user, get_examine_string(user, TRUE))
if(desc)
to_chat(user, desc)
@@ -303,11 +300,6 @@
if(AM && isturf(AM.loc))
step(AM, turn(AM.dir, 180))
GLOBAL_LIST_EMPTY(blood_splatter_icons)
/atom/proc/blood_splatter_index()
return "[REF(initial(icon))]-[initial(icon_state)]"
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
/mob/living/proc/get_blood_dna_list()
if(get_blood_id() != "blood")
@@ -332,100 +324,28 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
// Returns 0 if we have that blood already
var/new_blood_dna = L.get_blood_dna_list()
if(!new_blood_dna)
return 0
if(!blood_DNA) //if our list of DNA doesn't exist yet, initialise it.
blood_DNA = list()
var/old_length = blood_DNA.len
blood_DNA |= new_blood_dna
if(blood_DNA.len == old_length)
return 0
return 1
//to add blood dna info to the object's blood_DNA list
/atom/proc/transfer_blood_dna(list/blood_dna)
if(!blood_DNA)
blood_DNA = list()
var/old_length = blood_DNA.len
blood_DNA |= blood_dna
if(blood_DNA.len > old_length)
return 1//some new blood DNA was added
return FALSE
var/old_length = blood_DNA_length()
add_blood_DNA(new_blood_dna)
if(blood_DNA_length() == old_length)
return FALSE
return TRUE
//to add blood from a mob onto something, and transfer their dna info
/atom/proc/add_mob_blood(mob/living/M)
var/list/blood_dna = M.get_blood_dna_list()
if(!blood_dna)
return 0
return add_blood(blood_dna)
//to add blood onto something, with blood dna info to include.
/atom/proc/add_blood(list/blood_dna)
return 0
/obj/add_blood(list/blood_dna)
return transfer_blood_dna(blood_dna)
/obj/item/add_blood(list/blood_dna)
var/blood_count = !blood_DNA ? 0 : blood_DNA.len
if(!..())
return 0
if(!blood_count)//apply the blood-splatter overlay if it isn't already in there
add_blood_overlay()
return 1 //we applied blood to the item
/obj/item/proc/add_blood_overlay()
if(initial(icon) && initial(icon_state))
//try to find a pre-processed blood-splatter. otherwise, make a new one
var/index = blood_splatter_index()
var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index]
if(!blood_splatter_icon)
blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
blood_splatter_icon = fcopy_rsc(blood_splatter_icon)
GLOB.blood_splatter_icons[index] = blood_splatter_icon
add_overlay(blood_splatter_icon)
/obj/item/clothing/gloves/add_blood(list/blood_dna)
. = ..()
transfer_blood = rand(2, 4)
/turf/add_blood(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)
B.transfer_blood_dna(blood_dna) //give blood info to the blood decal.
return 1 //we bloodied the floor
/mob/living/carbon/human/add_blood(list/blood_dna)
if(wear_suit)
wear_suit.add_blood(blood_dna)
update_inv_wear_suit()
else if(w_uniform)
w_uniform.add_blood(blood_dna)
update_inv_w_uniform()
if(gloves)
var/obj/item/clothing/gloves/G = gloves
G.add_blood(blood_dna)
else
transfer_blood_dna(blood_dna)
bloody_hands = rand(2, 4)
update_inv_gloves() //handles bloody hands overlays and updating
return 1
/atom/proc/clean_blood()
if(islist(blood_DNA))
blood_DNA = null
return 1
return FALSE
return add_blood_DNA(blood_dna)
/atom/proc/wash_cream()
return 1
return TRUE
/atom/proc/isinspace()
if(isspaceturf(get_turf(src)))
return 1
return TRUE
else
return 0
return FALSE
/atom/proc/handle_fall()
return
@@ -67,10 +67,7 @@
//Left hand items
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
if(I.blood_DNA)
msg += "<span class='warning'>It is holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
else
msg += "It is holding [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
msg += "It is holding [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Braindead
if(!client && stat != DEAD)
+12 -9
View File
@@ -213,7 +213,7 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
var/mob/living/carbon/human/target = null
var/list/mob/living/carbon/human/possible = list()
var/obj/item/linked_item = null
var/obj/item/voodoo_link = null
var/cooldown_time = 30 //3s
var/cooldown = 0
max_integrity = 10
@@ -237,10 +237,10 @@
cooldown = world.time +cooldown_time
return
if(!linked_item)
if(!voodoo_link)
if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL)
if (user.transferItemToLoc(I,src))
linked_item = I
voodoo_link = I
to_chat(user, "You attach [I] to the doll.")
update_targets()
@@ -255,11 +255,11 @@
return
if(user.zone_selected == "chest")
if(linked_item)
if(voodoo_link)
target = null
linked_item.forceMove(drop_location())
to_chat(user, "<span class='notice'>You remove the [linked_item] from the doll.</span>")
linked_item = null
voodoo_link.forceMove(drop_location())
to_chat(user, "<span class='notice'>You remove the [voodoo_link] from the doll.</span>")
voodoo_link = null
update_targets()
return
@@ -291,10 +291,13 @@
/obj/item/voodoo/proc/update_targets()
possible = list()
if(!linked_item)
if(!voodoo_link)
return
var/list/prints = voodoo_link.return_fingerprints()
if(!length(prints))
return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(md5(H.dna.uni_identity) in linked_item.fingerprints)
if(prints[md5(H.dna.uni_identity)])
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
@@ -121,7 +121,7 @@
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = 3
icon_state = "3"
var/obj/item/stack/sheet/glass/G = new (drop_location(), 2)
var/obj/item/stack/sheet/glass/G = new(drop_location(), 2)
G.add_fingerprint(user)
return
if(istype(P, /obj/item/screwdriver))
@@ -154,11 +154,8 @@
to_chat(usr, "<span class='warning'>There's not enough room to build that here!</span>")
qdel(C)
return
if(href_list["dir"])
C.setDir(text2num(href_list["dir"]))
C.add_fingerprint(usr)
C.update_icon()
wait = world.time + 15
+1 -2
View File
@@ -236,8 +236,7 @@
visible_message("<span class='warning'>[src]'s door slides open, barraging you with the nauseating smell of charred flesh.</span>")
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
I.clean_blood()
I.fingerprints = list()
I.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
var/datum/component/radioactive/contamination = I.GetComponent(/datum/component/radioactive)
if(contamination)
qdel(contamination)
+8 -7
View File
@@ -12,6 +12,10 @@
var/obj/item/color_source
var/max_wash_capacity = 5
/obj/machinery/washing_machine/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
/obj/machinery/washing_machine/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click it to start a wash cycle.</span>")
@@ -36,20 +40,17 @@
busy = TRUE
update_icon()
sleep(200)
wash_cycle()
addtimer(CALLBACK(src, .proc/wash_cycle), 200)
/obj/machinery/washing_machine/clean_blood()
..()
/obj/machinery/washing_machine/proc/clean_blood()
if(!busy)
bloody_mess = 0
bloody_mess = FALSE
update_icon()
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
AM.clean_blood()
AM.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
AM.machine_wash(src)
busy = FALSE
@@ -79,14 +79,11 @@
add_blood = bloodiness
bloodiness -= add_blood
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
if(blood_DNA && blood_DNA.len)
S.add_blood(blood_DNA)
S.add_blood_DNA(return_blood_DNA())
S.blood_state = blood_state
update_icon()
H.update_inv_shoes()
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
return bloodiness
@@ -6,10 +6,13 @@
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
blood_DNA = list("UNKNOWN DNA" = "X*")
bloodiness = MAX_SHOE_BLOODINESS
blood_state = BLOOD_STATE_XENO
/obj/effect/decal/cleanable/xenoblood/Initialize()
. = ..()
add_blood_DNA(list("UNKNOWN DNA" = "X*"))
/obj/effect/decal/cleanable/xenoblood/xsplatter
random_icon_states = list("xgibbl1", "xgibbl2", "xgibbl3", "xgibbl4", "xgibbl5")
@@ -62,4 +65,7 @@
/obj/effect/decal/cleanable/blood/xtracks
icon_state = "xtracks"
random_icon_states = null
blood_DNA = list("UNKNOWN DNA" = "X*")
/obj/effect/decal/cleanable/blood/xtracks/Initialize()
. = ..()
add_blood_DNA(list("Unknown DNA" = "X*"))
@@ -4,13 +4,11 @@
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_DNA = list()
blood_state = BLOOD_STATE_HUMAN
bloodiness = MAX_SHOE_BLOODINESS
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
if (C.blood_DNA)
blood_DNA |= C.blood_DNA.Copy()
add_blood_DNA(C.return_blood_DNA())
..()
/obj/effect/decal/cleanable/blood/old
@@ -21,7 +19,7 @@
/obj/effect/decal/cleanable/blood/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
icon_state += "-old" //This IS necessary because the parent /blood type uses icon randomization.
blood_DNA["Non-human DNA"] = "A+"
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/blood/splatter
random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
@@ -37,11 +35,9 @@
desc = "Your instincts say you shouldn't be following these."
random_icon_states = null
var/list/existing_dirs = list()
blood_DNA = list()
/obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in()
return 1
return TRUE
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
@@ -100,8 +96,7 @@
. = ..()
setDir(pick(1,2,4,8))
icon_state += "-old"
blood_DNA["Non-human DNA"] = "A+"
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
@@ -111,9 +106,8 @@
bloodiness = 0
var/drips = 1
/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
return 1
return TRUE
//BLOODY FOOTPRINTS
@@ -151,7 +145,7 @@
if (!(exited_dirs & H.dir))
exited_dirs |= H.dir
update_icon()
/obj/effect/decal/cleanable/blood/footprints/update_icon()
cut_overlays()
@@ -30,9 +30,9 @@
digester.stomach_contents += gib
if(MobDNA)
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type
else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
gib.blood_DNA["Non-human DNA"] = "A+"
gib.add_blood_DNA(list("Non-human DNA" = "A+"))
var/list/directions = gibdirections[i]
if(isturf(loc))
if(directions.len)
-14
View File
@@ -553,20 +553,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.become_blind(EYE_DAMAGE)
to_chat(M, "<span class='danger'>You go blind!</span>")
/obj/item/clean_blood()
. = ..()
if(.)
if(initial(icon) && initial(icon_state))
var/index = blood_splatter_index()
var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index]
if(blood_splatter_icon)
cut_overlay(blood_splatter_icon)
/obj/item/clothing/gloves/clean_blood()
. = ..()
if(.)
transfer_blood = 0
/obj/item/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
+1 -1
View File
@@ -86,7 +86,7 @@
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
target.clean_blood()
target.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
target.wash_cream()
return
@@ -139,8 +139,8 @@
else
icon_state = initial(icon_state)
/obj/item/device/radio/intercom/add_blood(list/blood_dna)
return 0
/obj/item/device/radio/intercom/add_blood_DNA(list/blood_dna)
return FALSE
//Created through the autolathe or through deconstructing intercoms. Can be applied to wall to make a new intercom on it!
/obj/item/wallframe/intercom
+2 -2
View File
@@ -20,8 +20,8 @@
user.visible_message("<span class='suicide'>[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku!</span>")
return (BRUTELOSS|FIRELOSS)
/obj/item/melee/transforming/energy/add_blood(list/blood_dna)
return 0
/obj/item/melee/transforming/energy/add_blood_DNA(list/blood_dna)
return FALSE
/obj/item/melee/transforming/energy/is_sharp()
return active * sharpness
+2 -2
View File
@@ -284,8 +284,8 @@
T.ChangeTurf(T.baseturf)
T.CalculateAdjacentTurfs()
/obj/item/melee/supermatter_sword/add_blood(list/blood_dna)
return 0
/obj/item/melee/supermatter_sword/add_blood_DNA(list/blood_dna)
return FALSE
/obj/item/melee/curator_whip
name = "curator's whip"
-1
View File
@@ -23,7 +23,6 @@
/obj/item/mop/proc/clean(turf/A)
if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1))
A.clean_blood()
A.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
for(var/obj/effect/O in A)
if(is_cleanable(O))
+4 -4
View File
@@ -336,10 +336,10 @@
else
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj)
blood_DNA = from.blood_DNA
fingerprints = from.fingerprints
fingerprintshidden = from.fingerprintshidden
/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())
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
+1 -1
View File
@@ -213,5 +213,5 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
else
return ..(M,user,heal_mode = FALSE)
/obj/item/storage/book/bible/syndicate/add_blood(list/blood_dna)
/obj/item/storage/book/bible/syndicate/add_blood_DNA(list/blood_dna)
return FALSE
+1 -1
View File
@@ -293,7 +293,7 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
clean_blood()//blood overlays get weird otherwise, because the sprite changes.
SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
+6 -9
View File
@@ -296,8 +296,7 @@
/obj/machinery/shower/proc/wash_obj(obj/O)
O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
. = O.clean_blood()
. = O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
@@ -310,7 +309,6 @@
var/turf/tile = loc
tile.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
tile.clean_blood()
for(var/obj/effect/E in tile)
if(is_cleanable(E))
qdel(E)
@@ -361,7 +359,7 @@
else if(H.w_uniform && wash_obj(H.w_uniform))
H.update_inv_w_uniform()
if(washgloves)
H.clean_blood()
H.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(H.shoes && washshoes && wash_obj(H.shoes))
H.update_inv_shoes()
if(H.wear_mask && washmask && wash_obj(H.wear_mask))
@@ -378,9 +376,9 @@
else
if(M.wear_mask && wash_obj(M.wear_mask))
M.update_inv_wear_mask(0)
M.clean_blood()
M.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else
L.clean_blood()
L.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
@@ -473,8 +471,7 @@
H.regenerate_icons()
user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
else
user.clean_blood()
user.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
@@ -530,7 +527,7 @@
busy = FALSE
return 1
busy = FALSE
O.clean_blood()
O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
+1 -1
View File
@@ -173,7 +173,7 @@
for(var/mob/living/simple_animal/slime/M in src)
M.apply_water()
clean_blood()
SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/O in src)
if(is_cleanable(O))
qdel(O)