diff --git a/code/ATMOSPHERICS/_atmospherics_helpers.dm b/code/ATMOSPHERICS/_atmospherics_helpers.dm index 149ac5f1b1..d675e905a8 100644 --- a/code/ATMOSPHERICS/_atmospherics_helpers.dm +++ b/code/ATMOSPHERICS/_atmospherics_helpers.dm @@ -29,8 +29,6 @@ if (source.total_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing return -1 - //var/source_moles_initial = source.total_moles - if (isnull(transfer_moles)) transfer_moles = source.total_moles else @@ -69,6 +67,40 @@ return power_draw +//Gas 'pumping' proc for the case where the gas flow is passive and driven entirely by pressure differences (but still one-way). +/proc/pump_gas_passive(var/obj/machinery/M, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null) + if (source.total_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + return -1 + + if (isnull(transfer_moles)) + transfer_moles = source.total_moles + else + transfer_moles = min(source.total_moles, transfer_moles) + + var/equalize_moles = calculate_equalize_moles(source, sink) + transfer_moles = min(transfer_moles, equalize_moles) + + if (transfer_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + return -1 + + //Update flow rate meter + if (istype(M, /obj/machinery/atmospherics)) + var/obj/machinery/atmospherics/A = M + A.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here + if (A.debug) + A.visible_message("[A]: moles transferred = [transfer_moles] mol") + + if (istype(M, /obj/machinery/portable_atmospherics)) + var/obj/machinery/portable_atmospherics/P = M + P.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here + + var/datum/gas_mixture/removed = source.remove(transfer_moles) + if(!removed) //Just in case + return -1 + sink.merge(removed) + + return 0 + //Generalized gas scrubbing proc. //Selectively moves specified gasses one gas_mixture to another and returns the amount of power needed (assuming 1 second), or -1 if no gas was filtered. //filtering - A list of gasids to be scrubbed from source @@ -400,4 +432,17 @@ var/output_volume = (sink.volume * sink.group_multiplier) + sink_volume_mod //get the number of moles that would have to be transfered to bring sink to the target pressure - return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) \ No newline at end of file + return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) + +//Calculates the APPROXIMATE amount of moles that would need to be transferred to bring source and sink to the same pressure +/proc/calculate_equalize_moles(datum/gas_mixture/source, datum/gas_mixture/sink) + if(source.temperature == 0) return 0 + + //Make the approximation that the sink temperature is unchanged after transferring gas + var/source_volume = source.volume * source.group_multiplier + var/sink_volume = sink.volume * sink.group_multiplier + + var/source_pressure = source.return_pressure() + var/sink_pressure = sink.return_pressure() + + return (source_pressure - sink_pressure)/(R_IDEAL_GAS_EQUATION * (source.temperature/source_volume + sink.temperature/sink_volume)) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 3bd9fdae2b..0ec10aa582 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -80,7 +80,7 @@ transfer_moles = min(transfer_moles, calculate_transfer_moles(air1, air2, pressure_delta, (network2)? network2.volume : 0)) //pump_gas() will return a negative number if no flow occurred - returnval = pump_gas(src, air1, air2, transfer_moles, available_power=0) //available_power=0 means we only move gas if it would flow naturally + returnval = pump_gas_passive(src, air1, air2, transfer_moles) if (returnval >= 0) if(network1) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 4d96320518..78d7d48651 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -8,6 +8,7 @@ var/valve_open = 0 var/release_pressure = ONE_ATMOSPHERE + var/release_flow_rate = ATMOS_DEFAULT_VOLUME_PUMP //in L/s var/canister_color = "yellow" var/can_label = 1 @@ -175,21 +176,15 @@ update_flag environment = loc.return_air() var/env_pressure = environment.return_pressure() - var/pressure_delta = min(release_pressure - env_pressure, (air_contents.return_pressure() - env_pressure)/2) - //Can not have a pressure delta that would cause environment pressure > tank pressure + var/pressure_delta = release_pressure - env_pressure - var/transfer_moles = 0 if((air_contents.temperature > 0) && (pressure_delta > 0)) - transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION) + var/transfer_moles = calculate_transfer_moles(air_contents, environment, pressure_delta) + transfer_moles = min(transfer_moles, (release_flow_rate/air_contents.volume)*air_contents.total_moles) //flow rate limit - //Actually transfer the gas - var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) - - if(holding) - environment.merge(removed) - else - loc.assume_air(removed) - src.update_icon() + var/returnval = pump_gas_passive(src, air_contents, environment, transfer_moles) + if(returnval >= 0) + src.update_icon() if(air_contents.return_pressure() < 1) can_label = 1