Assorted atmos performance improvements. (#27966)

This commit is contained in:
Charlie Nolan
2025-01-20 15:18:32 +00:00
committed by GitHub
parent 8954a8e401
commit fdbd2b2050
13 changed files with 271 additions and 230 deletions
@@ -94,21 +94,14 @@
if(Old == parent)
parent = New
/obj/machinery/atmospherics/unary/unsafe_pressure_release(mob/user, pressures)
/obj/machinery/atmospherics/unary/unsafe_pressure_release(mob/user, pressure)
..()
var/turf/T = get_turf(src)
if(T)
var/datum/milla_safe/unary_unsafe_pressure_release/milla = new()
milla.invoke_async(src, pressures)
if(!T)
return
/datum/milla_safe/unary_unsafe_pressure_release
var/lost = pressure * CELL_VOLUME / (air_contents.temperature() * R_IDEAL_GAS_EQUATION)
/datum/milla_safe/unary_unsafe_pressure_release/on_run(obj/machinery/atmospherics/unary/device, pressures)
//Remove the gas from air_contents and assume it
var/turf/T = get_turf(device)
var/datum/gas_mixture/environment = get_turf_air(T)
var/lost = pressures * environment.volume / (device.air_contents.temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/to_release = device.air_contents.remove(lost)
environment.merge(to_release)
var/datum/gas_mixture/to_release = air_contents.remove(lost)
T.blind_release_air(to_release)
@@ -108,69 +108,71 @@
update_underlays()
/obj/machinery/atmospherics/unary/vent_pump/process_atmos()
var/datum/milla_safe/vent_pump_process/milla = new()
milla.invoke_async(src)
/datum/milla_safe/vent_pump_process
/datum/milla_safe/vent_pump_process/on_run(obj/machinery/atmospherics/unary/vent_pump/vent_pump)
if(vent_pump.stat & (NOPOWER|BROKEN))
if(stat & (NOPOWER|BROKEN))
return FALSE
if(QDELETED(vent_pump.parent))
if(QDELETED(parent))
// We're orphaned!
return FALSE
var/turf/T = get_turf(vent_pump)
var/turf/T = get_turf(src)
if(T.density) //No, you should not be able to get free air from walls
return
if(!vent_pump.node)
vent_pump.on = FALSE
if(!vent_pump.on)
if(!node)
on = FALSE
if(!on)
return FALSE
if(vent_pump.welded)
if(vent_pump.air_contents.return_pressure() >= vent_pump.weld_burst_pressure && prob(5)) //the weld is on but the cover is welded shut, can it withstand the internal pressure?
vent_pump.visible_message("<span class='danger'>The welded cover of [vent_pump] bursts open!</span>")
if(welded)
if(air_contents.return_pressure() >= weld_burst_pressure && prob(5)) //the weld is on but the cover is welded shut, can it withstand the internal pressure?
visible_message("<span class='danger'>The welded cover of [src] bursts open!</span>")
for(var/mob/living/M in range(1))
vent_pump.unsafe_pressure_release(M, vent_pump.air_contents.return_pressure()) //let's send everyone flying
vent_pump.welded = FALSE
vent_pump.update_icon()
unsafe_pressure_release(M, air_contents.return_pressure()) //let's send everyone flying
welded = FALSE
update_icon()
return FALSE
var/datum/gas_mixture/environment = get_turf_air(T)
var/environment_pressure = environment.return_pressure()
if(vent_pump.releasing) //internal -> external
var/datum/gas_mixture/environment = T.get_readonly_air()
if(releasing) //internal -> external
var/pressure_delta = 10000
if(vent_pump.pressure_checks == ONLY_CHECK_EXT_PRESSURE)
if(pressure_checks == ONLY_CHECK_EXT_PRESSURE)
// Only checks difference between set pressure and environment pressure
pressure_delta = min(pressure_delta, (vent_pump.external_pressure_bound - environment_pressure))
if(vent_pump.pressure_checks == ONLY_CHECK_INT_PRESSURE)
pressure_delta = min(pressure_delta, (vent_pump.air_contents.return_pressure() - vent_pump.internal_pressure_bound))
pressure_delta = min(pressure_delta, (external_pressure_bound - environment.return_pressure()))
if(pressure_checks == ONLY_CHECK_INT_PRESSURE)
pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound))
if(pressure_delta > 0.5 && vent_pump.air_contents.temperature() > 0)
if(pressure_delta > 0.5 && air_contents.temperature() > 0)
// 1kPa * 1L = 1J
var/wanted_joules = pressure_delta * environment.volume
var/transfer_moles = min(vent_pump.max_transfer_joules, wanted_joules) / (vent_pump.air_contents.temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = vent_pump.air_contents.remove(transfer_moles)
environment.merge(removed)
vent_pump.parent.update = TRUE
var/transfer_moles = min(max_transfer_joules, wanted_joules) / (air_contents.temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
// This isn't exactly "blind", but using the data from last tick is good enough for a vent.
T.blind_release_air(removed)
parent.update = TRUE
else //external -> internal
var/pressure_delta = 10000
if(vent_pump.pressure_checks == ONLY_CHECK_EXT_PRESSURE)
pressure_delta = min(pressure_delta, (environment_pressure - vent_pump.external_pressure_bound))
if(vent_pump.pressure_checks == ONLY_CHECK_INT_PRESSURE)
pressure_delta = min(pressure_delta, (vent_pump.internal_pressure_bound - vent_pump.air_contents.return_pressure()))
if(pressure_delta > 0.5 && environment.temperature() > 0)
// 1kPa * 1L = 1J
var/wanted_joules = pressure_delta * environment.volume
var/transfer_moles = min(vent_pump.max_transfer_joules, wanted_joules) / (environment.temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = environment.remove(transfer_moles)
vent_pump.air_contents.merge(removed)
vent_pump.parent.update = TRUE
var/datum/milla_safe/vent_pump_siphon/milla = new()
milla.invoke_async(src)
return TRUE
/datum/milla_safe/vent_pump_siphon
/datum/milla_safe/vent_pump_siphon/on_run(obj/machinery/atmospherics/unary/vent_pump/vent_pump)
var/turf/T = get_turf(vent_pump)
var/datum/gas_mixture/environment = get_turf_air(T)
var/pressure_delta = 10000
if(vent_pump.pressure_checks == ONLY_CHECK_EXT_PRESSURE)
pressure_delta = min(pressure_delta, (environment.return_pressure() - vent_pump.external_pressure_bound))
if(vent_pump.pressure_checks == ONLY_CHECK_INT_PRESSURE)
pressure_delta = min(pressure_delta, (vent_pump.internal_pressure_bound - vent_pump.air_contents.return_pressure()))
if(pressure_delta > 0.5 && environment.temperature() > 0)
// 1kPa * 1L = 1J
var/wanted_joules = pressure_delta * environment.volume
var/transfer_moles = min(vent_pump.max_transfer_joules, wanted_joules) / (environment.temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = environment.remove(transfer_moles)
vent_pump.air_contents.merge(removed)
vent_pump.parent.update = TRUE
/obj/machinery/atmospherics/unary/vent_pump/can_crawl_through()
return !welded
@@ -140,9 +140,31 @@
adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir=1)
/obj/machinery/atmospherics/unary/vent_scrubber/proc/scrub(turf/simulated/tile)
if(!tile || !istype(tile))
return 0
if(scrubbing && !should_scrub(tile.get_readonly_air()))
return 0
var/datum/milla_safe/vent_scrubber_process/milla = new()
milla.invoke_async(src, tile)
/obj/machinery/atmospherics/unary/vent_scrubber/proc/should_scrub(datum/gas_mixture/environment)
if(scrub_O2 && environment.oxygen() > 0.001)
return TRUE
if(scrub_N2 && environment.nitrogen() > 0.001)
return TRUE
if(scrub_CO2 && environment.carbon_dioxide() > 0.001)
return TRUE
if(scrub_Toxins && environment.toxins() > 0.001)
return TRUE
if(environment.sleeping_agent() > 0.001)
return TRUE
if(environment.agent_b() > 0.001)
return TRUE
return FALSE
/datum/milla_safe/vent_scrubber_process
/datum/milla_safe/vent_scrubber_process/on_run(obj/machinery/atmospherics/unary/vent_scrubber/scrubber, turf/simulated/tile)
@@ -152,7 +174,7 @@
var/datum/gas_mixture/environment = get_turf_air(tile)
if(scrubber.scrubbing)
if((scrubber.scrub_O2 && environment.oxygen() > 0.001) || (scrubber.scrub_N2 && environment.nitrogen() > 0.001) || (scrubber.scrub_CO2 && environment.carbon_dioxide() > 0.001) || (scrubber.scrub_Toxins && environment.toxins() > 0.001) || (environment.sleeping_agent()) || (environment.agent_b()))
if(scrubber.should_scrub(environment))
var/transfer_moles = min(1, scrubber.volume_rate / environment.volume) * environment.total_moles()
//Take a gas sample