Adds gas filtering proc

This commit is contained in:
mwerezak
2014-08-01 20:37:48 -04:00
parent 400c1b5cf6
commit f0016df4f3

View File

@@ -2,22 +2,26 @@
Atmos processes
These procs generalize various processes used by atmos machinery, such as pumping, filtering, or scrubbing gas, allowing them to be reused elsewhere.
If no gas was moved/pumped/filtered/whatever, they return a negative number.
Otherwise they return the amount of energy needed to do whatever it is they do (equivalently power if done over 1 second).
In the case of free-flowing gas you can do things with gas and still use 0 power, hence the distinction between negative and non-negative return values.
*/
/obj/machinery/atmospherics/var/last_flow_rate = 0 //Can't return multiple values, unfortunately
//Generalized gas pumping proc.
//Moves gas from one gas_mixture to another and returns the amount of power needed (assuming 1 second), or -1 if no gas was pumped.
//transfer_moles - Limits the amount of moles to transfer. The actual amount of gas moved may also be limited by available_power, if given.
//available_power - the maximum amount of power that may be used when moving gas. If null then the transfer is not limited by power.
/obj/machinery/atmospherics/var/last_flow_rate = 0 //Can't return multiple values, unfortunately...
/obj/machinery/atmospherics/proc/pump_gas(var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null, var/available_power = null)
if (source.total_moles < MINUMUM_MOLES_TO_PUMP)
if (source.total_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing
return -1
if (!transfer_moles)
transfer_moles = source.total_moles
else
transfer_moles = min(source.total_moles, transfer_moles)
//Calculate the amount of energy required and limit transfer_moles based on available power
var/specific_power = calculate_specific_power(source, sink)/ATMOS_PUMP_EFFICIENCY //this has to be calculated before we modify any gas mixtures
@@ -30,7 +34,7 @@
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 (isnull(removed)) //not sure why this would happen, but it does at the very beginning of the game
if (!removed) //Just in case
return -1
var/power_draw = specific_power*transfer_moles
@@ -47,7 +51,7 @@
//total_transfer_moles - Limits the amount of moles to scrub. The actual amount of gas scrubbed may also be limited by available_power, if given.
//available_power - the maximum amount of power that may be used when scrubbing gas. If null then the scrubbing is not limited by power.
/obj/machinery/atmospherics/proc/scrub_gas(var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/total_transfer_moles = null, var/available_power = null)
if (source.total_moles < MINUMUM_MOLES_TO_FILTER)
if (source.total_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
filtering &= source.gas //only filter gasses that are actually there.
@@ -63,12 +67,12 @@
specific_power_gas[g] = specific_power
total_filterable_moles += source.gas[g]
if (total_filterable_moles < MINUMUM_MOLES_TO_FILTER)
if (total_filterable_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
var/total_specific_power = 0 //the power required to remove one mole of filterable gas
for (var/g in filtering)
var/ratio = source.gas[g]/total_filterable_moles //converts the specific power per mole of pure gas to specific power per mole of filterable gas mix
var/ratio = source.gas[g]/total_filterable_moles //this converts the specific power per mole of pure gas to specific power per mole of filterable gas mix
total_specific_power = specific_power_gas[g]*ratio
//Figure out how much of each gas to filter
@@ -81,7 +85,7 @@
if (available_power && total_specific_power > 0)
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //we check this repeatedly so that we do as little processing as possible
if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
var/power_draw = 0
@@ -91,19 +95,101 @@
//filter gas in proportion to the mole ratio
transfer_moles = min(transfer_moles, total_transfer_moles*(source.gas[g]/total_filterable_moles))
source.gas[g] -= transfer_moles
sink.gas[g] += transfer_moles //do we need to check if g is in sink.gas first?
//use update=0. All the filtered gasses get added simultaneously, so we update after the for loop.
source.adjust_gas(g, -transfer_moles, update=0)
sink.adjust_gas_temp(g, transfer_moles, source.temperature, update=0)
power_draw += specific_power_gas[g]*transfer_moles
if (power_draw > 0)
sink.add_thermal_energy(power_draw) //gotta conserve that energy
//Remix the resulting gases
sink.update_values()
source.update_values()
if (power_draw > 0)
sink.add_thermal_energy(power_draw) //gotta conserve that energy
return power_draw
//Generalized gas filtering proc.
//Filtering is a bit different from scrubbing. Instead of selectively moving the targeted gas types from one gas mix to another, filtering splits
//the input gas into two outputs: one that contains /only/ the targeted gas types, and another that completely clean of the targeted gas types.
//filtering - A list of gasids to be filtered. These gasses get moved to sink_filtered, while the other gasses get moved to sink_clean.
//total_transfer_moles - Limits the amount of moles to input. The actual amount of gas filtered may also be limited by available_power, if given.
//available_power - the maximum amount of power that may be used when filtering gas. If null then the filtering is not limited by power.
/obj/machinery/atmospherics/proc/filter_gas(var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink_filtered, var/datum/gas_mixture/sink_clean, var/total_transfer_moles = null, var/available_power = null)
if (source.total_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
filtering &= source.gas //only filter gasses that are actually there.
var/list/not_filtering = source.gas - filtering
var/total_filterable_moles = 0
var/total_unfilterable_moles = 0
var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type
for (var/g in source.gas)
if (source.gas[g] < MINUMUM_MOLES_TO_FILTER)
continue
if (g in filtering)
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_filtered)/ATMOS_FILTER_EFFICIENCY
total_filterable_moles += source.gas[g]
else
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_clean)/ATMOS_FILTER_EFFICIENCY
total_unfilterable_moles += source.gas[g]
var/total_specific_power = 0 //the power required to remove one mole of input gas
for (var/g in source.gas)
var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix
total_specific_power = specific_power_gas[g]*ratio
//Figure out how much of each gas to filter
if (!total_transfer_moles)
total_transfer_moles = source.total_moles
else
total_transfer_moles = min(total_transfer_moles, source.total_moles)
//limit transfer_moles based on available power
if (available_power && total_specific_power > 0)
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
var/datum/gas_mixture/removed = source.remove(total_transfer_moles)
if (!removed) //Just in case
return -1
var/filtered_power_used = 0
var/unfiltered_power_used = 0
for (var/g in removed.gas)
var/power_used = specific_power_gas[g]*removed.gas[g]
//use update=0. All the filtered gasses get added simultaneously, so we update after the for loop.
if (g in filtering)
sink_filtered.adjust_gas_temp(g, removed.gas[g], removed.temperature, update=0)
filtered_power_used += power_used
else
sink_clean.adjust_gas_temp(g, removed.gas[g], removed.temperature, update=0)
unfiltered_power_used += power_used
sink_filtered.update_values()
sink_clean.update_values()
del(removed) //removed should have nothing in it now, so we can just get rid of it.
if (filtered_power_used > 0)
sink_filtered.add_thermal_energy(filtered_power_used) //1st law - energy is conserved
if (unfiltered_power_used > 0)
sink_clean.add_thermal_energy(unfiltered_power_used) //1st law - energy is conserved
return filtered_power_used + unfiltered_power_used
/*
Helper procs for various things.
*/
//Calculates the amount of power needed to move one mole from source to sink.
/obj/machinery/atmospherics/proc/calculate_specific_power(datum/gas_mixture/source, datum/gas_mixture/sink)
//Calculate the amount of energy required