Adds gas mixing proc and updates gas mixer

Also includes a whole bunch of fixes and updates for atmos machinery
This commit is contained in:
mwerezak
2014-08-02 17:43:08 -04:00
parent d034511ee6
commit 3647fa4d7d
13 changed files with 244 additions and 179 deletions

View File

@@ -25,7 +25,7 @@
//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
if (available_power && specific_power > 0)
if (!isnull(available_power) && specific_power > 0)
transfer_moles = min(transfer_moles, available_power / specific_power)
if (transfer_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing
@@ -82,7 +82,7 @@
total_transfer_moles = min(total_transfer_moles, total_filterable_moles)
//limit transfer_moles based on available power
if (available_power && total_specific_power > 0)
if (!isnull(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
@@ -122,6 +122,7 @@
filtering &= source.gas //only filter gasses that are actually there.
var/total_specific_power = 0 //the power required to remove one mole of input gas
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
@@ -135,9 +136,7 @@
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
@@ -148,7 +147,7 @@
total_transfer_moles = min(total_transfer_moles, source.total_moles)
//limit transfer_moles based on available power
if (available_power && total_specific_power > 0)
if (!isnull(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
@@ -175,13 +174,79 @@
sink_filtered.update_values()
sink_clean.merge(removed)
//1LTD energy is conserved
if (filtered_power_used > 0)
sink_filtered.add_thermal_energy(filtered_power_used) //1st law - energy is conserved
sink_filtered.add_thermal_energy(filtered_power_used)
if (unfiltered_power_used > 0)
sink_clean.add_thermal_energy(unfiltered_power_used) //1st law - energy is conserved
sink_clean.add_thermal_energy(unfiltered_power_used)
return filtered_power_used + unfiltered_power_used
//Similar deal as the other atmos process procs.
//mix_sources maps input gas mixtures to mix ratios. The mix ratios MUST add up to 1.
/obj/machinery/atmospherics/proc/mix_gas(var/list/mix_sources, var/datum/gas_mixture/sink, var/total_transfer_moles = null, var/available_power = null)
if (!mix_sources.len)
return -1
var/total_specific_power = 0
var/total_mixing_moles = null
var/total_input_volume = 0 //for flow rate calculation
var/total_input_moles = 0 //for flow rate calculation
var/list/source_specific_power = list()
for (var/datum/gas_mixture/source in mix_sources)
if (source.total_moles < MINUMUM_MOLES_TO_FILTER)
return -1 //either mix at the set ratios or mix no gas at all
var/mix_ratio = mix_sources[source]
if (!mix_ratio)
continue
//mixing rate is limited by the source with the least amount of available gas
if (isnull(total_mixing_moles))
total_mixing_moles = source.total_moles/mix_ratio
else
total_mixing_moles = min(total_mixing_moles, source.total_moles/mix_ratio)
source_specific_power[source] = calculate_specific_power(source, sink)*mix_ratio/ATMOS_FILTER_EFFICIENCY
total_specific_power += source_specific_power[source]
total_input_volume += source.volume
total_input_moles += source.total_moles
if (total_mixing_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
if (!total_transfer_moles)
total_transfer_moles = total_mixing_moles
else
total_transfer_moles = min(total_mixing_moles, total_transfer_moles)
//limit transfer_moles based on available power
if (!isnull(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/total_input_moles)*total_input_volume //group_multiplier gets divided out here
var/total_power_draw = 0
for (var/datum/gas_mixture/source in mix_sources)
var/mix_ratio = mix_sources[source]
if (!mix_ratio)
continue
var/transfer_moles = total_transfer_moles * mix_ratio
var/datum/gas_mixture/removed = source.remove(transfer_moles)
var/power_draw = transfer_moles * source_specific_power[source]
removed.add_thermal_energy(power_draw) //conservation of energy
total_power_draw += power_draw
sink.merge(removed)
return total_power_draw
/*
Helper procs for various things.
*/
@@ -212,21 +277,42 @@
return specific_power
//This proc handles power usages so that we only have to call use_power() when the pump is loaded but not at full load.
//This proc handles power usages.
//Calling update_use_power() or use_power() too often will result in lag since updating area power can be costly.
//This proc implements an approximation scheme that will cause area power updates to be triggered less often.
//By having atmos machinery use this proc it is easy to change the power usage approximation for all atmos machines
/obj/machinery/atmospherics/proc/handle_power_draw(var/usage_amount)
//***This scheme errs on the side of using more power. Using this will mean that sometimes atmos machines use more power than they need, but won't get power for free.
if (usage_amount > idle_power_usage)
update_use_power(1)
else
use_power = 1 //Don't update here. We will use more power than we are supposed to, but trigger less area power updates.
switch (use_power)
if (0) return 0
if (1) return idle_power_usage
if (2 to INFINITY) return active_power_usage
/* Alternate power usage schemes
//***This scheme has the most accurate power usage, but triggers area power updates too often.
if (usage_amount > active_power_usage - 5)
update_use_power(2)
else
use_power = 1 //Don't update here. Sure, we will use more power than we are supposed to, but it's easier on CPU
/*
//This is the correct way to update pump power usage. Unfortunately it is also pretty laggy.
//Leaving this here in case someone finds a way to do this that doesn't involve doing area power updates all the time.
update_use_power(1)
if (usage_amount > idle_power_usage)
use_power(round(usage_amount))
*/
//***This scheme errs on the side of using less power. Using this will mean that sometimes atmos machines get free power.
if (usage_amount > active_power_usage - 5)
update_use_power(2)
else
use_power = 1 //Don't need to update here.
*/
/*
//DEBUG

View File

@@ -93,12 +93,8 @@ Thus, the two variables affect pump operation are set in New():
use_power = 0 //don't force update - easier on CPU
last_power_draw = 0
last_flow_rate = 0
else if (power_draw > 0)
handle_power_draw(power_draw)
last_power_draw = power_draw
else
handle_power_draw(idle_power_usage)
last_power_draw = idle_power_usage
last_power_draw = handle_power_draw(power_draw)
return 1

View File

@@ -8,6 +8,8 @@
var/list/filters = new()
var/datum/omni_port/input
var/datum/omni_port/output
var/target_pressure = ONE_ATMOSPHERE
/obj/machinery/atmospherics/omni/filter/Del()
input = null

View File

@@ -13,6 +13,8 @@
var/tag_south_con
var/tag_east_con
var/tag_west_con
var/target_pressure = ONE_ATMOSPHERE
/obj/machinery/atmospherics/omni/mixer/New()
..()

View File

@@ -11,7 +11,7 @@
var/on = 0
var/configuring = 0
var/target_pressure = ONE_ATMOSPHERE
//var/target_pressure = ONE_ATMOSPHERE //a base type as abstract as this should NOT be making these kinds of assumptions
var/tag_north = ATM_NONE
var/tag_south = ATM_NONE

View File

@@ -15,16 +15,18 @@
var/max_flow_rate = 200 //L/s
var/set_flow_rate = 200
/*
Filter types:
-1: Nothing
0: Phoron: Phoron, Oxygen Agent B
1: Oxygen: Oxygen ONLY
2: Nitrogen: Nitrogen ONLY
3: Carbon Dioxide: Carbon Dioxide ONLY
4: Sleeping Agent (N2O)
*/
var/filter_type = 0
/*
Filter types:
-1: Nothing
0: Phoron: Phoron, Oxygen Agent B
1: Oxygen: Oxygen ONLY
2: Nitrogen: Nitrogen ONLY
3: Carbon Dioxide: Carbon Dioxide ONLY
4: Sleeping Agent (N2O)
*/
var/list/filtered_out = list()
var/frequency = 0
var/datum/radio_frequency/radio_connection
@@ -90,23 +92,7 @@ Filter types:
var/transfer_moles = (set_flow_rate/air1.volume)*air1.total_moles
var/power_draw = -1
if (transfer_moles > 0)
var/list/filtered_out
switch(filter_type)
if(0) //removing hydrocarbons
filtered_out = list("phoron", "oxygen_agent_b")
if(1) //removing O2
filtered_out = list("oxygen")
if(2) //removing N2
filtered_out = list("nitrogen")
if(3) //removing CO2
filtered_out = list("carbon_dioxide")
if(4)//removing N2O
filtered_out = list("sleeping_agent")
else
filtered_out = null
if (transfer_moles > MINUMUM_MOLES_TO_FILTER)
power_draw = filter_gas(filtered_out, air1, air2, air3, transfer_moles, active_power_usage)
if(network2)
@@ -122,10 +108,8 @@ Filter types:
//update_use_power(0)
use_power = 0 //don't force update - easier on CPU
last_flow_rate = 0
else if (power_draw > 0)
handle_power_draw(power_draw)
else
handle_power_draw(idle_power_usage)
handle_power_draw(power_draw)
return 1
@@ -190,9 +174,9 @@ Filter types:
<A href='?src=\ref[src];filterset=4'>Nitrous Oxide</A><BR>
<A href='?src=\ref[src];filterset=-1'>Nothing</A><BR>
<HR>
<B>Desirable input flow rate:</B>
<B>Set Flow Rate Limit:</B>
[src.set_flow_rate]L/s | <a href='?src=\ref[src];set_flow_rate=1'>Change</a><BR>
<B>Flow rate:</B>[last_flow_rate]L/s
<B>Flow rate: </B>[round(last_flow_rate, 0.1)]L/s
"}
/*
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD>[dat]","window=atmo_filter")
@@ -214,7 +198,22 @@ Filter types:
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["filterset"])
src.filter_type = text2num(href_list["filterset"])
filter_type = text2num(href_list["filterset"])
filtered_out.Cut() //no need to create new lists unnecessarily
switch(filter_type)
if(0) //removing hydrocarbons
filtered_out += "phoron"
filtered_out += "oxygen_agent_b"
if(1) //removing O2
filtered_out += "oxygen"
if(2) //removing N2
filtered_out += "nitrogen"
if(3) //removing CO2
filtered_out += "carbon_dioxide"
if(4)//removing N2O
filtered_out += "sleeping_agent"
if (href_list["temp"])
src.temp = null
if(href_list["set_flow_rate"])

View File

@@ -6,7 +6,15 @@
name = "Gas mixer"
var/target_pressure = ONE_ATMOSPHERE
use_power = 1
idle_power_usage = 150 //internal circuitry, friction losses and stuff
active_power_usage = 3700 //This also doubles as a measure of how powerful the mixer is, in Watts. 3700 W ~ 5 HP
var/max_flow_rate = 200 //L/s
var/set_flow_rate = 200
var/list/mixing_inputs
//for mapping
var/node1_concentration = 0.5
var/node2_concentration = 0.5
@@ -62,56 +70,39 @@
/obj/machinery/atmospherics/trinary/mixer/process()
..()
if(!on)
return 0
//For some reason this doesn't work even in initialize(), so it goes here.
if (!mixing_inputs)
mixing_inputs = list(src.air1 = node1_concentration, src.air2 = node2_concentration)
if((stat & (NOPOWER|BROKEN)) || !on)
update_use_power(0) //usually we get here because a player turned a pump off - definitely want to update.
last_flow_rate = 0
return
//Figure out the amount of moles to transfer
var/transfer_moles = (set_flow_rate*mixing_inputs[air1]/air1.volume)*air1.total_moles + (set_flow_rate*mixing_inputs[air1]/air2.volume)*air2.total_moles
var/power_draw = -1
if (transfer_moles > MINUMUM_MOLES_TO_FILTER)
power_draw = mix_gas(mixing_inputs, air3, transfer_moles, active_power_usage)
if(network1 && mixing_inputs[air1])
network1.update = 1
var/output_starting_pressure = air3.return_pressure()
if(network2 && mixing_inputs[air2])
network2.update = 1
if(output_starting_pressure >= target_pressure)
//No need to mix if target is already full!
return 1
//Calculate necessary moles to transfer using PV=nRT
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles1 = 0
var/transfer_moles2 = 0
if(air1.temperature > 0)
transfer_moles1 = (node1_concentration*pressure_delta)*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
if(air2.temperature > 0)
transfer_moles2 = (node2_concentration*pressure_delta)*air3.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
var/air1_moles = air1.total_moles
var/air2_moles = air2.total_moles
if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
if(!transfer_moles1 || !transfer_moles2) return
var/ratio = min(air1_moles/transfer_moles1, air2_moles/transfer_moles2)
transfer_moles1 *= ratio
transfer_moles2 *= ratio
//Actually transfer the gas
if(transfer_moles1 > 0)
var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
air3.merge(removed1)
if(transfer_moles2 > 0)
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
air3.merge(removed2)
if(network1 && transfer_moles1)
network1.update = 1
if(network2 && transfer_moles2)
network2.update = 1
if(network3)
network3.update = 1
if(network3)
network3.update = 1
if (power_draw < 0)
//update_use_power(0)
use_power = 0 //don't force update - easier on CPU
last_flow_rate = 0
else
handle_power_draw(power_draw)
return 1
/obj/machinery/atmospherics/trinary/mixer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
@@ -142,20 +133,22 @@
return
usr.set_machine(src)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[target_pressure]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
<b>Set Flow Rate Limit: </b>
[set_flow_rate]L/s | <a href='?src=\ref[src];set_press=1'>Change</a>
<br>
<b>Flow Rate: </b>[round(last_flow_rate, 0.1)]L/s
<br><hr>
<b>Node 1 Concentration:</b>
<a href='?src=\ref[src];node1_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node1_c=-0.01'>-</a>
[node1_concentration]([node1_concentration*100]%)
[mixing_inputs[air1]]([mixing_inputs[air1]*100]%)
<a href='?src=\ref[src];node1_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node1_c=0.1'>+</a>
<br>
<b>Node 2 Concentration:</b>
<a href='?src=\ref[src];node2_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node2_c=-0.01'>-</a>
[node2_concentration]([node2_concentration*100]%)
[mixing_inputs[air2]]([mixing_inputs[air2]*100]%)
<a href='?src=\ref[src];node2_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node2_c=0.1'>+</a>
"}
@@ -169,16 +162,16 @@
if(href_list["power"])
on = !on
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",src.set_flow_rate) as num
src.set_flow_rate = max(0, min(max_flow_rate, new_flow_rate))
if(href_list["node1_c"])
var/value = text2num(href_list["node1_c"])
src.node1_concentration = max(0, min(1, src.node1_concentration + value))
src.node2_concentration = max(0, min(1, src.node2_concentration - value))
src.mixing_inputs[air1] = max(0, min(1, src.mixing_inputs[air1] + value))
src.mixing_inputs[air2] = 1.0 - mixing_inputs[air1]
if(href_list["node2_c"])
var/value = text2num(href_list["node2_c"])
src.node2_concentration = max(0, min(1, src.node2_concentration + value))
src.node1_concentration = max(0, min(1, src.node1_concentration - value))
src.mixing_inputs[air2] = max(0, min(1, src.mixing_inputs[air2] + value))
src.mixing_inputs[air1] = 1.0 - mixing_inputs[air2]
src.update_icon()
src.updateUsrDialog()
return
@@ -204,6 +197,7 @@ obj/machinery/atmospherics/trinary/mixer/t_mixer/New()
initialize_directions = WEST|NORTH|SOUTH
obj/machinery/atmospherics/trinary/mixer/t_mixer/initialize()
..()
if(node1 && node2 && node3) return
var/node1_connect = turn(dir, -90)
@@ -249,6 +243,7 @@ obj/machinery/atmospherics/trinary/mixer/m_mixer/New()
initialize_directions = WEST|SOUTH|EAST
obj/machinery/atmospherics/trinary/mixer/m_mixer/initialize()
..()
if(node1 && node2 && node3) return
var/node1_connect = turn(dir, -180)

View File

@@ -154,7 +154,7 @@
if(pressure_delta > 0.5)
if(pump_direction) //internal -> external
var/output_volume = environment.volume * environment.group_multiplier
var/air_temperature = environment.temperature? environment.volume : air_contents.temperature
var/air_temperature = environment.temperature? environment.temperature : air_contents.temperature
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
power_draw = pump_gas(air_contents, environment, transfer_moles, active_power_usage)
@@ -176,12 +176,8 @@
last_flow_rate = 0
//update_use_power(0)
use_power = 0 //don't force update - easier on CPU
if (power_draw > 0)
handle_power_draw(power_draw)
last_power_draw = power_draw
else
handle_power_draw(idle_power_usage)
last_power_draw = idle_power_usage
last_power_draw = handle_power_draw(power_draw)
return 1
@@ -367,6 +363,7 @@
/obj/machinery/atmospherics/unary/vent_pump/examine()
set src in oview(1)
..()
usr << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W"
if(welded)
usr << "It seems welded shut."

View File

@@ -138,12 +138,9 @@
if (power_draw < 0)
//update_use_power(0)
use_power = 0 //don't force update. Sure, we will continue to use power even though we're not pumping anything, but it is easier on the CPU
else if (power_draw > 0)
else
//last_power_draw = power_draw
handle_power_draw(power_draw)
else
//last_power_draw = idle_power_usage
handle_power_draw(idle_power_usage)
if(network)
network.update = 1
@@ -250,6 +247,11 @@
new /obj/item/pipe(loc, make_from=src)
del(src)
/obj/machinery/atmospherics/unary/vent_scrubber/examine()
set src in oview(1)
..()
usr << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s"
/obj/machinery/atmospherics/unary/vent_scrubber/Del()
if(initial_loc)
initial_loc.air_scrub_info -= id_tag

View File

@@ -102,9 +102,6 @@
var/temperature_dangerlevel = 0
var/other_dangerlevel = 0
var/alarm_sound_cooldown = 200
var/last_sound_time = 0
/obj/machinery/alarm/server/New()
..()
req_access = list(access_rd, access_atmospherics, access_engine_equip)
@@ -161,7 +158,6 @@
if (!master_is_operating())
elect_master()
/obj/machinery/alarm/process()
if((stat & (NOPOWER|BROKEN)) || shorted || buildstage != 2)
return
@@ -169,12 +165,43 @@
var/turf/simulated/location = loc
if(!istype(location)) return//returns if loc is not simulated
if ((alarm_area.fire || alarm_area.atmosalm >= 2) && world.time > last_sound_time + alarm_sound_cooldown)
last_sound_time = world.time
var/datum/gas_mixture/environment = location.return_air()
//Handle temperature adjustment here.
handle_heating_cooling(environment)
var/old_level = danger_level
var/old_pressurelevel = pressure_dangerlevel
danger_level = overall_danger_level(environment)
if (old_level != danger_level)
apply_danger_level(danger_level)
if (old_pressurelevel != pressure_dangerlevel)
if (breach_detected())
mode = AALARM_MODE_OFF
apply_mode()
if (mode==AALARM_MODE_CYCLE && environment.return_pressure()<ONE_ATMOSPHERE*0.05)
mode=AALARM_MODE_FILL
apply_mode()
//atmos computer remote controll stuff
switch(rcon_setting)
if(RCON_NO)
remote_control = 0
if(RCON_AUTO)
if(danger_level == 2)
remote_control = 1
else
remote_control = 0
if(RCON_YES)
remote_control = 1
updateDialog()
return
/obj/machinery/alarm/proc/handle_heating_cooling(var/datum/gas_mixture/environment)
if (!regulating_temperature)
//check for when we should start adjusting temperature
if(!get_danger_level(target_temperature, TLV["temperature"]) && abs(environment.temperature - target_temperature) > 2.0)
@@ -198,7 +225,7 @@
target_temperature = T0C + MIN_TEMPERATURE
var/datum/gas_mixture/gas
gas = location.remove_air(0.25*environment.total_moles)
gas = environment.remove(0.25*environment.total_moles)
if(gas)
if (gas.temperature <= target_temperature) //gas heating
@@ -222,44 +249,7 @@
environment.merge(gas)
var/old_level = danger_level
var/old_pressurelevel = pressure_dangerlevel
danger_level = overall_danger_level()
if (old_level != danger_level)
apply_danger_level(danger_level)
if (old_pressurelevel != pressure_dangerlevel)
if (breach_detected())
mode = AALARM_MODE_OFF
apply_mode()
if (mode==AALARM_MODE_CYCLE && environment.return_pressure()<ONE_ATMOSPHERE*0.05)
mode=AALARM_MODE_FILL
apply_mode()
//atmos computer remote controll stuff
switch(rcon_setting)
if(RCON_NO)
remote_control = 0
if(RCON_AUTO)
if(danger_level == 2)
remote_control = 1
else
remote_control = 0
if(RCON_YES)
remote_control = 1
updateDialog()
return
/obj/machinery/alarm/proc/overall_danger_level()
var/turf/simulated/location = loc
if(!istype(location)) return//returns if loc is not simulated
var/datum/gas_mixture/environment = location.return_air()
/obj/machinery/alarm/proc/overall_danger_level(var/datum/gas_mixture/environment)
var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
var/environment_pressure = environment.return_pressure()
//var/other_moles = 0.0

View File

@@ -9,8 +9,7 @@
var/frequency = 0
var/id
use_power = 1
idle_power_usage = 2
active_power_usage = 5
idle_power_usage = 15
/obj/machinery/meter/New()
..()
@@ -30,8 +29,6 @@
icon_state = "meter0"
return 0
//use_power(5)
var/datum/gas_mixture/environment = target.return_air()
if(!environment)
icon_state = "meterX"

View File

@@ -829,16 +829,15 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
Atmos Machinery
*/
//These limit the flow rate when taking gas away from turfs. This is necessary because moving 2500 L in a single iteration causes a huge amount of error with pressure and gas calculations.
//This error is related to the fact that we do everything in 1 second steps instead of continuous time. Limiting the flow rate will prevent pressures from overshooting too much.
#define MAX_SIPHON_FLOWRATE 500 //L/s
#define MAX_FILTER_FLOWRATE 200 //L/s
//Note: anything higher than these values has no effect at the moment.
#define MAX_SIPHON_FLOWRATE 2500 //L/s This can be used to balance how fast a room is siphoned.
#define MAX_FILTER_FLOWRATE 200 //L/s
//These control how easy or hard it is to create huge pressure gradients with pumps and filters. Lower values means it takes longer to create large pressures differences.
//These balance how easy or hard it is to create huge pressure gradients with pumps and filters. Lower values means it takes longer to create large pressures differences.
//If you want to limit the ability of players to create very high pressures then it makes more sense to adjust these instead of artificially limiting the pump settings.
//Has no effect on pumping gasses from high pressure to low, only from low to high. Must be between 0 and 1.
#define ATMOS_PUMP_EFFICIENCY 1.0
#define ATMOS_FILTER_EFFICIENCY 0.9
#define ATMOS_PUMP_EFFICIENCY 0.6
#define ATMOS_FILTER_EFFICIENCY 0.45
#define MINUMUM_MOLES_TO_PUMP 0.01 //will not bother pumping or filtering if the gas source as fewer than this amount of moles, to help with performance.
#define MINUMUM_MOLES_TO_FILTER 0.1