diff --git a/code/modules/swarmers/swarmer_act.dm b/code/modules/swarmers/swarmer_act.dm index 6590cacd9d5..8db93146619 100644 --- a/code/modules/swarmers/swarmer_act.dm +++ b/code/modules/swarmers/swarmer_act.dm @@ -5,6 +5,31 @@ * Arguments: * * S - A reference to the swarmer doing the interaction */ +#define DANGEROUS_DELTA_P 250 //Value in kPa where swarmers arent allowed to break a wall or window with this difference in pressure. + +///Finds the greatest difference in pressure across a turf, only considers open turfs. +/turf/proc/return_turf_delta_p() + var/pressure_greatest = 0 + var/pressure_smallest = INFINITY //Freaking terrified to use INFINITY, man + for(var/t in RANGE_TURFS(1, src)) //Begin processing the delta pressure across the wall. + var/turf/open/turf_adjacent = t + if(!istype(turf_adjacent)) + continue + pressure_greatest = max(pressure_greatest, turf_adjacent.air.return_pressure()) + pressure_smallest = min(pressure_smallest, turf_adjacent.air.return_pressure()) + + return pressure_greatest - pressure_smallest + +///Runs through all adjacent open turfs and checks if any are planetary_atmos returns true if even one passes. +/turf/proc/is_nearby_planetary_atmos() + . = FALSE + for(var/t in RANGE_TURFS(1, src)) + if(!isopenturf(t)) + continue + var/turf/open/turf_adjacent = t + if(turf_adjacent.planetary_atmos) + return TRUE + /atom/proc/swarmer_act(mob/living/simple_animal/hostile/swarmer/actor) actor.dis_integrate(src) return TRUE //return TRUE/FALSE whether or not an AI swarmer should try this swarmer_act() again, NOT whether it succeeded. @@ -85,10 +110,17 @@ var/isonshuttle = istype(get_area(src), /area/shuttle) for(var/turf/turf_in_range in range(1, src)) var/area/turf_area = get_area(turf_in_range) - if(isspaceturf(turf_in_range) || (!isonshuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (isonshuttle && !istype(turf_area, /area/shuttle))) + //Check for dangerous pressure differences + if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P) + to_chat(actor, "Destroying this object has the potential to cause an explosive pressure release. Aborting.") + actor.target = null + return TRUE + //Check if breaking this door will expose the station to space/planetary atmos + else if(turf_in_range.is_nearby_planetary_atmos() || isspaceturf(turf_in_range) || (!isonshuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (isonshuttle && !istype(turf_area, /area/shuttle))) to_chat(actor, "Destroying this object has the potential to cause a hull breach. Aborting.") actor.target = null return FALSE + //Check if this door is important in supermatter containment else if(istype(turf_area, /area/engine/supermatter)) to_chat(actor, "Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.") actor.target = null @@ -166,7 +198,11 @@ var/isonshuttle = istype(loc, /area/shuttle) for(var/turf/turf_in_range in range(1, src)) var/area/turf_area = get_area(turf_in_range) - if(isspaceturf(turf_area) || (!isonshuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (isonshuttle && !istype(turf_area, /area/shuttle))) + if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P) + to_chat(actor, "Destroying this object has the potential to cause an explosive pressure release. Aborting.") + actor.target = null + return TRUE + else if(turf_in_range.is_nearby_planetary_atmos() || isspaceturf(turf_area) || (!isonshuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (isonshuttle && !istype(turf_area, /area/shuttle) )) to_chat(actor, "Destroying this object has the potential to cause a hull breach. Aborting.") actor.target = null return TRUE @@ -178,13 +214,18 @@ /obj/structure/window/swarmer_act(mob/living/simple_animal/hostile/swarmer/actor) var/is_on_shuttle = istype(get_area(src), /area/shuttle) - for(var/turf/adj_turf in range(1, src)) - var/area/adj_area = get_area(adj_turf) - if(isspaceturf(adj_turf) || (!is_on_shuttle && (istype(adj_area, /area/shuttle) || istype(adj_area, /area/space))) || (is_on_shuttle && !istype(adj_area, /area/shuttle))) + for(var/t in RANGE_TURFS(1, src)) + var/turf/turf_in_range = t + var/area/turf_area = get_area(turf_in_range) + if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P) + to_chat(actor, "Destroying this object has the potential to cause an explosive pressure release. Aborting.") + actor.target = null + return TRUE + else if(turf_in_range.is_nearby_planetary_atmos() || isspaceturf(turf_in_range) || (!is_on_shuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (is_on_shuttle && !istype(turf_area, /area/shuttle))) to_chat(actor, "Destroying this object has the potential to cause a hull breach. Aborting.") actor.target = null return TRUE - if(istype(adj_area, /area/engine/supermatter)) + else if(istype(turf_area, /area/engine/supermatter)) to_chat(actor, "Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.") actor.target = null return TRUE @@ -229,3 +270,5 @@ /obj/machinery/shieldwall/swarmer_act(mob/living/simple_animal/hostile/swarmer/actor) to_chat(actor, "This object does not contain solid matter. Aborting.") return FALSE + +#undef DANGEROUS_DELTA_P