From 0679d3cc1909c9ccfb594640a3cc7430f0041f60 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Mon, 17 Jul 2017 21:01:13 -0400 Subject: [PATCH 1/6] Splatter lands 1 tile away in target direction. Adjusts splatter to land 1 tile away from the mob in the target direction. Splatter can land on walls, windows, etc. and works with diagonals. --- code/modules/projectiles/projectile.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index f2beec3f6bc..298a61ee98b 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -76,6 +76,7 @@ var/splatter_dir = dir if(starting) splatter_dir = get_dir(starting, target_loca) + target_loca = get_step(target_loca, splatter_dir) if(isalien(L)) new /obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir) else From 849f69825650291d822c622206f766b0419c0f23 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Fri, 21 Jul 2017 21:59:39 -0400 Subject: [PATCH 2/6] Respects Walls and our Inability to see Through Them & Xenosplatter Fix Pixel shifts blood onto non-floor structures, thus respecting viewing angles. You are no longer able to see blood splattered on a wall from the other side unless you've x-ray vision. This also fixes a bug where xeno blood splatters were red. --- code/__HELPERS/unsorted.dm | 24 ++++++++++++++++++ code/game/objects/effects/overlays.dm | 1 + code/modules/projectiles/projectile.dm | 8 ++++-- code/modules/surgery/organs/blood.dm | 34 +++++++++++++++++--------- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 3900ba2ba33..b88e3aa492a 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1871,3 +1871,27 @@ var/global/list/g_fancy_list_of_types = null num_sample -= num result += (1 << num) return result + +/proc/pixel_shift_dir(var/dir, var/amount_x = 32, var/amount_y = 32) //Returns a list with pixel_shift values that will shift an object's icon one tile in the direction passed. + amount_x = min(max(0, amount_x), 32) //No less than 0, no greater than 32. + amount_y = min(max(0, amount_x), 32) + var/list/shift = list("x" = 0, "y" = 0) + switch(dir) + if(NORTH) + shift["y"] = amount_y + if(SOUTH) + shift["y"] = -amount_y + if(EAST) + shift["x"] = amount_x + if(WEST) + shift["x"] = -amount_x + if(NORTHEAST) + shift = list("x" = amount_x, "y" = amount_y) + if(NORTHWEST) + shift = list("x" = -amount_x, "y" = amount_y) + if(SOUTHEAST) + shift = list("x" = amount_x, "y" = -amount_y) + if(SOUTHWEST) + shift = list("x" = -amount_x, "y" = -amount_y) + + return shift diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 2dd8502d662..cb5ff20d184 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -205,6 +205,7 @@ animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration) /obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter + color = null splatter_type = "xsplatter" /obj/effect/overlay/wall_rot diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 298a61ee98b..fa73cfab29f 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -76,7 +76,6 @@ var/splatter_dir = dir if(starting) splatter_dir = get_dir(starting, target_loca) - target_loca = get_step(target_loca, splatter_dir) if(isalien(L)) new /obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir) else @@ -86,7 +85,12 @@ blood_color = H.species.blood_color new /obj/effect/overlay/temp/dir_setting/bloodsplatter(target_loca, splatter_dir, blood_color) if(prob(33)) - L.add_splatter_floor(target_loca) + var/list/shift = list("x" = 0, "y" = 0) + if(!istype(get_step(target_loca, splatter_dir), /turf/simulated/floor)) //If one step in the splatter direction isn't a floor... + shift = pixel_shift_dir(splatter_dir) + else //Pixel shift the blood there instead (so you can't see wallsplatter through walls). + target_loca = get_step(target_loca, splatter_dir) + L.add_splatter_floor(target_loca, shift_x = shift["x"], shift_y = shift["y"]) var/organ_hit_text = "" if(L.has_limbs) diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index 987b5cf53e4..ba27270d63b 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -229,7 +229,7 @@ return list("O-", "O+") //to add a splatter of blood or other mob liquid. -/mob/living/proc/add_splatter_floor(turf/T, small_drip) +/mob/living/proc/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) if(get_blood_id() != "blood")//is it blood or welding fuel? return if(!T) @@ -260,29 +260,41 @@ return // Find a blood decal or create a new one. - var/obj/effect/decal/cleanable/blood/B = locate() in T - if(!B) + var/obj/effect/decal/cleanable/blood/B + if(!(locate(B) in T) || pixel_x || pixel_y) B = new /obj/effect/decal/cleanable/blood/splatter(T) + else + B = locate() in T B.transfer_mob_blood_dna(src) //give blood info to the blood decal. if(temp_blood_DNA) B.blood_DNA |= temp_blood_DNA + B.pixel_x = (shift_x) + B.pixel_y = (shift_y) B.update_icon() -/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip) +/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) if(!(NO_BLOOD in species.species_traits)) ..() -/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip) +/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) if(!T) T = get_turf(src) - var/obj/effect/decal/cleanable/blood/xeno/B = locate() in T.contents - if(!B) + var/obj/effect/decal/cleanable/blood/xeno/B + if(!(locate(B) in T) || pixel_x || pixel_y) B = new(T) + else + B = locate() in T B.blood_DNA["UNKNOWN DNA"] = "X*" + B.pixel_x = (shift_x) + B.pixel_y = (shift_y) -/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip) +/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) if(!T) T = get_turf(src) - var/obj/effect/decal/cleanable/blood/oil/B = locate() in T.contents - if(!B) - B = new(T) \ No newline at end of file + var/obj/effect/decal/cleanable/blood/oil/B + if(!(locate(B) in T) || pixel_x || pixel_y) + B = new(T) + else + B = locate() in T + B.pixel_x = (shift_x) + B.pixel_y = (shift_y) From 8dbfc8ee1d8a7701a2729f7ed985e964d6b5cbae Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Sat, 22 Jul 2017 19:55:21 -0400 Subject: [PATCH 3/6] Respects Windows and our Inability to Pass Them Blood that would splatter onto windows is now pixel-shifted and renders above them so you can A: Clean it with ease and B: See it in all its gorey glory. I had to get creative with how I detected structures blocking blood splatter. Janiborgs riding, sprayers spraying and cleaner grenades foaming over adjacent tiles won't clean off wall/windowblood. You have to use soap and click on the blood. --- code/game/atoms.dm | 9 ++++---- .../effects/decals/Cleanable/humans.dm | 3 ++- .../modules/mob/living/silicon/robot/robot.dm | 10 +++++++-- code/modules/projectiles/projectile.dm | 19 +++++++++++++---- .../reagents/chemistry/reagents/water.dm | 21 +++++++++++++------ code/modules/surgery/organs/blood.dm | 9 ++++++++ 6 files changed, 54 insertions(+), 17 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 8c12e452d1d..06f6ca8a631 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -512,10 +512,11 @@ var/list/blood_splatter_icons = list() overlays += blood_overlay /atom/proc/clean_blood() - germ_level = 0 - if(islist(blood_DNA)) - blood_DNA = null - return 1 + if(!istype(src, /obj/effect/decal/cleanable/blood)) + germ_level = 0 + if(islist(blood_DNA)) + blood_DNA = null + return 1 /obj/item/clean_blood() diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index bb8436340a6..cba5d3f733c 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -23,6 +23,7 @@ var/global/list/image/splatter_cache=list() var/amount = 5 appearance_flags = NO_CLIENT_COLOR var/dry_timer = 0 + var/off_floor = FALSE /obj/effect/decal/cleanable/blood/New() ..() @@ -89,7 +90,7 @@ var/global/list/image/splatter_cache=list() //Add "bloodiness" of this blood's type, to the human's shoes /obj/effect/decal/cleanable/blood/Crossed(atom/movable/O) - if(ishuman(O)) + if(!off_floor && ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/organ/external/l_foot = H.get_organ("l_foot") var/obj/item/organ/external/r_foot = H.get_organ("r_foot") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 3de8b868430..3f756f465f1 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1157,14 +1157,18 @@ var/list/robot_verbs_default = list( if(module.type == /obj/item/weapon/robot_module/janitor) var/turf/tile = loc if(isturf(tile)) - tile.clean_blood() + var/floor_only = TRUE if(istype(tile, /turf/simulated)) var/turf/simulated/S = tile S.dirt = 0 for(var/A in tile) if(istype(A, /obj/effect)) if(is_cleanable(A)) - qdel(A) + var/obj/effect/decal/cleanable/blood/B = A + if(istype(B) && B.off_floor) + floor_only = FALSE + else + qdel(A) else if(istype(A, /obj/item)) var/obj/item/cleaned_item = A cleaned_item.clean_blood() @@ -1185,6 +1189,8 @@ var/list/robot_verbs_default = list( cleaned_human.update_inv_shoes(0,0) cleaned_human.clean_blood() to_chat(cleaned_human, "[src] cleans your face!") + if(floor_only) + tile.clean_blood() return #undef BORG_CAMERA_BUFFER diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index fa73cfab29f..07ca1d02f27 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -86,10 +86,12 @@ new /obj/effect/overlay/temp/dir_setting/bloodsplatter(target_loca, splatter_dir, blood_color) if(prob(33)) var/list/shift = list("x" = 0, "y" = 0) - if(!istype(get_step(target_loca, splatter_dir), /turf/simulated/floor)) //If one step in the splatter direction isn't a floor... - shift = pixel_shift_dir(splatter_dir) - else //Pixel shift the blood there instead (so you can't see wallsplatter through walls). - target_loca = get_step(target_loca, splatter_dir) + var/turf/step_over = get_step(target_loca, splatter_dir) + + if(get_splatter_blockage(step_over, target, splatter_dir, target_loca)) //If you can't cross the tile or any of its relevant obstacles... + shift = pixel_shift_dir(splatter_dir) //Pixel shift the blood there instead (so you can't see wallsplatter through walls). + else + target_loca = step_over L.add_splatter_floor(target_loca, shift_x = shift["x"], shift_y = shift["y"]) var/organ_hit_text = "" @@ -115,6 +117,15 @@ add_logs(firer, L, "shot", src, reagent_note) return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) +/obj/item/projectile/proc/get_splatter_blockage(var/turf/step_over, var/atom/target, var/splatter_dir, var/target_loca) //Check whether the place we want to splatter blood is blocked (i.e. by windows). + var/turf/step_cardinal = !(splatter_dir in list(NORTH, SOUTH, EAST, WEST)) ? get_step(target_loca, get_cardinal_dir(target_loca, step_over)) : null + + if(step_over.density && !step_over.CanPass(target, step_over, 1)) //Preliminary simple check. + return 1 + for(var/atom/movable/border_obstacle in step_over) //Check to see if we're blocked by a (non-full) window or some such. Do deeper investigation if we're splattering blood diagonally. + if(border_obstacle.flags&ON_BORDER && get_dir(step_cardinal ? step_cardinal : target_loca, step_over) == turn(border_obstacle.dir, 180)) + return 1 + /obj/item/projectile/proc/vol_by_damage() if(damage) return Clamp((damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index c1c3191c5ba..afc7e805e0d 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -132,18 +132,27 @@ taste_message = "floor cleaner" /datum/reagent/space_cleaner/reaction_obj(obj/O, volume) - if(istype(O, /obj/effect/decal/cleanable)) - qdel(O) + if(is_cleanable(O)) + var/obj/effect/decal/cleanable/blood/B = O + if(!(istype(B) && B.off_floor)) + qdel(O) else - O.color = initial(O.color) + if(!istype(O, /atom/movable/lighting_overlay)) + O.color = initial(O.color) O.clean_blood() /datum/reagent/space_cleaner/reaction_turf(turf/T, volume) if(volume >= 1) - T.color = initial(T.color) - T.clean_blood() + var/floor_only = TRUE for(var/obj/effect/decal/cleanable/C in src) - qdel(C) + var/obj/effect/decal/cleanable/blood/B = C + if(istype(B) && B.off_floor) + floor_only = FALSE + else + qdel(C) + T.color = initial(T.color) + if(floor_only) + T.clean_blood() for(var/mob/living/carbon/slime/M in T) M.adjustToxLoss(rand(5,10)) diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index ba27270d63b..bc19b6c6159 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -271,6 +271,9 @@ B.pixel_x = (shift_x) B.pixel_y = (shift_y) B.update_icon() + if(shift_x || shift_y) + B.off_floor = TRUE + B.layer = BELOW_MOB_LAYER //So the blood lands ontop of things like posters, windows, etc. /mob/living/carbon/human/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) if(!(NO_BLOOD in species.species_traits)) @@ -287,6 +290,9 @@ B.blood_DNA["UNKNOWN DNA"] = "X*" B.pixel_x = (shift_x) B.pixel_y = (shift_y) + if(shift_x || shift_y) + B.off_floor = TRUE + B.layer = BELOW_MOB_LAYER /mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) if(!T) @@ -298,3 +304,6 @@ B = locate() in T B.pixel_x = (shift_x) B.pixel_y = (shift_y) + if(shift_x || shift_y) + B.off_floor = TRUE + B.layer = BELOW_MOB_LAYER From 00a65b4fc14fd556c5efe107f5f7bd15c1ba8347 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Sun, 23 Jul 2017 14:23:31 -0400 Subject: [PATCH 4/6] Truth. --- code/game/atoms.dm | 2 +- code/modules/projectiles/projectile.dm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 06f6ca8a631..823e6dcad8f 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -516,7 +516,7 @@ var/list/blood_splatter_icons = list() germ_level = 0 if(islist(blood_DNA)) blood_DNA = null - return 1 + return TRUE /obj/item/clean_blood() diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 07ca1d02f27..fee2524cb41 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -121,10 +121,10 @@ var/turf/step_cardinal = !(splatter_dir in list(NORTH, SOUTH, EAST, WEST)) ? get_step(target_loca, get_cardinal_dir(target_loca, step_over)) : null if(step_over.density && !step_over.CanPass(target, step_over, 1)) //Preliminary simple check. - return 1 + return TRUE for(var/atom/movable/border_obstacle in step_over) //Check to see if we're blocked by a (non-full) window or some such. Do deeper investigation if we're splattering blood diagonally. if(border_obstacle.flags&ON_BORDER && get_dir(step_cardinal ? step_cardinal : target_loca, step_over) == turn(border_obstacle.dir, 180)) - return 1 + return TRUE /obj/item/projectile/proc/vol_by_damage() if(damage) From 258df0caadb598e3ca0ff129b866d77e79746522 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Thu, 10 Aug 2017 22:40:44 -0400 Subject: [PATCH 5/6] Blood Spray now Lands on Mobs in Path of Splatter Whether the blood is pixel-shifted there or not, if there's a mob that can be splattered, they will be. --- code/modules/projectiles/projectile.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index fee2524cb41..dfbcdf935b8 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -71,6 +71,7 @@ if(!isliving(target)) return 0 var/mob/living/L = target + var/mob/living/carbon/human/H if(blocked < 100) // not completely blocked if(damage && L.blood_volume && damage_type == BRUTE) var/splatter_dir = dir @@ -81,7 +82,7 @@ else var/blood_color = "#C80000" if(ishuman(target)) - var/mob/living/carbon/human/H = target + H = target blood_color = H.species.blood_color new /obj/effect/overlay/temp/dir_setting/bloodsplatter(target_loca, splatter_dir, blood_color) if(prob(33)) @@ -93,6 +94,10 @@ else target_loca = step_over L.add_splatter_floor(target_loca, shift_x = shift["x"], shift_y = shift["y"]) + if(istype(H)) + for(var/mob/living/carbon/human/M in step_over) //Bloody the mobs who're infront of the spray. + M.bloody_hands(H) + M.bloody_body(H) var/organ_hit_text = "" if(L.has_limbs) From dd683fa0810d5e715a73c779c937a56ea7e23681 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Wed, 13 Dec 2017 21:20:19 -0500 Subject: [PATCH 6/6] Comment body-bloodying out until it gets fixed. "So, there's a bit of a bug with the blood system- specifically bloody_body. It doesn't always transfer the color of the blood correctly, for no apparent reason." - Tigercat2000 --- code/modules/projectiles/projectile.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index dfbcdf935b8..71ac935153b 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -97,7 +97,8 @@ if(istype(H)) for(var/mob/living/carbon/human/M in step_over) //Bloody the mobs who're infront of the spray. M.bloody_hands(H) - M.bloody_body(H) + /* Uncomment when bloody_body stops randomly not transferring blood colour. + M.bloody_body(H) */ var/organ_hit_text = "" if(L.has_limbs)