From 0f6677b9564cb689726e8db065eeb0a42d730859 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Thu, 16 May 2019 08:23:53 -0500 Subject: [PATCH] Blood colors happens to footprints now. Different prints not working. splatter effect not working, I'm just sick of looking at this right now. --- code/__DEFINES/components.dm | 2 + code/__DEFINES/footsteps.dm | 1 + code/datums/components/decals/blood.dm | 6 +- code/datums/components/forensics.dm | 26 ++-- code/game/objects/effects/decals/cleanable.dm | 5 +- .../effects/decals/cleanable/aliens.dm | 4 +- .../objects/effects/decals/cleanable/gibs.dm | 10 +- .../effects/decals/cleanable/humans.dm | 72 +++++---- code/game/objects/items.dm | 3 + code/modules/clothing/clothing.dm | 1 - code/modules/clothing/shoes/_shoes.dm | 2 + code/modules/detectivework/detective_work.dm | 10 ++ .../mob/living/carbon/human/human_defines.dm | 1 + .../mob/living/carbon/human/human_movement.dm | 143 ++++++------------ .../mob/living/carbon/human/species.dm | 11 +- .../carbon/human/species_types/angel.dm | 1 + .../carbon/human/species_types/humans.dm | 1 + .../carbon/human/species_types/jellypeople.dm | 4 +- .../human/species_types/lizardpeople.dm | 3 + .../carbon/human/species_types/mothmen.dm | 1 + .../carbon/human/species_types/plasmamen.dm | 1 + .../carbon/human/species_types/podpeople.dm | 1 + .../carbon/human/species_types/skeletons.dm | 1 + .../carbon/human/species_types/zombies.dm | 5 +- .../chemistry/reagents/other_reagents.dm | 4 +- icons/effects/fluidtracks.dmi | Bin 13404 -> 13833 bytes .../carbon/human/species_types/furrypeople.dm | 26 +++- .../living/carbon/human/species_types/ipc.dm | 1 + 28 files changed, 184 insertions(+), 162 deletions(-) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 7322823231..b00765d2bb 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -202,6 +202,8 @@ #define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool. #define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength) +//Blood color +#define COMSIG_BLOOD_COLOR "blood_DNA_to_color" //RGB blood stuff //Food #define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder) diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm index 56dfbe155d..8937ab6afa 100644 --- a/code/__DEFINES/footsteps.dm +++ b/code/__DEFINES/footsteps.dm @@ -8,6 +8,7 @@ #define FOOTSTEP_LAVA "lava" #define FOOTPRINT_SHOE "shoe" +#define FOOTPRINT_FOOT "foot" #define FOOTPRINT_PAW "paw" #define FOOTPRINT_CLAW "claw" #define FOOTPRINT_WHEEL "wheels" diff --git a/code/datums/components/decals/blood.dm b/code/datums/components/decals/blood.dm index ba69e07d65..3daa4b5944 100644 --- a/code/datums/components/decals/blood.dm +++ b/code/datums/components/decals/blood.dm @@ -19,17 +19,17 @@ // It's something which takes on the look of other items, probably icon = I.icon icon_state = I.icon_state - GET_COMPONENT(D, /datum/component/forensics) 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]-[D.blood_mix_color]" + var/index = "[REF(icon)]-[icon_state]" 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 - blood_splatter_icon.Blend(D.blood_mix_color, ICON_MULTIPLY) //add the blood's color with DNA information + pic = mutable_appearance(blood_splatter_icon, initial(I.icon_state)) + pic.color = I.blood_color //add the blood's color with DNA information blood_splatter_appearances[index] = pic return TRUE diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm index a3461b31fb..4ee8b93cc7 100644 --- a/code/datums/components/forensics.dm +++ b/code/datums/components/forensics.dm @@ -32,6 +32,7 @@ /datum/component/forensics/RegisterWithParent() check_blood() RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act) +// RegisterSignal(parent, COMSIG_BLOOD_COLOR, .proc/ /datum/component/forensics/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_COMPONENT_CLEAN_ACT)) @@ -163,10 +164,14 @@ if(!length(dna)) return LAZYINITLIST(blood_DNA) + LAZYINITLIST(blood_mix_types) for(var/i in dna) blood_DNA[i] = dna[i] - var/blood_type = blood_DNA.Find(GLOB.all_types_bloods) - add_blood_list(blood_type) + for(var/type in blood_DNA) + if(type in blood_DNA[type]) + blood_mix_types += blood_DNA[type] + + blood_list_check(blood_mix_types) check_blood() return TRUE @@ -176,22 +181,18 @@ if(!length(blood_DNA)) return -/datum/component/forensics/proc/add_blood_list(blood_type) - if(!blood_type) - return - LAZYINITLIST(blood_mix_types) - blood_list_checks(blood_mix_types, blood_type) - blood_DNA_to_color(blood_mix_types) - return TRUE - -/datum/component/forensics/proc/blood_list_checks(list/blood_types, var/blood_type) //This is a messy attempt at trying to reduce lists of items and mobs with blood colors on them +/datum/component/forensics/proc/blood_list_check(list/blood_types, 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(blood_type in blood_mix_types) return else LAZYADD(blood_mix_types, blood_type) - return TRUE + + if(blood_mix_types.len) + blood_DNA_to_color(blood_mix_types) + else + return /datum/component/forensics/proc/blood_DNA_to_color(list/bloods) var/final_rgb = "#940000" //We default to red just in case @@ -210,4 +211,3 @@ final_rgb = BlendRGB(final_rgb, bloodtype_to_color(bloods)) blood_mix_color = final_rgb - return TRUE diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index c4b668696d..f5e929a7ae 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -90,12 +90,13 @@ else if(H.bloodiness && blood_state && bloodiness && (!H.has_trait(TRAIT_LIGHT_STEP) || !H.mind.assigned_role == "Detective")) var/add_blood = 0 - if(H.bloodiness >= BLOOD_GAIN_PER_STEP) - add_blood = BLOOD_GAIN_PER_STEP + if(H.bloodiness >= 1) + add_blood = 5 else add_blood = bloodiness bloodiness -= add_blood H.blood_smear[blood_state] = min(MAX_SHOE_BLOODINESS,H.blood_smear[blood_state]+add_blood) + H.bloodiness = add_blood H.add_blood_DNA(return_blood_DNA()) H.blood_state = blood_state H.blood_color = blood_color diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index 29c8332529..9b4d65cff4 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -33,8 +33,10 @@ GET_COMPONENT(infective, /datum/component/infective) if(infective) diseases = infective.diseases + var/obj/effect/decal/cleanable/blood/gibs/gibbers = src var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases) - splat.update_icon() + splat.color = gibbers.blood_color + splat.blood_color = gibbers.blood_color 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 5c76bd6867..31849c7251 100644 --- a/code/game/objects/effects/decals/cleanable/gibs.dm +++ b/code/game/objects/effects/decals/cleanable/gibs.dm @@ -11,14 +11,13 @@ /obj/effect/decal/cleanable/blood/gibs/proc/guts() if(gib_overlay) - var/mutable_appearance/gibz = mutable_appearance(icon, icon_state + "-overlay", color = blood_color) - gibz.layer = (LOW_OBJ_LAYER - 0.1) - var/mutable_appearance/gibz2 = mutable_appearance(icon, icon_state + "c-overlay", color = body_colors) - gibz2.layer = (LOW_OBJ_LAYER - 0.2) + var/mutable_appearance/gibz = mutable_appearance(icon, icon_state + "-overlay", color = blood_color, layer = (LOW_OBJ_LAYER + 0.1)) + var/mutable_appearance/gibz2 = mutable_appearance(icon, icon_state + "c-overlay", color = body_colors, layer = (LOW_OBJ_LAYER + 0.1)) if(!slimy_gibs) gibz.appearance_flags = RESET_COLOR add_overlay(gibz) else + gibz.appearance_flags = RESET_COLOR add_overlay(gibz) add_overlay(gibz2) @@ -31,6 +30,8 @@ var/mob/living/carbon/human/H = L if(H.mind.assigned_role == "Detective") //Gumshoe perks yo playsound(loc, 'sound/effects/gib_step.ogg', 10, 1) + else + playsound(loc, 'sound/effects/gib_step.ogg', H.has_trait(TRAIT_LIGHT_STEP) ? 20 : 50, 1) else playsound(loc, 'sound/effects/gib_step.ogg', L.has_trait(TRAIT_LIGHT_STEP) ? 20 : 50, 1) . = ..() @@ -48,6 +49,7 @@ var/obj/effect/decal/cleanable/blood/gibs/gibbers = src var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases) splat.color = gibbers.blood_color + splat.blood_color = gibbers.blood_color if(!step_to(src, get_step(src, direction), 0)) break diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 1c9dfb9a35..0a4a266874 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -8,10 +8,6 @@ color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere. bloodiness = BLOOD_AMOUNT_PER_DECAL -/obj/effect/decal/cleanable/blood/ComponentInitialize() - . = ..() - AddComponent(/datum/component/forensics) - update_icon() /obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) if(bloodiness) @@ -28,21 +24,24 @@ update_icon() /obj/effect/decal/cleanable/blood/update_icon() - GET_COMPONENT(F, /datum/component/forensics) - if(F && istype(F)) - blood_color = F.blood_mix_color + if(!blood_color) + if(reagents.reagent_list.len) + 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"]) + blood_color = bloodtype_to_color(R.data["blood_type"]) + else if(istype(R, /datum/reagent/liquidgibs)) + if(R.data["blood_type"]) + blood_color = bloodtype_to_color(R.data["blood_type"]) + else + return else - 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"]) - blood_color = bloodtype_to_color(R.data["blood_type"]) - else if(istype(R, /datum/reagent/liquidgibs)) - if(R.data["blood_type"]) - blood_color = bloodtype_to_color(R.data["blood_type"]) - - color = blood_color + color = blood_color +//obj/effect/decal/cleanable/blood/update_color() + // if(SEND_SIGNAL(COMSIG_BLOOD_COLOR) & COMPONENT_BLOCK_UPDATE_COLOR) + // return /obj/effect/decal/cleanable/blood/old name = "dried blood" @@ -108,9 +107,9 @@ entered_dirs |= H.dir update_icon() - else if(!H.bloodiness) - H.blood_smear[blood_state] = max(S.blood_smear[blood_state] - BLOOD_LOSS_PER_STEP, 0) - H.bloodiness = max(H.bloodiness - BLOOD_LOSS_IN_SPREAD, 0) + else if(H.bloodiness && H.blood_smear[blood_state]) + H.blood_smear[blood_state] = max(H.blood_smear[blood_state] - BLOOD_LOSS_PER_STEP, 0) + H.bloodiness = H.bloodinessmax H.blood_color = blood_color if (!(entered_dirs & H.dir)) entered_dirs |= H.dir @@ -130,9 +129,9 @@ exited_dirs |= H.dir update_icon() - else if(!H.bloodiness) + else if(H.bloodiness && H.blood_smear[blood_state]) H.blood_smear[blood_state] = max(H.blood_smear[blood_state] - BLOOD_LOSS_PER_STEP, 0) - H.bloodiness = max(H.bloodiness - BLOOD_LOSS_IN_SPREAD, 0) + H.bloodiness = H.bloodinessmax H.blood_color = blood_color if (!(exited_dirs & H.dir)) exited_dirs |= H.dir @@ -143,17 +142,18 @@ for(var/Ddir in GLOB.cardinals) if(entered_dirs & Ddir) - var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[print_state]-[Ddir]-[color]"] + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[print_state]-[Ddir]"] if(!bloodstep_overlay) - GLOB.bloody_footprints_cache["entered-[print_state]-[Ddir]-[color]"] = bloodstep_overlay = image(icon, "[print_state]1", dir = Ddir) + GLOB.bloody_footprints_cache["entered-[print_state]-[Ddir]"] = 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-[print_state]-[Ddir]-[color]"] + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[print_state]-[Ddir]"] if(!bloodstep_overlay) - GLOB.bloody_footprints_cache["exited-[print_state]-[Ddir]-[color]"] = bloodstep_overlay = image(icon, "[print_state]2", dir = Ddir) + GLOB.bloody_footprints_cache["exited-[print_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[print_state]2", dir = Ddir) add_overlay(bloodstep_overlay) alpha = BLOODY_FOOTPRINT_BASE_ALPHA + bloodiness + color = blood_color /obj/effect/decal/cleanable/blood/footprints/tracks/examine(mob/user) @@ -166,8 +166,8 @@ to_chat(user, .) -/obj/effect/decal/cleanable/blood/footprints/tracks/replace_decal(obj/effect/decal/cleanable/C) - if(blood_state != C.blood_state) //We only replace footprints of the same type as us +/obj/effect/decal/cleanable/blood/footprints/tracks/replace_decal(obj/effect/decal/cleanable/blood/footprints/tracks/C) + if(print_state != C.print_state) //We only replace footprints of the same type as us return if(color != C.color) return @@ -178,12 +178,18 @@ return TRUE return FALSE -/obj/effect/decal/cleanable/blood/footprints/tracks/footprints +/obj/effect/decal/cleanable/blood/footprints/tracks/shoe name = "footprints" desc = "They look like tracks left by footwear." icon_state = FOOTPRINT_SHOE print_state = FOOTPRINT_SHOE +/obj/effect/decal/cleanable/blood/footprints/tracks/foot + name = "footprints" + desc = "They look like tracks left by a bare foot." + icon_state = FOOTPRINT_FOOT + print_state = FOOTPRINT_FOOT + /obj/effect/decal/cleanable/blood/footprints/tracks/snake name = "tracks" desc = "They look like tracks left by a giant snake." @@ -191,14 +197,14 @@ print_state = FOOTPRINT_SNAKE /obj/effect/decal/cleanable/blood/footprints/tracks/paw - name = "tracks" - desc = "They look like tracks left by mammalian paws." + name = "footprints" + desc = "They look like tracks left by paws." icon_state = FOOTPRINT_PAW print_state = FOOTPRINT_PAW /obj/effect/decal/cleanable/blood/footprints/tracks/claw - name = "tracks" - desc = "They look like tracks left by reptilian claws." + name = "footprints" + desc = "They look like tracks left by claws." icon_state = FOOTPRINT_CLAW print_state = FOOTPRINT_CLAW diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 4d6253d0b0..88eb8e9ad4 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -111,6 +111,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! + //Blood overlay things + var/blood_color + /obj/item/Initialize() materials = typelist("materials", materials) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f79bf5c567..922f37b270 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -41,7 +41,6 @@ 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) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 4c6131644c..4aec17fafe 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -17,6 +17,8 @@ var/adjusted = NORMAL_STYLE mutantrace_variation = MUTANTRACE_VARIATION + var/move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/shoe + /obj/item/clothing/shoes/ComponentInitialize() . = ..() AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood))) diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm index c892bfeffc..0b1d6807bf 100644 --- a/code/modules/detectivework/detective_work.dm +++ b/code/modules/detectivework/detective_work.dm @@ -25,6 +25,16 @@ if(D) . = D.fibers +/atom/proc/return_blood_mix_types() + GET_COMPONENT(D, /datum/component/forensics) + if(D) + . = D.blood_mix_types + +/atom/proc/return_blood_mix_color() + GET_COMPONENT(D, /datum/component/forensics) + if(D) + . = D.blood_mix_color + /atom/proc/add_fingerprint_list(list/fingerprints) //ASSOC LIST FINGERPRINT = FINGERPRINT if(length(fingerprints)) . = AddComponent(/datum/component/forensics, fingerprints) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index be6d2196e0..95139f75ee 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -44,6 +44,7 @@ var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding var/bloodiness = 0 + var/bloodinessmax = 5 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/blood_color //For blood smearing stuff diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 1135a592e1..b2592ae157 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -46,110 +46,61 @@ for(var/datum/mutation/human/HM in dna.mutations) HM.on_move(src, NewLoc) - if(shoes) - if(!lying && !buckled) - if(loc == NewLoc) - if(!has_gravity(loc)) - return - var/obj/item/clothing/shoes/S = shoes - - //Bloody footprints - var/turf/T = get_turf(src) - 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 == color)) - return - 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.blood_color = S.blood_color - FP.entered_dirs |= dir - FP.bloodiness = S.blood_smear[S.blood_state] - FP.update_icon() - update_inv_shoes() - //End bloody footprints - - S.step_action() - - else - if(!buckled) + if(!buckled) + if(shoes) if(!lying) if(loc == NewLoc) if(!has_gravity(loc)) return + var/obj/item/clothing/shoes/S = shoes + //Bloody footprints var/turf/T = get_turf(src) - var/mob/living/carbon/human/H = src - if(H.bloodiness) - var/obj/effect/decal/cleanable/blood/footprints/tracks/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints/tracks) in T - if(oldFP && (oldFP.blood_state == blood_state && oldFP.color == color)) + if(S.blood_smear && S.blood_smear[S.blood_state]) + var/obj/effect/decal/cleanable/blood/footprints/tracks/shoe/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints/tracks/shoe) in T + if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == S.blood_color)) return - else - var/obj/effect/decal/cleanable/blood/footprints/tracks/FP = new /obj/effect/decal/cleanable/blood/footprints/tracks(T) - if(DIGITIGRADE in dna.species.species_traits) - if(dna.species.id == ("lizard" || "ashwalker" || "xeno")) - FP.icon_state = FOOTPRINT_CLAW - FP.print_state = FOOTPRINT_CLAW - else if(dna.species.id == "Mammal") - FP.icon_state = FOOTPRINT_PAW - FP.print_state = FOOTPRINT_PAW - else - FP.icon_state = FOOTPRINT_SHOE - FP.print_state = FOOTPRINT_SHOE - else if(("taur" in dna.species.mutant_bodyparts) && (dna.features["taur"] != "None")) - if(dna.features["taur"] in GLOB.noodle_taurs) - FP.icon_state = FOOTPRINT_SNAKE - FP.print_state = FOOTPRINT_SNAKE - else if(dna.features["taur"] in GLOB.paw_taurs) - FP.icon_state = FOOTPRINT_PAW - FP.print_state = FOOTPRINT_PAW - else - FP.icon_state = FOOTPRINT_SHOE - FP.print_state = FOOTPRINT_SHOE - FP.add_blood_DNA(return_blood_DNA()) - FP.blood_color = H.blood_color - FP.update_icon() - var/newdir = get_dir(T, loc) - if(newdir == dir) - FP.setDir(newdir) - else - newdir = newdir | dir - if(newdir == 3) - newdir = 1 - else if(newdir == 12) - newdir = 4 - FP.setDir(newdir) - bloodiness-- + 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/shoe/FP = new /obj/effect/decal/cleanable/blood/footprints/tracks/shoe(T) + FP.icon_state = FOOTPRINT_SHOE + FP.print_state = FOOTPRINT_SHOE + FP.blood_state = S.blood_state + FP.blood_color = S.blood_color + FP.entered_dirs |= dir + FP.bloodiness = S.blood_smear[S.blood_state] + FP.update_icon() + update_inv_shoes() + //End bloody footprints - else //we're on the floor, smear some stuff around - if(loc == NewLoc) - if(!has_gravity(loc)) + S.step_action() + else + if(loc == NewLoc) + if(!has_gravity(loc)) + return + var/turf/T = get_turf(src) + var/step_print = dna.species.get_move_trail(src) + if(bloodiness && blood_smear[blood_state]) + var/obj/effect/decal/cleanable/blood/footprints/tracks/oldFP = locate(step_print) in T + if(oldFP && (oldFP.blood_state == blood_state && oldFP == dna.species.move_trail && oldFP.blood_color == blood_color)) return - var/turf/T = get_turf(src) - var/mob/living/carbon/human/H = src - if(bloodiness) - var/obj/effect/decal/cleanable/blood/footprints/tracks/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints/tracks) in T - 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.blood_color = H.blood_color - FP.update_icon() - var/newdir = get_dir(T, loc) - if(newdir == dir) - FP.setDir(newdir) - else - newdir = newdir | dir - if(newdir == 3) - newdir = 1 - else if(newdir == 12) - newdir = 4 - FP.setDir(newdir) - bloodiness-- + else + var/obj/effect/decal/cleanable/blood/footprints/tracks/FP = new step_print(T) + if(("taur" in dna.species.mutant_bodyparts) && (dna.features["taur"] != "None") && !lying) + if(dna.features["taur"] in GLOB.noodle_taurs) + FP.icon_state = FOOTPRINT_SNAKE + FP.print_state = FOOTPRINT_SNAKE + else if(dna.features["taur"] in GLOB.paw_taurs) + FP.icon_state = FOOTPRINT_PAW + FP.print_state = FOOTPRINT_PAW + if(!dna.species.move_trail && !lying) //we're assuming people have their chosen snowflake on, so. + FP.icon_state = FOOTPRINT_SHOE + FP.print_state = FOOTPRINT_SHOE + + FP.add_blood_DNA(return_blood_DNA()) + FP.blood_color = blood_color + FP.entered_dirs |= dir + FP.bloodiness = blood_smear[blood_state] + FP.update_icon() + bloodiness-- /mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee. if(dna.species.space_move(src)) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index d3eb4bafa0..e34d17163b 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -77,7 +77,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/fixed_mut_color3 = "" var/whitelisted = 0 //Is this species restricted to certain players? var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both. - + var/obj/effect/decal/cleanable/blood/footprints/tracks/move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/shoe // What marks are left when walking /////////// // PROCS // @@ -927,6 +927,15 @@ GLOBAL_LIST_EMPTY(roundstart_races) return "TAUR" //END EDIT +// Impliments different trails for species depending on if they're wearing shoes. +/datum/species/proc/get_move_trail(var/mob/living/carbon/human/H) + if(H.lying) + return /obj/effect/decal/cleanable/blood/footprints/tracks/body + if(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET))) + var/obj/item/clothing/shoes/shoes = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) ? H.wear_suit : H.shoes // suits take priority over shoes + return shoes.move_trail + else + return move_trail /datum/species/proc/spec_life(mob/living/carbon/human/H) if(H.has_trait(TRAIT_NOBREATH)) diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm index 5122294956..92798c8bc7 100644 --- a/code/modules/mob/living/carbon/human/species_types/angel.dm +++ b/code/modules/mob/living/carbon/human/species_types/angel.dm @@ -10,6 +10,7 @@ blacklisted = 1 limbs_id = "human" skinned_type = /obj/item/stack/sheet/animalhide/human + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot var/datum/action/innate/flight/fly diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index 96b43795a2..d3288e1cd1 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -9,6 +9,7 @@ skinned_type = /obj/item/stack/sheet/animalhide/human disliked_food = GROSS | RAW liked_food = JUNKFOOD | FRIED + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot /datum/species/human/qualifies_for_rank(rank, list/features) return TRUE //Pure humans are always allowed in all roles. diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 5c8c082d47..ea7a20163a 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -10,6 +10,7 @@ inherent_traits = list(TRAIT_TOXINLOVER) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime exotic_blood = "jellyblood" + exotic_bloodtype = "GEL" damage_overlay_type = "" var/datum/action/innate/regenerate_limbs/regenerate_limbs var/datum/action/innate/slime_change/slime_change //CIT CHANGE @@ -17,6 +18,7 @@ coldmod = 6 // = 3x cold damage heatmod = 0.5 // = 1/4x heat damage burnmod = 0.5 // = 1/2x generic burn damage + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot /datum/species/jelly/on_species_loss(mob/living/carbon/C) if(regenerate_limbs) @@ -119,7 +121,7 @@ name = "Slimeperson" id = "slime" default_color = "00FFFF" - species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD) + species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR) say_mod = "says" hair_color = "mutcolor" hair_alpha = 150 diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index c5a64ebd13..ba4d8b8781 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -73,6 +73,7 @@ /datum/species/lizard/on_species_gain(mob/living/carbon/human/C, datum/species/old_species) if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Digitigrade Legs") species_traits += DIGITIGRADE + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/claw if(DIGITIGRADE in species_traits) C.Digitigrade_Leg_Swap(FALSE) return ..() @@ -80,6 +81,7 @@ /datum/species/lizard/on_species_loss(mob/living/carbon/human/C, datum/species/new_species) if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Normal Legs") species_traits -= DIGITIGRADE + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot if(DIGITIGRADE in species_traits) C.Digitigrade_Leg_Swap(TRUE) @@ -95,6 +97,7 @@ mutantlungs = /obj/item/organ/lungs/ashwalker burnmod = 0.9 brutemod = 0.9 + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/claw /datum/species/lizard/ashwalker/on_species_gain(mob/living/carbon/human/C, datum/species/old_species) if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index d15d989384..4c2c360c68 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -15,6 +15,7 @@ disliked_food = FRUIT | GROSS toxic_food = MEAT | RAW mutanteyes = /obj/item/organ/eyes/moth + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/claw /datum/species/moth/on_species_gain(mob/living/carbon/C) . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 6f5ae6f4eb..9fae5a21ea 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -21,6 +21,7 @@ var/internal_fire = FALSE //If the bones themselves are burning clothes won't help you much disliked_food = FRUIT liked_food = VEGETABLES + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot /datum/species/plasmaman/spec_life(mob/living/carbon/human/H) var/datum/gas_mixture/environment = H.loc.return_air() diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 3e238f8a53..cfbe16bfbf 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -12,6 +12,7 @@ meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant disliked_food = MEAT | DAIRY liked_food = VEGETABLES | FRUIT | GRAIN + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot /datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index d778aa50f2..25967dd0c3 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -13,6 +13,7 @@ damage_overlay_type = ""//let's not show bloody wounds or burns over bones. disliked_food = NONE liked_food = GROSS | MEAT | RAW + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot /datum/species/skeleton/check_roundstart_eligible() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 504dbb514b..e2c8ffb9c3 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -15,6 +15,7 @@ var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg') disliked_food = NONE liked_food = GROSS | MEAT | RAW + move_trail = /obj/effect/decal/cleanable/blood/footprints/tracks/foot /datum/species/zombie/check_roundstart_eligible() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) @@ -47,7 +48,7 @@ /datum/species/zombie/infectious/spec_life(mob/living/carbon/C) . = ..() C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW - + //Zombies never actually die, they just fall down until they regenerate enough to rise back up. //They must be restrained, beheaded or gibbed to stop being a threat. if(regen_cooldown < world.time) @@ -58,7 +59,7 @@ C.adjustToxLoss(-heal_amt) if(!C.InCritical() && prob(4)) playsound(C, pick(spooks), 50, TRUE, 10) - + //Congrats you somehow died so hard you stopped being a zombie /datum/species/zombie/infectious/spec_death(mob/living/carbon/C) . = ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 85d73d6a6e..d91b675e22 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1,5 +1,5 @@ /datum/reagent/blood - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Blood" id = "blood" color = BLOOD_COLOR_HUMAN // rgb: 200, 0, 0 @@ -182,7 +182,7 @@ description = "You don't even want to think about what's in here." taste_description = "gross iron" shot_glass_icon_state = "shotglassred" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) /datum/reagent/liquidgibs/xeno name = "Liquid xeno gibs" diff --git a/icons/effects/fluidtracks.dmi b/icons/effects/fluidtracks.dmi index 6579334e87a3948321a20941478925e3ea182fd1..e2f0c97479a3d5401fe8f178e34c1ad3aa6e0802 100644 GIT binary patch literal 13833 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 literal 13404 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