mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
Cleans up /proc/find_safe_turf(), documenting and improving code (#93848)
## About The Pull Request `/proc/find_safe_turf()` was cleaned up so that it did not have two arguments that accomplished the same thing, removing opportunities for user errors when calling the proc. Additionally, since I was here, I decided to clean up some of the code and document it. Some thresholds were changed in this PR (the max temperature threshold was dropped from 360K to 340K), but I believe that it's better to keep them consistent instead of using arbitrary values. ## Uncomfortably large gap <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> ## Changelog No user facing changes. <!-- Both 🆑's are required for the changelog to work! You can put your name to the right of the first 🆑 if you want to overwrite your GitHub username as author ingame. --> <!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. --> --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -173,16 +173,20 @@ GLOBAL_LIST_EMPTY(gas_handbook)
|
||||
return null
|
||||
|
||||
/**
|
||||
* A simple helped proc that checks if the contents of a list of gases are within acceptable terms.
|
||||
* A simple helper proc that checks if the contents of a list of gases are within acceptable terms.
|
||||
*
|
||||
* Arguments:
|
||||
* * gases: The list of gases which contents are being checked
|
||||
* * gases to check: An associated list of gas types and acceptable boundaries in moles. e.g. /datum/gas/oxygen = list(16, 30)
|
||||
* * acceptable_gas_bounds: An associated list of gas types and acceptable boundaries in moles. e.g. /datum/gas/oxygen = list(16, 30)
|
||||
* * * if the assoc list is null, then it'll be considered a safe gas and won't return FALSE.
|
||||
* * extraneous_gas_limit: If a gas not in gases is found, this is the limit above which the proc will return FALSE.
|
||||
*
|
||||
* Returns TRUE if the list of gases is acceptable, FALSE otherwise.
|
||||
*/
|
||||
/proc/check_gases(list/gases, list/gases_to_check, extraneous_gas_limit = 0.1)
|
||||
gases_to_check = gases_to_check.Copy()
|
||||
/proc/check_gases(list/gases, list/acceptable_gas_bounds, extraneous_gas_limit = 0.1)
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
|
||||
var/list/gases_to_check = acceptable_gas_bounds.Copy() // thank you spaceman
|
||||
for(var/id in gases)
|
||||
var/gas_moles = gases[id][MOLES]
|
||||
if(!(id in gases_to_check))
|
||||
|
||||
@@ -125,26 +125,53 @@
|
||||
effect.attach(location)
|
||||
effect.start()
|
||||
|
||||
// Safe location finder
|
||||
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE, dense_atoms = FALSE)
|
||||
if(!zlevels)
|
||||
if (zlevel)
|
||||
zlevels = list(zlevel)
|
||||
else
|
||||
zlevels = SSmapping.levels_by_trait(ZTRAIT_STATION)
|
||||
var/cycles = 1000
|
||||
for(var/cycle in 1 to cycles)
|
||||
// DRUNK DIALLING WOOOOOOOOO
|
||||
/**
|
||||
* Attempts to find a "safe" floor turf within some given z-levels
|
||||
* * zlevel_or_levels: The list of z-levels we are searching though. You can supply just a number and it will be turned into a list.
|
||||
* * extended_safety_checks: Will do some additional checks to make sure the destination is safe, see [/proc/is_safe_turf].
|
||||
* * dense_atoms: Will additionally check to see if the turf has any dense obstructions, like machines or structures.
|
||||
*
|
||||
* Returns a safe floor turf,
|
||||
* **BUT** there is a chance of it being null if an extremely large portion of a z-level is unsafe or blocked.
|
||||
*/
|
||||
/proc/find_safe_turf(zlevel_or_levels, extended_safety_checks = FALSE, dense_atoms = FALSE) as /turf/open/floor
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
RETURN_TYPE(/turf/open/floor)
|
||||
|
||||
var/list/zlevels
|
||||
if(islist(zlevel_or_levels))
|
||||
zlevels = zlevel_or_levels
|
||||
else if(zlevel_or_levels)
|
||||
zlevels = list(zlevel_or_levels)
|
||||
else
|
||||
zlevels = SSmapping.levels_by_trait(ZTRAIT_STATION)
|
||||
|
||||
for(var/cycle in 1 to 1000)
|
||||
var/x = rand(1, world.maxx)
|
||||
var/y = rand(1, world.maxy)
|
||||
var/z = pick(zlevels)
|
||||
var/random_location = locate(x,y,z)
|
||||
|
||||
if(is_safe_turf(random_location, extended_safety_checks, dense_atoms, cycle < 300))//if the area is mostly NOTELEPORT (centcom) we gotta give up on this fantasy at some point.
|
||||
var/keep_trying_no_teleport = (cycle < 300) //if the area is mostly NOTELEPORT (centcom) we gotta give up on this fantasy at some point.
|
||||
if(is_safe_turf(random_location, extended_safety_checks, dense_atoms, keep_trying_no_teleport))
|
||||
return random_location
|
||||
|
||||
/// Checks if a given turf is a "safe" location
|
||||
/**
|
||||
* Checks to see if a given turf is a "safe" location. Being safe requires the following to be true:
|
||||
* * Must be a [floor][/turf/open/floor]
|
||||
* * Must have air, and that air must have [breathable bounds][/proc/check_gases] for humans
|
||||
* * Must have goldilocks temperature
|
||||
* * Must have safe pressure
|
||||
*
|
||||
* Optionally:
|
||||
* * extended_safety_checks: Will make additional checks for turfs that technically pass all previous requirements but still may not be safe
|
||||
* * dense_atoms: Must be unobstructed (no blocking objects such as machines, structures or mobs)
|
||||
* * no_teleport: Must not have [NOTELEPORT][/area/var/area_flag]
|
||||
*
|
||||
* Returns TRUE if all conditions pass, FALSE otherwise.
|
||||
*/
|
||||
/proc/is_safe_turf(turf/random_location, extended_safety_checks = FALSE, dense_atoms = FALSE, no_teleport = FALSE)
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
|
||||
. = FALSE
|
||||
if(!isfloorturf(random_location))
|
||||
return
|
||||
@@ -160,18 +187,18 @@
|
||||
|
||||
var/list/floor_gases = floor_gas_mixture.gases
|
||||
var/static/list/gases_to_check = list(
|
||||
/datum/gas/oxygen = list(16, 100),
|
||||
/datum/gas/oxygen = list(/obj/item/organ/lungs::safe_oxygen_min, 100),
|
||||
/datum/gas/nitrogen,
|
||||
/datum/gas/carbon_dioxide = list(0, 10)
|
||||
/datum/gas/carbon_dioxide = list(0, /obj/item/organ/lungs::safe_co2_max)
|
||||
)
|
||||
if(!check_gases(floor_gases, gases_to_check))
|
||||
return FALSE
|
||||
|
||||
// Aim for goldilocks temperatures and pressure
|
||||
if((floor_gas_mixture.temperature <= 270) || (floor_gas_mixture.temperature >= 360))
|
||||
if((floor_gas_mixture.temperature <= BODYTEMP_COLD_DAMAGE_LIMIT) || (floor_gas_mixture.temperature >= BODYTEMP_HEAT_DAMAGE_LIMIT))
|
||||
return
|
||||
var/pressure = floor_gas_mixture.return_pressure()
|
||||
if((pressure <= 20) || (pressure >= 550))
|
||||
if((pressure <= HAZARD_LOW_PRESSURE) || (pressure >= HAZARD_HIGH_PRESSURE))
|
||||
return
|
||||
|
||||
if(extended_safety_checks)
|
||||
|
||||
@@ -135,11 +135,11 @@
|
||||
var/effect_range = 5
|
||||
|
||||
/obj/effect/fun_balloon/scatter/effect()
|
||||
for(var/mob/living/M in range(effect_range, get_turf(src)))
|
||||
var/turf/T = find_safe_turf(zlevel = src.z)
|
||||
new /obj/effect/temp_visual/gravpush(get_turf(M))
|
||||
M.forceMove(T)
|
||||
to_chat(M, span_notice("Pop!"), confidential = TRUE)
|
||||
for(var/mob/living/dispersed_mob in range(effect_range, get_turf(src)))
|
||||
var/turf/drop_off = find_safe_turf(z)
|
||||
new /obj/effect/temp_visual/gravpush(get_turf(dispersed_mob))
|
||||
dispersed_mob.forceMove(drop_off)
|
||||
dispersed_mob.balloon_alert(dispersed_mob, "pop!")
|
||||
|
||||
// ----------- Station Crash
|
||||
// Can't think of anywhere better to put it right now
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
/// Attempts to teleport the passed mob to somewhere safe on the station, if they can use the blade.
|
||||
/obj/item/melee/sickly_blade/proc/seek_safety(mob/user)
|
||||
var/turf/safe_turf = find_safe_turf(zlevels = z, extended_safety_checks = TRUE)
|
||||
var/turf/safe_turf = find_safe_turf(z, extended_safety_checks = TRUE)
|
||||
if(check_usability(user))
|
||||
if(do_teleport(user, safe_turf, channel = TELEPORT_CHANNEL_MAGIC))
|
||||
to_chat(user, span_warning("As you shatter [src], you feel a gust of energy flow through your body. [after_use_message]"))
|
||||
|
||||
@@ -16,19 +16,20 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(tgui_alert(usr,question,name,list("Yes","No")) == "Yes" && Adjacent(user))
|
||||
var/turf/T = zlevels ? find_safe_turf(zlevels=zlevels) : get_safe_random_station_turf_equal_weight()
|
||||
if(tgui_alert(usr,question,name,list("Yes","No")) != "Yes" && !Adjacent(user))
|
||||
return
|
||||
|
||||
if(T)
|
||||
var/atom/movable/AM = user.pulling
|
||||
if(AM)
|
||||
AM.forceMove(T)
|
||||
user.forceMove(T)
|
||||
if(AM)
|
||||
user.start_pulling(AM)
|
||||
to_chat(user, span_notice("You blink and find yourself in [get_area_name(T)]."))
|
||||
else
|
||||
to_chat(user, "Nothing happens. You feel that this is a bad sign.")
|
||||
var/turf/safe_dropoff = zlevels ? find_safe_turf(zlevels) : get_safe_random_station_turf_equal_weight()
|
||||
if(!safe_dropoff)
|
||||
to_chat(user, "Nothing happens. You feel that this is a bad sign.")
|
||||
return
|
||||
|
||||
var/atom/movable/pulled = user.pulling
|
||||
user.forceMove(safe_dropoff)
|
||||
if(pulled)
|
||||
pulled.forceMove(safe_dropoff)
|
||||
user.start_pulling(pulled)
|
||||
to_chat(user, span_notice("You blink and find yourself in [get_area_name(safe_dropoff)]."))
|
||||
|
||||
/obj/structure/signpost/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
|
||||
return interact(user)
|
||||
|
||||
@@ -715,12 +715,12 @@
|
||||
if(healthcheck && (healthcheck - owner.health) > 5)
|
||||
owner.visible_message(span_warning("[linked_extract] notices the sudden change in [owner]'s physical health, and activates!"))
|
||||
do_sparks(5,FALSE,owner)
|
||||
var/F = find_safe_turf(zlevel = owner.z, extended_safety_checks = TRUE)
|
||||
var/turf/emergency_turf = find_safe_turf(owner.z, extended_safety_checks = TRUE)
|
||||
var/range = 0
|
||||
if(!F)
|
||||
F = get_turf(owner)
|
||||
if(!emergency_turf)
|
||||
emergency_turf = get_turf(owner)
|
||||
range = 50
|
||||
if(do_teleport(owner, F, range, channel = TELEPORT_CHANNEL_BLUESPACE))
|
||||
if(do_teleport(owner, emergency_turf, range, channel = TELEPORT_CHANNEL_BLUESPACE))
|
||||
to_chat(owner, span_notice("[linked_extract] will take some time to re-align you on the bluespace axis."))
|
||||
do_sparks(5,FALSE,owner)
|
||||
owner.apply_status_effect(/datum/status_effect/bluespacestabilization)
|
||||
|
||||
Reference in New Issue
Block a user