From 3971a14e34d43f1b280f6f5a7bd57975060f99c9 Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Sat, 21 Oct 2023 17:16:31 -0700 Subject: [PATCH] Fix cluster and incend OB not respecting ceiling protections (#4746) # About the pull request This PR makes it so incend and cluster OBs actually respect ceiling protections (not just pylon protections). HE already is respecting closed areas, so your fault for leaving the doors open. # Explain why it's good for the game Dropships ceilings were changed fairly long ago to protect against OBs, but the implementation I guess was never tested thoroughly. # Testing Photographs and Procedure
Screenshots & Videos ![incend](https://github.com/cmss13-devs/cmss13/assets/76988376/76907e59-d95d-4ddd-8165-864fa688e8c6) https://youtu.be/Fc0q9p6hmeE
# Changelog :cl: Drathek fix: Fix incend and cluster OBs not respecting ceiling OB protections. /:cl: --- code/__DEFINES/__game.dm | 13 ++++- code/modules/cm_marines/orbital_cannon.dm | 10 ++-- .../modules/projectiles/guns/flamer/flamer.dm | 50 +++++++++++-------- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/code/__DEFINES/__game.dm b/code/__DEFINES/__game.dm index 113b78dbada1..f1424f5560ec 100644 --- a/code/__DEFINES/__game.dm +++ b/code/__DEFINES/__game.dm @@ -283,7 +283,6 @@ block( \ /// Only use the CEILING_PROTECTION_TIER_X defines for `protection_level` #define CEILING_IS_PROTECTED(ceiling, protection_level) (ceiling >= protection_level) - // Default font settings #define FONT_SIZE "5pt" #define DEFAULT_FONT_COLOR "#09f" @@ -493,6 +492,18 @@ block( \ #define TURF_PROTECTION_CAS 2 #define TURF_PROTECTION_OB 3 +/// Convert a turf protection level to a ceiling protection level +/proc/get_ceiling_protection_level(turf_protection_level) + switch(turf_protection_level) + if(TURF_PROTECTION_OB) + return CEILING_PROTECTION_TIER_4 + if(TURF_PROTECTION_CAS) + return CEILING_PROTECTION_TIER_3 + if(TURF_PROTECTION_MORTAR) + return CEILING_PROTECTION_TIER_2 + else + return CEILING_NO_PROTECTION + // Anything above the deck boundary is the upper deck, anything below is the lower deck // This is exclusive, so anything ON the boundary is an edge case that's neither on the upper nor the lower deck #define ALMAYER_DECK_BOUNDARY 101 diff --git a/code/modules/cm_marines/orbital_cannon.dm b/code/modules/cm_marines/orbital_cannon.dm index 5a3cad590c08..78bdfc3d778c 100644 --- a/code/modules/cm_marines/orbital_cannon.dm +++ b/code/modules/cm_marines/orbital_cannon.dm @@ -538,10 +538,14 @@ var/list/ob_type_fuel_requirements for(var/i = 1 to total_amount) for(var/k = 1 to instant_amount) - var/turf/U = pick(turf_list) - if(protected_by_pylon(TURF_PROTECTION_OB, U)) //If the turf somehow gained OB protection while the cluster was firing + var/turf/selected_turf = pick(turf_list) + if(protected_by_pylon(TURF_PROTECTION_OB, selected_turf)) continue - fire_in_a_hole(U) + var/area/selected_area = get_area(selected_turf) + if(CEILING_IS_PROTECTED(selected_area?.ceiling, CEILING_PROTECTION_TIER_4)) + continue + fire_in_a_hole(selected_turf) + sleep(delay_between_clusters) QDEL_IN(src, 5 SECONDS) // Leave time for last handle_ob_shake below diff --git a/code/modules/projectiles/guns/flamer/flamer.dm b/code/modules/projectiles/guns/flamer/flamer.dm index 1091df3391b6..d562d305c28b 100644 --- a/code/modules/projectiles/guns/flamer/flamer.dm +++ b/code/modules/projectiles/guns/flamer/flamer.dm @@ -719,12 +719,12 @@ GLOBAL_LIST_EMPTY(flamer_particles) var/direction_angle = dir2angle(direction) var/obj/flamer_fire/foundflame = locate() in target if(!foundflame) - var/datum/reagent/R = new() - R.intensityfire = burn_lvl - R.durationfire = fire_lvl - R.burn_sprite = burn_sprite - R.burncolor = f_color - new/obj/flamer_fire(target, cause_data, R) + var/datum/reagent/fire_reag = new() + fire_reag.intensityfire = burn_lvl + fire_reag.durationfire = fire_lvl + fire_reag.burn_sprite = burn_sprite + fire_reag.burncolor = f_color + new/obj/flamer_fire(target, cause_data, fire_reag) if(target.density) return @@ -751,25 +751,29 @@ GLOBAL_LIST_EMPTY(flamer_particles) if (spread_power < 1) continue - var/turf/T = get_step(target, spread_direction) + var/turf/picked_turf = get_step(target, spread_direction) - if(!T) //prevents trying to spread into "null" (edge of the map?) + if(!picked_turf) //prevents trying to spread into "null" (edge of the map?) continue - if(aerial_flame_level && (T.get_pylon_protection_level() >= aerial_flame_level)) - break + if(aerial_flame_level) + if(picked_turf.get_pylon_protection_level() >= aerial_flame_level) + break + var/area/picked_area = get_area(picked_turf) + if(CEILING_IS_PROTECTED(picked_area?.ceiling, get_ceiling_protection_level(aerial_flame_level))) + break spawn(0) - fire_spread_recur(T, cause_data, spread_power, spread_direction, fire_lvl, burn_lvl, f_color, burn_sprite, aerial_flame_level) + fire_spread_recur(picked_turf, cause_data, spread_power, spread_direction, fire_lvl, burn_lvl, f_color, burn_sprite, aerial_flame_level) /proc/fire_spread(turf/target, datum/cause_data/cause_data, range, fire_lvl, burn_lvl, f_color, burn_sprite = "dynamic", aerial_flame_level = TURF_PROTECTION_NONE) - var/datum/reagent/R = new() - R.intensityfire = burn_lvl - R.durationfire = fire_lvl - R.burn_sprite = burn_sprite - R.burncolor = f_color + var/datum/reagent/fire_reag = new() + fire_reag.intensityfire = burn_lvl + fire_reag.durationfire = fire_lvl + fire_reag.burn_sprite = burn_sprite + fire_reag.burncolor = f_color - new/obj/flamer_fire(target, cause_data, R) + new/obj/flamer_fire(target, cause_data, fire_reag) for(var/direction in alldirs) var/spread_power = range switch(direction) @@ -777,7 +781,11 @@ GLOBAL_LIST_EMPTY(flamer_particles) spread_power-- else spread_power -= 1.414 //diagonal spreading - var/turf/T = get_step(target, direction) - if(aerial_flame_level && (T.get_pylon_protection_level() >= aerial_flame_level)) - continue - fire_spread_recur(T, cause_data, spread_power, direction, fire_lvl, burn_lvl, f_color, burn_sprite, aerial_flame_level) + var/turf/picked_turf = get_step(target, direction) + if(aerial_flame_level) + if(picked_turf.get_pylon_protection_level() >= aerial_flame_level) + continue + var/area/picked_area = get_area(picked_turf) + if(CEILING_IS_PROTECTED(picked_area?.ceiling, get_ceiling_protection_level(aerial_flame_level))) + continue + fire_spread_recur(picked_turf, cause_data, spread_power, direction, fire_lvl, burn_lvl, f_color, burn_sprite, aerial_flame_level)