diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 090727d845..27991133c7 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -171,12 +171,7 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) #define BLOOD_LOSS_IN_SPREAD 20 //Bloody shoe blood states -#define HUMANIZED_BLOOD "A+" -#define LIZARDIZED_BLOOD "L" -#define SLIMEIZED_BLOOD "GEL" -#define OILIZED_BLOOD "HR" -#define XENOIZED_BLOOD "X*" -#define SYNTHETICIZED_BLOOD "SY" +#define BLOOD_STATE_BLOOD "blood" #define BLOOD_STATE_OIL "oil" #define BLOOD_STATE_NOT_BLOODY "no blood whatsoever" #define BLOOD_AMOUNT_PER_DECAL 20 diff --git a/code/datums/components/decals/blood.dm b/code/datums/components/decals/blood.dm index b615b05280..98e92ce710 100644 --- a/code/datums/components/decals/blood.dm +++ b/code/datums/components/decals/blood.dm @@ -15,21 +15,21 @@ _icon_state = "itemblood" var/icon = initial(I.icon) var/icon_state = initial(I.icon_state) + var/color = initial(I.blood_DNA_to_color(I.blood_mix_types)) if(!icon || !icon_state) // It's something which takes on the look of other items, probably icon = I.icon icon_state = I.icon_state var/static/list/blood_splatter_appearances = list() //try to find a pre-processed blood-splatter. otherwise, make a new one - var/index = "[REF(icon)]-[icon_state]" + var/index = "[REF(icon)]-[icon_state]-[color]" pic = blood_splatter_appearances[index] if(!pic) var/icon/blood_splatter_icon = icon(initial(I.icon), initial(I.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(_icon, _icon_state), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant - GET_COMPONENT(D, /datum/component/forensics) - blood_splatter_icon.Blend(D.blood_DNA_to_color(), ICON_MULTIPLY) + blood_splatter_icon.color = I.blood_DNA_to_color(I.blood_mix_types) //Colors it based upon blood color mix blood_splatter_appearances[index] = pic return TRUE diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm index c93981f0df..29aaa9bf02 100644 --- a/code/datums/components/forensics.dm +++ b/code/datums/components/forensics.dm @@ -4,25 +4,26 @@ var/list/hiddenprints //assoc ckey = realname/gloves/ckey var/list/blood_DNA //assoc dna = bloodtype var/list/fibers //assoc print = print + var/list/blood_mix_types // data("[blood_type]" = sting list /datum/component/forensics/InheritComponent(datum/component/forensics/F, original) //Use of | and |= being different here is INTENTIONAL. fingerprints = fingerprints | F.fingerprints hiddenprints = hiddenprints | F.hiddenprints blood_DNA = blood_DNA | F.blood_DNA fibers = fibers | F.fibers + blood_mix_types = blood_mix_types | F.blood_mix_types check_blood() - blood_DNA_to_color() return ..() -/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers) +/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers, new_blood_mix_types) if(!isatom(parent)) return COMPONENT_INCOMPATIBLE fingerprints = new_fingerprints hiddenprints = new_hiddenprints blood_DNA = new_blood_DNA fibers = new_fibers + blood_mix_types = new_blood_mix_types check_blood() - blood_DNA_to_color() RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act) /datum/component/forensics/proc/wipe_fingerprints() @@ -34,6 +35,7 @@ /datum/component/forensics/proc/wipe_blood_DNA() blood_DNA = null + blood_mix_types = null return TRUE /datum/component/forensics/proc/wipe_fibers() @@ -149,35 +151,61 @@ for(var/i in dna) blood_DNA[i] = dna[i] check_blood() - blood_DNA_to_color() return TRUE /datum/component/forensics/proc/check_blood() - if(!isitem(parent)) + if(!isitem(parent) || !ismob(parent)) return if(!length(blood_DNA)) return -/datum/component/forensics/proc/blood_DNA_to_color() - var/list/colors = list()//first we make a list of all bloodtypes present - for(var/bloop in blood_DNA) - if(colors[blood_DNA[bloop]]) - colors[blood_DNA[bloop]]++ +/datum/component/forensics/proc/add_blood_list_check(list/_blood_mix_types) + if(!length(_blood_mix_types)) + return + LAZYINITLIST(blood_mix_types) + for(var/i in _blood_mix_types) //We use an associative list, because all the other cool kids are doing it + blood_mix_types[i] = i + return TRUE + +/datum/component/forensics/proc/blood_list_checks(Atom/A, var/blood_type) //This is a messy attempt at trying to reduce lists of items and mobs with blood colors on them + if(blood_type in GLOB.regular_bloods) + blood_type = "A+" //generic so we don't have 8 different types of human blood + if(is_cleanable(src)) + var/obj/effect/decal/cleanable/CL = src + if(blood_type in CL.blood_mix_types) + return else - colors[blood_DNA[bloop]] = 1 + LAZYSET(blood_type,CL.blood_mix_types, CL.blood_mix_types) + CL.blood_color = blood_DNA_to_color(CL.blood_mix_types) + else if(isitem(src)) + var/obj/item/I = src + if(blood_type in I.blood_mix_types) + return + else + LAZYSET(blood_type,I.blood_mix_types, I.blood_mix_types) + I.blood_color = blood_DNA_to_color(I.blood_mix_types) + else if(iscarbon(src)) + var/mob/living/carbon/C = src + if(blood_type in C.blood_mix_types) + return + else + LAZYSET(blood_type,C.blood_mix_types, C.blood_mix_types) + C.blood_color = blood_DNA_to_color(C.blood_mix_types) + return TRUE - var/final_rgb = "#940000" - - if(colors.len) +/datum/component/forensics/proc/blood_DNA_to_color(list/bloods) + var/final_rgb = "#940000" //We default to red just in case + if(bloods.len) var/sum = 0 //this is all shitcode, but it works; trust me - final_rgb = bloodtype_to_color(colors[1]) - sum = colors[colors[1]] - if(colors.len > 1) + final_rgb = bloodtype_to_color(bloods[1]) + sum = bloods[bloods[1]] + if(bloods.len > 1) var/i = 2 - while(i <= colors.len) - var/tmp = colors[colors[i]] - final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum)) + while(i <= bloods.len) + var/tmp = bloods[bloods[i]] + final_rgb = BlendRGB(final_rgb, bloodtype_to_color(bloods[i]), tmp/(tmp+sum)) sum += tmp i++ - + else + final_rgb = BlendRGB(final_rgb, bloodtype_to_color(bloods)) return final_rgb diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c6ae093ab5..0ba8d7411b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -324,26 +324,16 @@ return list("ANIMAL DNA" = "Y-") /mob/living/carbon/get_blood_dna_list() - to_chat(world, "carbon's get_blood_dna_list called by [src]") var/blood_id = get_blood_id() - to_chat(world, "We got [blood_id] for a return") for(var/B in GLOB.blood_id_types) - to_chat(world, "checking blood_id_types") var/list/bluhduh = typecacheof(B) - to_chat(world, "We bluhduh now, let's compare with [blood_id] now") if(!blood_id in bluhduh) - to_chat(world, "[src] apparently doesn't have a valid blood type of blood, we're returning null due to [bluhduh]") return - to_chat(world, "[src] has an approved type of blood.") var/list/blood_dna = list() - to_chat(world, "blood_dna list made.") if(dna) - to_chat(world, "[src] has dna, we know the bloodtype to be [dna.blood_type].") blood_dna[dna.unique_enzymes] = dna.blood_type else - to_chat(world, "[src] doesn't have dna I guess.") blood_dna["UNKNOWN DNA"] = "X*" - to_chat(world, "blood_dna is [blood_dna]") return blood_dna /mob/living/carbon/alien/get_blood_dna_list() @@ -368,77 +358,6 @@ return FALSE return add_blood_DNA(blood_dna) -//to add blood onto something, with blood dna info to include. -/atom/proc/add_blood(list/blood_dna) - return FALSE - -/obj/item/add_blood(list/blood_dna) - if(!..()) - return FALSE - add_blood_overlay() - return TRUE //we applied blood to the item - -/obj/item/proc/add_blood_overlay() - GET_COMPONENT(D, /datum/component/forensics) - if(!D.blood_DNA.len) - return - if(initial(icon) && initial(icon_state)) - 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.Blend(blood_DNA_to_color(), ICON_MULTIPLY) - add_overlay(blood_splatter_icon) - -/atom/proc/blood_list_checks(Atom/A, var/blood_type, var/amount) //This is a messy attempt at trying to reduce lists of items and mobs with blood on them - if(blood_type in GLOB.regular_bloods) - blood_type = "A+" //generic so we don't have 8 different types of human blood - - if(is_cleanable(A) - var/obj/effect/decal/cleanable/CL = A - if(blood_type in CL.bloodmeme) - return - else - CL.bloodmeme += blood_type - - if(isitem(A)) - var/obj/item/I = A - if(blood_type in CL.bloodmeme) - return - else - CL.bloodmeme += blood_type - - if(iscarbon(A)) - var/mob/living/carbon/C = A - if(blood_type in C.bloodmeme) - return - else - C.bloodmeme += blood_type - - -/atom/proc/blood_DNA_to_color(list/bloods) - var/list/colors = list()//first we make a list of all bloodtypes present - for(var/bloop in bloods) - if(colors[bloods[bloop]]) - colors[bloods[bloop]]++ - else - colors[bloods[bloop]] = 1 - - var/final_rgb = "#940000" - - if(colors.len) - var/sum = 0 //this is all shitcode, but it works; trust me - final_rgb = bloodtype_to_color(colors[1]) - sum = colors[colors[1]] - if(colors.len > 1) - var/i = 2 - while(i <= colors.len) - var/tmp = colors[colors[i]] - final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum)) - sum += tmp - i++ - - return final_rgb - /atom/proc/wash_cream() return TRUE diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 0c767dd1ae..2059b5f57f 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -5,6 +5,7 @@ var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one? + var/blood_color = BLOOD_COLOR_HUMAN /obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases) . = ..() @@ -72,37 +73,50 @@ ..() if(ishuman(O)) var/mob/living/carbon/human/H = O - if(H.shoes && blood_state && bloodiness && !H.has_trait(TRAIT_LIGHT_STEP)) + if(H.shoes && blood_state && bloodiness && (!H.has_trait(TRAIT_LIGHT_STEP) || !H.mind.assigned_role == "Detective")) var/obj/item/clothing/shoes/S = H.shoes for(var/datum/reagent/R in reagents.reagent_list) // Get blood data from the blood reagent. if(istype(R, /datum/reagent/blood)) - if(R.data) - var/blood_type_meme = R.data["blood_type"] - color = bloodtype_to_color(blood_type_meme) //Color the blood with our dna stuff - if(blood_type_meme) - S.last_bloodtype = blood_type_meme + if(R.data["blood_type"]) + S.blood_list_checks(src, R.data["blood_type"]) + else if(istype(R, /datum/reagent/liquidgibs)) + if(R.data["blood_type"]) + S.blood_list_checks(src, R.data["blood_type"]) var/add_blood = 0 if(bloodiness >= BLOOD_GAIN_PER_STEP) add_blood = BLOOD_GAIN_PER_STEP else add_blood = bloodiness bloodiness -= add_blood - S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood) + S.blood_smear[blood_state] = min(MAX_SHOE_BLOODINESS,S.blood_smear[blood_state]+add_blood) S.add_blood_DNA(return_blood_DNA()) S.blood_state = blood_state update_icon() H.update_inv_shoes() - else if(H && blood_state && bloodiness && !H.has_trait(TRAIT_LIGHT_STEP)) + else if(H.bloodiness && blood_state && bloodiness && (!H.has_trait(TRAIT_LIGHT_STEP) || !H.mind.assigned_role == "Detective")) for(var/datum/reagent/R in reagents.reagent_list) // Get blood data from the blood reagent. if(istype(R, /datum/reagent/blood)) if(R.data["blood_type"]) - var/blood_type_meme = R.data["blood_type"] - color = bloodtype_to_color(blood_type_meme) //Color the blood with our dna stuff - if(blood_type_meme) - H.last_bloodtype = blood_type_meme + H.blood_list_checks(src, R.data["blood_type"]) + else if(istype(R, /datum/reagent/liquidgibs)) + if(R.data["blood_type"]) + H.blood_list_checks(src, R.data["blood_type"]) + var/add_blood = 0 + if(H.bloodiness >= BLOOD_GAIN_PER_STEP) + add_blood = BLOOD_GAIN_PER_STEP + else + add_blood = bloodiness + bloodiness -= add_blood + H.blood_smear[blood_state] = min(MAX_SHOE_BLOODINESS,H.blood_smear[blood_state]+add_blood) + H.add_blood_DNA(return_blood_DNA()) + H.blood_state = blood_state + update_icon() + + else + color = blood_DNA_to_color() var/add_blood = 0 if(bloodiness >= BLOOD_GAIN_PER_STEP) add_blood = BLOOD_GAIN_PER_STEP diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index 93bde588ee..52168d4e69 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -35,8 +35,7 @@ if(infective) diseases = infective.diseases var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases) - splat.color = color - splat.bloodmeme = bloodmeme + splat.update_icon() if(!step_to(src, get_step(src, direction), 0)) break diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm index 81d3e43c03..5e7b470be8 100644 --- a/code/game/objects/effects/decals/cleanable/gibs.dm +++ b/code/game/objects/effects/decals/cleanable/gibs.dm @@ -6,11 +6,12 @@ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") mergeable_decal = FALSE var/gib_overlay = FALSE + var/slimy_gibs = FALSE /obj/effect/decal/cleanable/blood/gibs/proc/guts() if(gib_overlay) var/mutable_appearance/gibz = mutable_appearance(icon, icon_state + "-overlay") - if(bloodmeme != "GEL") + if(!slimy_gibs) gibz.appearance_flags = RESET_COLOR add_overlay(gibz) @@ -19,7 +20,10 @@ /obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L) if(istype(L) && has_gravity(loc)) - playsound(loc, 'sound/effects/gib_step.ogg', L.has_trait(TRAIT_LIGHT_STEP) ? 20 : 50, 1) + if(L.mind.assigned_role == "Detective") //Gumshoe perks yo + playsound(loc, 'sound/effects/gib_step.ogg', 10, 1) + else + playsound(loc, 'sound/effects/gib_step.ogg', L.has_trait(TRAIT_LIGHT_STEP) ? 20 : 50, 1) . = ..() /obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions) @@ -33,8 +37,7 @@ if(infective) diseases = infective.diseases var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases) - splat.color = color - splat.bloodmeme = bloodmeme + splat.update_icon() if(!step_to(src, get_step(src, direction), 0)) break @@ -129,26 +132,32 @@ /obj/effect/decal/cleanable/blood/gibs/slime/up random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1") gib_overlay = TRUE + slimy_gibs = TRUE /obj/effect/decal/cleanable/blood/gibs/slime/down random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1") gib_overlay = TRUE + slimy_gibs = TRUE /obj/effect/decal/cleanable/blood/gibs/slime/body random_icon_states = list("gibhead", "gibtorso") gib_overlay = TRUE + slimy_gibs = TRUE /obj/effect/decal/cleanable/blood/gibs/slime/torso random_icon_states = list("gibtorso") gib_overlay = TRUE + slimy_gibs = TRUE /obj/effect/decal/cleanable/blood/gibs/slime/limb random_icon_states = list("gibleg", "gibarm") gib_overlay = TRUE + slimy_gibs = TRUE /obj/effect/decal/cleanable/blood/gibs/slime/core random_icon_states = list("gibmid1", "gibmid2", "gibmid3") gib_overlay = TRUE + slimy_gibs = TRUE /obj/effect/decal/cleanable/blood/gibs/synth desc = "They look sludgy and disgusting." diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 92cf77ab2f..05c8a0c44f 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -7,22 +7,20 @@ blood_state = BLOOD_STATE_BLOOD color = BLOOD_COLOR_HUMAN bloodiness = BLOOD_AMOUNT_PER_DECAL - var/list/bloodmeme = "" var/data = "" /obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) if(!data) C.data = add_blood_DNA(return_blood_DNA()) - if (bloodiness) - if (C.bloodiness < MAX_SHOE_BLOODINESS) + if(bloodiness) + if(C.bloodiness < MAX_SHOE_BLOODINESS) C.bloodiness += bloodiness - if(!bloodmeme) - C.bloodmeme = add_blood_DNA(return_blood_DNA()) update_icon() return ..() -//obj/effect/decal/cleanable/blood/add_blood_DNA(list/blood_dna) -// return TRUE +obj/effect/decal/cleanable/blood/add_blood_DNA(list/blood_dna) + blood_list_checks(src, data["blood_type"]) + return TRUE /obj/effect/decal/cleanable/blood/transfer_mob_blood_dna() . = ..() @@ -33,14 +31,12 @@ // Get blood data from the blood reagent. if(istype(R, /datum/reagent/blood)) if(R.data["blood_type"]) - bloodmeme = R.data["blood_type"] - color = bloodtype_to_color(R.data["blood_type"]) + blood_list_checks(src, R.data["blood_type"]) + blood_color = blood_DNA_to_color(blood_mix_types) else if(istype(R, /datum/reagent/liquidgibs)) if(R.data["blood_type"]) - bloodmeme = R.data["blood_type"] - color = bloodtype_to_color(R.data["blood_type"]) - else - color = blood_DNA_to_color() + blood_list_checks(src, R.data["blood_type"]) + blood_color = blood_DNA_to_color(blood_mix_types) /obj/effect/decal/cleanable/blood/old name = "dried blood" @@ -50,7 +46,6 @@ /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. add_blood_DNA(list("blood_type"= "A+")) /obj/effect/decal/cleanable/blood/splatter @@ -65,7 +60,6 @@ blood_state = BLOOD_STATE_BLOOD color = BLOOD_COLOR_HUMAN bloodiness = BLOOD_AMOUNT_PER_DECAL - var/bloodmeme = "" var/data = "" /obj/effect/decal/cleanable/trail_holder/update_icon() @@ -73,17 +67,17 @@ // Get blood data from the blood reagent. if(istype(R, /datum/reagent/blood)) if(R.data["blood_type"]) - color = bloodtype_to_color(R.data["blood_type"]) //Color the blood with our dna stuff + blood_list_checks(src, R.data["blood_type"]) + color = blood_DNA_to_color(blood_mix_types) else if(istype(R, /datum/reagent/liquidgibs)) if(R.data["blood_type"]) - bloodmeme = R.data["blood_type"] - color = bloodtype_to_color(R.data["blood_type"]) + blood_list_checks(src, R.data["blood_type"]) + color = blood_DNA_to_color(blood_mix_types) else color = blood_DNA_to_color() /obj/effect/cleanable/trail_holder/Initialize() . = ..() - AddComponent(/datum/component/forensics) update_icon() /obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in() @@ -110,15 +104,20 @@ if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes - if(S && S.bloody_shoes[blood_state]) - S.last_bloodtype = bloodmeme - S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) + if(S && S.blood_smear[blood_state]) + S.blood_list_checks(S, data["blood_type"]) + S.blood_smear[blood_state] = max(S.blood_smear[blood_state] - BLOOD_LOSS_PER_STEP, 0) shoe_types |= S.type if (!(entered_dirs & H.dir)) entered_dirs |= H.dir update_icon() - else if(!bloodiness) - H.bloodiness = max(bloodiness / BLOOD_LOSS_IN_SPREAD, 0) + + else if(!H.bloodiness) + H.bloodiness = max(H.bloodiness - BLOOD_LOSS_IN_SPREAD, 0) + H.blood_list_checks(H, data["blood_type"]) + if (!(entered_dirs & H.dir)) + entered_dirs |= H.dir + update_icon() /obj/effect/decal/cleanable/blood/footprints/tracks/Uncrossed(atom/movable/O) @@ -126,34 +125,42 @@ if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes - if(S && S.bloody_shoes[blood_state]) - S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) + if(S && S.blood_smear[blood_state]) + S.blood_list_checks(S, data["blood_type"]) + S.blood_smear[blood_state] = max(S.blood_smear[blood_state] - BLOOD_LOSS_PER_STEP, 0) shoe_types |= S.type if (!(exited_dirs & H.dir)) exited_dirs |= H.dir update_icon() + else if(!H.bloodiness) + H.bloodiness = max(H.bloodiness - BLOOD_LOSS_IN_SPREAD, 0) + H.blood_list_checks(H, data["blood_type"]) + if (!(exited_dirs & H.dir)) + exited_dirs |= H.dir + update_icon() /obj/effect/decal/cleanable/blood/footprints/tracks/update_icon() cut_overlays() for(var/Ddir in GLOB.cardinals) if(entered_dirs & Ddir) - var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[print_state]-[Ddir]-[color]"] if(!bloodstep_overlay) - GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]1", dir = Ddir) + GLOB.bloody_footprints_cache["entered-[print_state]-[Ddir]-[color]"] = bloodstep_overlay = image(icon, "[print_state]1", dir = Ddir) add_overlay(bloodstep_overlay) if(exited_dirs & Ddir) - var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[print_state]-[Ddir]-[color]"] if(!bloodstep_overlay) - GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]2", dir = Ddir) + GLOB.bloody_footprints_cache["exited-[print_state]-[Ddir]-[color]"] = bloodstep_overlay = image(icon, "[print_state]2", dir = Ddir) add_overlay(bloodstep_overlay) alpha = BLOODY_FOOTPRINT_BASE_ALPHA+bloodiness + color = blood_DNA_to_color(blood_mix_types) /obj/effect/decal/cleanable/blood/footprints/tracks/examine(mob/user) . = ..() - if(shoe_types.len) + if(shoe_types.len && user.mind.assigned_role == "Detective") //gumshoe does the detective thing, not every fucking assistant . += "You recognise the footprints as belonging to:\n" for(var/shoe in shoe_types) var/obj/item/clothing/shoes/S = shoe diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 845c66fb33..be0e06b47a 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -739,9 +739,9 @@ for(var/obj/effect/decal/cleanable/trail_holder/TH in view(T, 2)) qdel(TH) var/obj/item/clothing/shoes/shoecheck = user.shoes - if(shoecheck && shoecheck.bloody_shoes["blood"]) - temp += shoecheck.bloody_shoes["blood"]/20 - shoecheck.bloody_shoes["blood"] = 0 + if(shoecheck && shoecheck.blood_smear["blood"]) + temp += shoecheck.blood_smear["blood"]/20 + shoecheck.blood_smear["blood"] = 0 if(temp) user.Beam(T,icon_state="drainbeam",time=15) new /obj/effect/temp_visual/cult/sparks(get_turf(user)) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 746d5da60d..f79bf5c567 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -41,6 +41,10 @@ var/dynamic_hair_suffix = ""//head > mask for head hair var/dynamic_fhair_suffix = ""//mask > head for facial hair + var/blood_color = BLOOD_COLOR_HUMAN + var/blood_state = BLOOD_STATE_NOT_BLOODY + var/list/blood_smear = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0) + /obj/item/clothing/Initialize() . = ..() if(ispath(pocket_storage_component_path)) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index c0227b8765..b9b37f67b0 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -10,12 +10,8 @@ permeability_coefficient = 0.5 slowdown = SHOES_SLOWDOWN - var/blood_state = BLOOD_STATE_NOT_BLOODY - var/list/bloody_shoes = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0) var/offset = 0 var/equipped_before_drop = FALSE - var/last_bloodtype = ""//used to track the last bloodtype to have graced these shoes; makes for better performing footprint shenanigans - var/last_blood_DNA = ""//same as last one //CITADEL EDIT Enables digitigrade shoe styles var/adjusted = NORMAL_STYLE @@ -51,15 +47,15 @@ IF_HAS_BLOOD_DNA(src) bloody = TRUE else - bloody = bloody_shoes[BLOOD_STATE_BLOOD] + bloody = blood_smear[BLOOD_STATE_BLOOD] if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe") if(bloody) if(adjusted == NORMAL_STYLE) - . += mutable_appearance('icons/effects/blood.dmi', "shoeblood", color = bloodtype_to_color(last_bloodtype)) + . += mutable_appearance('icons/effects/blood.dmi', "shoeblood", color = blood_DNA_to_color(blood_mix_types)) else - . += mutable_appearance('modular_citadel/icons/mob/digishoes.dmi', "shoeblood", color = bloodtype_to_color(last_bloodtype)) + . += mutable_appearance('modular_citadel/icons/mob/digishoes.dmi', "shoeblood", color = blood_DNA_to_color(blood_mix_types)) /obj/item/clothing/shoes/equipped(mob/user, slot) . = ..() @@ -98,7 +94,7 @@ /obj/item/clothing/shoes/proc/clean_blood(datum/source, strength) if(strength < CLEAN_STRENGTH_BLOOD) return - bloody_shoes = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0) + blood_smear = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0) blood_state = BLOOD_STATE_NOT_BLOODY if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index b51d464ff7..5fb78c0098 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -43,9 +43,9 @@ var/bleed_rate = 0 //how much are we bleeding var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding + var/bloodiness = 0 var/blood_state = BLOOD_STATE_NOT_BLOODY var/list/blood_smear = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0) - var/last_bloodtype = ""//used to track the last bloodtype to have graced this smelly person. for smears on the floor var/last_blood_DNA = ""//same as last one var/name_override //For temporary visible name changes diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 28a642d7a0..9d072c90a2 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -55,18 +55,17 @@ //Bloody footprints var/turf/T = get_turf(src) - if(S.bloody_shoes && S.bloody_shoes[S.blood_state]) + if(S.blood_smear && S.blood_smear[S.blood_state]) var/obj/effect/decal/cleanable/blood/footprints/tracks/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints/tracks) in T - if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == bloodtype_to_color(S.last_bloodtype))) + if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == color)) return - S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP) + S.blood_smear[S.blood_state] = max(0, S.blood_smear[S.blood_state]-BLOOD_LOSS_PER_STEP) var/obj/effect/decal/cleanable/blood/footprints/tracks/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints/tracks/footprints(T) FP.icon_state = FOOTPRINT_SHOE FP.print_state = FOOTPRINT_SHOE FP.blood_state = S.blood_state FP.entered_dirs |= dir - FP.bloodiness = S.bloody_shoes[S.blood_state] - FP.bloodmeme = S.bloodmeme + FP.bloodiness = S.blood_smear[S.blood_state] FP.update_icon() update_inv_shoes() //End bloody footprints @@ -82,7 +81,7 @@ var/turf/T = get_turf(src) if(bloodiness) var/obj/effect/decal/cleanable/blood/footprints/tracks/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints/tracks) in T - if (oldFP.color == color) + if(oldFP && (oldFP.blood_state == blood_state && oldFP.color == color)) return else var/obj/effect/decal/cleanable/blood/footprints/tracks/FP = new /obj/effect/decal/cleanable/blood/footprints/tracks(T) @@ -107,18 +106,17 @@ FP.icon_state = FOOTPRINT_SHOE FP.print_state = FOOTPRINT_SHOE FP.add_blood_DNA(return_blood_DNA()) - FP.bloodmeme = bloodmeme FP.update_icon() var/newdir = get_dir(T, loc) if(newdir == dir) - B.setDir(newdir) + FP.setDir(newdir) else newdir = newdir | dir if(newdir == 3) newdir = 1 else if(newdir == 12) newdir = 4 - B.setDir(newdir) + FP.setDir(newdir) bloodiness-- else //we're on the floor, smear some stuff around @@ -128,26 +126,24 @@ var/turf/T = get_turf(src) if(bloodiness) var/obj/effect/decal/cleanable/blood/footprints/tracks/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints/tracks) in T - if (oldFP.color == color) + if(oldFP && (oldFP.blood_state == blood_state && oldFP.color == color)) return else var/obj/effect/decal/cleanable/blood/footprints/tracks/FP = new /obj/effect/decal/cleanable/blood/footprints/tracks/body(T) FP.icon_state = FOOTPRINT_DRAG FP.print_state = FOOTPRINT_DRAG FP.add_blood_DNA(return_blood_DNA()) - FP.bloodtrack = bloodtrack - FP.bloodmeme = bloodmeme FP.update_icon() var/newdir = get_dir(T, loc) if(newdir == dir) - B.setDir(newdir) + FP.setDir(newdir) else newdir = newdir | dir if(newdir == 3) newdir = 1 else if(newdir == 12) newdir = 4 - B.setDir(newdir) + FP.setDir(newdir) bloodiness-- /mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee. diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 92c9c1e104..4622d79777 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -106,10 +106,8 @@ // Get blood data from the blood reagent. if(istype(R, /datum/reagent/blood)) if(R.data["blood_type"]) - B.bloodmeme = R.data["blood_type"] - if(istype(R, /datum/reagent/liquidgibs)) - if(R.data["blood_type"]) - B.bloodmeme = R.data["blood_type"] + B.blood_list_checks(src, R.data["blood_type"]) + B.color = B.blood_DNA_to_color(blood_mix_types) /datum/reagent/blood/synthetics data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) diff --git a/tgstation.dme b/tgstation.dme index 7037d50cb7..88e843f542 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -375,6 +375,7 @@ #include "code\datums\components\uplink.dm" #include "code\datums\components\wearertargeting.dm" #include "code\datums\components\wet_floor.dm" +#include "code\datums\components\decals\blood.dm" #include "code\datums\components\storage\storage.dm" #include "code\datums\components\storage\concrete\_concrete.dm" #include "code\datums\components\storage\concrete\bag_of_holding.dm"