mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-28 11:03:19 +00:00
Cleanup, adds setup parameters for atmos machinery
Allows atmos machinery efficiency to be adjusted in setup.dm Limits flow rates when moving gas from a turf to avoid very high pressures being created when they shouldn't be. Attempts to limit processing when there isn't much gas to be moved, for performance. Reverts all changes to _gas_mixture.dm
This commit is contained in:
@@ -67,58 +67,67 @@ Thus, the two variables affect pump operation are set in New():
|
|||||||
last_flow_rate = 0
|
last_flow_rate = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/gas_mixture/source = air1
|
var/power_draw = -1
|
||||||
var/datum/gas_mixture/sink = air2
|
if (air1.temperature > 0 || air2.temperature > 0)
|
||||||
|
power_draw = pump_gas(air1, air2)
|
||||||
var/pressure_delta = target_pressure - sink.return_pressure()
|
|
||||||
|
|
||||||
//Calculate necessary moles to transfer using PV=nRT
|
|
||||||
if(pressure_delta > 0.01 && (source.total_moles > 0) && (source.temperature > 0 || sink.temperature > 0))
|
|
||||||
|
|
||||||
var/transfer_moles = source.total_moles
|
|
||||||
/* TODO Uncomment this once we have a good way to get the volume of a pipe network.
|
|
||||||
//Figure out how much gas to transfer to meet the target pressure.
|
|
||||||
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
|
||||||
|
|
||||||
var/output_volume = sink.volume * sink.group_multiplier
|
|
||||||
|
|
||||||
//Return the number of moles that would have to be transfered to bring sink to the target pressure
|
|
||||||
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Calculate the amount of energy required and limit transfer_moles based on available power
|
|
||||||
var/specific_power = calculate_specific_power(source, sink) //this has to be calculated before we modify any gas mixtures
|
|
||||||
if (specific_power > 0)
|
|
||||||
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
|
||||||
|
|
||||||
var/power_draw = specific_power*transfer_moles
|
|
||||||
|
|
||||||
var/datum/gas_mixture/removed = source.remove(transfer_moles)
|
|
||||||
last_flow_rate = (removed.total_moles/(removed.total_moles + source.total_moles))*source.volume
|
|
||||||
|
|
||||||
if (power_draw > 0)
|
|
||||||
removed.add_thermal_energy(power_draw) //1st law - energy is conserved
|
|
||||||
handle_pump_power_draw(power_draw)
|
|
||||||
last_power_draw = power_draw
|
|
||||||
else
|
|
||||||
handle_pump_power_draw(idle_power_usage)
|
|
||||||
last_power_draw = idle_power_usage
|
|
||||||
|
|
||||||
sink.merge(removed)
|
|
||||||
|
|
||||||
if(network1)
|
if(network1)
|
||||||
network1.update = 1
|
network1.update = 1
|
||||||
|
|
||||||
if(network2)
|
if(network2)
|
||||||
network2.update = 1
|
network2.update = 1
|
||||||
else
|
|
||||||
|
if (power_draw < 0)
|
||||||
update_use_power(0)
|
update_use_power(0)
|
||||||
last_power_draw = 0
|
last_power_draw = 0
|
||||||
last_flow_rate = 0
|
last_flow_rate = 0
|
||||||
return 1
|
else if (power_draw > 0)
|
||||||
|
handle_pump_power_draw(power_draw)
|
||||||
|
last_power_draw = power_draw
|
||||||
|
else
|
||||||
|
handle_pump_power_draw(idle_power_usage)
|
||||||
|
last_power_draw = idle_power_usage
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
//pumps gas from source to sink, and returns the power used, or -1 if no pumping was done
|
||||||
|
/obj/machinery/atmospherics/binary/pump/proc/pump_gas(var/datum/gas_mixture/source, var/datum/gas_mixture/sink)
|
||||||
|
var/pressure_delta = target_pressure - sink.return_pressure()
|
||||||
|
|
||||||
|
if(pressure_delta < 0.01 || source.total_moles < MINUMUM_MOLES_TO_PUMP)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
var/transfer_moles = source.total_moles
|
||||||
|
/* TODO Uncomment this once we have a good way to get the volume of a pipe network.
|
||||||
|
//Figure out how much gas to transfer to meet the target pressure.
|
||||||
|
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
||||||
|
|
||||||
|
var/output_volume = sink.volume * sink.group_multiplier
|
||||||
|
|
||||||
|
//Return the number of moles that would have to be transfered to bring sink to the target pressure
|
||||||
|
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//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 (specific_power > 0)
|
||||||
|
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
||||||
|
|
||||||
|
if (transfer_moles < MINUMUM_MOLES_TO_PUMP)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
var/power_draw = specific_power*transfer_moles
|
||||||
|
|
||||||
|
var/datum/gas_mixture/removed = source.remove(transfer_moles)
|
||||||
|
last_flow_rate = (removed.total_moles/(removed.total_moles + source.total_moles))*source.volume
|
||||||
|
|
||||||
|
if (power_draw > 0)
|
||||||
|
removed.add_thermal_energy(power_draw) //1st law - energy is conserved
|
||||||
|
|
||||||
|
sink.merge(removed)
|
||||||
|
|
||||||
|
return power_draw
|
||||||
|
|
||||||
//Radio remote control
|
//Radio remote control
|
||||||
|
|
||||||
/obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency)
|
/obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency)
|
||||||
|
|||||||
@@ -144,16 +144,14 @@
|
|||||||
last_power_draw = 0
|
last_power_draw = 0
|
||||||
last_flow_rate = 0
|
last_flow_rate = 0
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
var/datum/gas_mixture/environment = loc.return_air()
|
var/datum/gas_mixture/environment = loc.return_air()
|
||||||
var/environment_pressure = environment.return_pressure()
|
var/environment_pressure = environment.return_pressure()
|
||||||
|
|
||||||
if(air_contents.temperature == 0 && environment.temperature == 0)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
var/pressure_delta = DEFAULT_PRESSURE_DELTA
|
var/pressure_delta = DEFAULT_PRESSURE_DELTA
|
||||||
|
|
||||||
if(pressure_delta > 0.5)
|
var/power_draw = -1
|
||||||
|
if((air_contents.temperature > 0 || environment.temperature > 0) && pressure_delta > 0.5)
|
||||||
if(pump_direction) //internal -> external
|
if(pump_direction) //internal -> external
|
||||||
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
||||||
pressure_delta = min(pressure_delta, external_pressure_bound - environment_pressure) //increasing the pressure here
|
pressure_delta = min(pressure_delta, external_pressure_bound - environment_pressure) //increasing the pressure here
|
||||||
@@ -166,7 +164,7 @@
|
|||||||
var/air_temperature = environment.temperature? environment.volume : air_contents.temperature
|
var/air_temperature = environment.temperature? environment.volume : air_contents.temperature
|
||||||
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
||||||
|
|
||||||
transfer_gas(air_contents, environment, transfer_moles)
|
power_draw = transfer_gas(air_contents, environment, transfer_moles)
|
||||||
else //external -> internal
|
else //external -> internal
|
||||||
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
||||||
pressure_delta = min(pressure_delta, environment_pressure - external_pressure_bound) //decreasing the pressure here
|
pressure_delta = min(pressure_delta, environment_pressure - external_pressure_bound) //decreasing the pressure here
|
||||||
@@ -178,46 +176,57 @@
|
|||||||
var/air_temperature = air_contents.temperature? air_contents.temperature : environment.temperature
|
var/air_temperature = air_contents.temperature? air_contents.temperature : environment.temperature
|
||||||
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
||||||
|
|
||||||
transfer_gas(environment, air_contents, transfer_moles)
|
//limit flow rate from turfs
|
||||||
|
transfer_moles = min(transfer_moles, environment.total_moles*MAX_SIPHON_FLOWRATE/environment.volume) //group_multiplier gets divided out here
|
||||||
|
|
||||||
|
power_draw = transfer_gas(environment, air_contents, transfer_moles)
|
||||||
|
|
||||||
if(network)
|
if(network)
|
||||||
network.update = 1
|
network.update = 1
|
||||||
else
|
|
||||||
|
if (power_draw < 0)
|
||||||
last_power_draw = 0
|
last_power_draw = 0
|
||||||
last_flow_rate = 0
|
last_flow_rate = 0
|
||||||
update_use_power(0)
|
update_use_power(0)
|
||||||
|
if (power_draw > 0)
|
||||||
|
handle_pump_power_draw(power_draw)
|
||||||
|
last_power_draw = power_draw
|
||||||
|
else
|
||||||
|
handle_pump_power_draw(idle_power_usage)
|
||||||
|
last_power_draw = idle_power_usage
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
//pumps gas from source to sink and returns the power used, or -1 if no pumping was done.
|
||||||
/obj/machinery/atmospherics/unary/vent_pump/proc/transfer_gas(datum/gas_mixture/source, datum/gas_mixture/sink, var/transfer_moles)
|
/obj/machinery/atmospherics/unary/vent_pump/proc/transfer_gas(datum/gas_mixture/source, datum/gas_mixture/sink, var/transfer_moles)
|
||||||
if(source.total_moles == 0)
|
if(source.total_moles < MINUMUM_MOLES_TO_PUMP)
|
||||||
update_use_power(0)
|
return -1
|
||||||
return
|
|
||||||
|
|
||||||
//limit transfer_moles by available power
|
//limit transfer_moles by available power
|
||||||
var/specific_power = calculate_specific_power(source, sink) //this has to be calculated before we modify any gas mixtures
|
var/specific_power = calculate_specific_power(source, sink)/ATMOS_PUMP_EFFICIENCY //this has to be calculated before we modify any gas mixtures
|
||||||
if (specific_power > 0)
|
if (specific_power > 0)
|
||||||
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
||||||
|
|
||||||
//Get the gas to be transferred
|
//Get the gas to be transferred
|
||||||
|
if (transfer_moles < MINUMUM_MOLES_TO_PUMP)
|
||||||
|
return -1 //don't bother
|
||||||
|
|
||||||
var/datum/gas_mixture/removed = source.remove(transfer_moles)
|
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 (isnull(removed)) //not sure why this would happen, but it does at the very beginning of the game
|
||||||
return
|
return -1
|
||||||
|
|
||||||
last_flow_rate = (removed.total_moles/(removed.total_moles + source.total_moles))*source.volume
|
last_flow_rate = (removed.total_moles/(removed.total_moles + source.total_moles))*source.volume
|
||||||
|
|
||||||
var/power_draw = specific_power*transfer_moles
|
var/power_draw = specific_power*transfer_moles
|
||||||
if (power_draw > 0)
|
if (power_draw > 0)
|
||||||
removed.add_thermal_energy(power_draw)
|
removed.add_thermal_energy(power_draw)
|
||||||
handle_pump_power_draw(power_draw)
|
|
||||||
last_power_draw = power_draw
|
|
||||||
else
|
|
||||||
handle_pump_power_draw(idle_power_usage)
|
|
||||||
last_power_draw = idle_power_usage
|
|
||||||
|
|
||||||
//merge the removed gas into the sink
|
//merge the removed gas into the sink
|
||||||
sink.merge(removed)
|
sink.merge(removed)
|
||||||
|
|
||||||
|
return power_draw
|
||||||
|
|
||||||
//Radio remote control
|
//Radio remote control
|
||||||
|
|
||||||
|
|||||||
@@ -122,66 +122,17 @@
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
var/datum/gas_mixture/environment = loc.return_air()
|
var/datum/gas_mixture/environment = loc.return_air()
|
||||||
if ((environment.total_moles == 0) || (environment.temperature == 0 && air_contents.temperature == 0))
|
|
||||||
|
var/power_draw = -1
|
||||||
|
if (environment.temperature > 0 || air_contents.temperature > 0)
|
||||||
|
if(scrubbing)
|
||||||
|
power_draw = filter_gas(environment)
|
||||||
|
else //Just siphon all air
|
||||||
|
power_draw = siphon_gas(environment)
|
||||||
|
|
||||||
|
if (power_draw < 0)
|
||||||
update_use_power(0)
|
update_use_power(0)
|
||||||
return
|
else if (power_draw > 0)
|
||||||
|
|
||||||
var/power_draw
|
|
||||||
if(scrubbing)
|
|
||||||
//Filter it
|
|
||||||
var/total_specific_power = 0 //the power required to remove one mole of filterable gas
|
|
||||||
var/total_filterable_moles = 0
|
|
||||||
var/list/specific_power_gas = list()
|
|
||||||
for (var/g in scrubbing_gas)
|
|
||||||
if (environment.gas[g] < 0.1)
|
|
||||||
continue //don't bother
|
|
||||||
|
|
||||||
var/specific_power = calculate_specific_power_gas(g, environment, air_contents)
|
|
||||||
specific_power_gas[g] = specific_power
|
|
||||||
total_specific_power += specific_power
|
|
||||||
total_filterable_moles += environment.gas[g]
|
|
||||||
|
|
||||||
if (total_filterable_moles == 0)
|
|
||||||
update_use_power(0)
|
|
||||||
return
|
|
||||||
|
|
||||||
//Calculate the amount of energy required and limit transfer_moles based on available power
|
|
||||||
power_draw = 0
|
|
||||||
var/total_transfer_moles = total_filterable_moles
|
|
||||||
if (total_specific_power > 0)
|
|
||||||
total_transfer_moles = min(total_transfer_moles, active_power_usage/total_specific_power)
|
|
||||||
|
|
||||||
for (var/g in scrubbing_gas)
|
|
||||||
var/transfer_moles = environment.gas[g]
|
|
||||||
if (specific_power_gas[g] > 0)
|
|
||||||
//if our flow rate is limited by available power, the proportion of the filtered gas is based on mole ratio
|
|
||||||
transfer_moles = min(transfer_moles, total_transfer_moles*(environment.gas[g]/total_filterable_moles))
|
|
||||||
|
|
||||||
environment.gas[g] -= transfer_moles
|
|
||||||
air_contents.gas[g] += transfer_moles
|
|
||||||
power_draw += specific_power_gas[g]*transfer_moles
|
|
||||||
|
|
||||||
//Remix the resulting gases
|
|
||||||
air_contents.update_values()
|
|
||||||
environment.update_values()
|
|
||||||
|
|
||||||
else //Just siphon all air
|
|
||||||
var/transfer_moles = environment.total_moles
|
|
||||||
|
|
||||||
//Calculate the amount of energy required
|
|
||||||
var/specific_power = calculate_specific_power(environment, air_contents) //this has to be calculated before we modify any gas mixtures
|
|
||||||
if (specific_power > 0)
|
|
||||||
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
|
||||||
|
|
||||||
if (transfer_moles < 0.01)
|
|
||||||
update_use_power(0)
|
|
||||||
return //don't bother
|
|
||||||
|
|
||||||
power_draw = specific_power*transfer_moles
|
|
||||||
air_contents.merge(environment.remove(transfer_moles))
|
|
||||||
|
|
||||||
if (power_draw > 0)
|
|
||||||
air_contents.add_thermal_energy(power_draw)
|
|
||||||
//last_power_draw = power_draw
|
//last_power_draw = power_draw
|
||||||
handle_pump_power_draw(power_draw)
|
handle_pump_power_draw(power_draw)
|
||||||
else
|
else
|
||||||
@@ -193,6 +144,80 @@
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
//filters gas from environment and returns the amount of power used, or -1 if no filtering was done
|
||||||
|
/obj/machinery/atmospherics/unary/vent_scrubber/proc/filter_gas(datum/gas_mixture/environment)
|
||||||
|
//Filter it
|
||||||
|
var/total_specific_power = 0 //the power required to remove one mole of filterable gas
|
||||||
|
var/total_filterable_moles = 0
|
||||||
|
var/list/specific_power_gas = list()
|
||||||
|
for (var/g in scrubbing_gas)
|
||||||
|
if (environment.gas[g] < MINUMUM_MOLES_TO_PUMP)
|
||||||
|
continue //don't bother
|
||||||
|
|
||||||
|
var/specific_power = calculate_specific_power_gas(g, environment, air_contents)/ATMOS_FILTER_EFFICIENCY
|
||||||
|
specific_power_gas[g] = specific_power
|
||||||
|
total_specific_power += specific_power
|
||||||
|
total_filterable_moles += environment.gas[g]
|
||||||
|
|
||||||
|
if (total_filterable_moles < MINUMUM_MOLES_TO_PUMP)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
//Figure out how much of each gas to filter
|
||||||
|
var/total_transfer_moles = total_filterable_moles
|
||||||
|
|
||||||
|
//limit flow rate from turfs
|
||||||
|
total_transfer_moles = min(total_transfer_moles, environment.total_moles*MAX_FILTER_FLOWRATE/environment.volume) //group_multiplier gets divided out here
|
||||||
|
|
||||||
|
//limit transfer_moles based on available power
|
||||||
|
var/power_draw = 0
|
||||||
|
if (total_specific_power > 0)
|
||||||
|
total_transfer_moles = min(total_transfer_moles, active_power_usage/total_specific_power)
|
||||||
|
|
||||||
|
for (var/g in scrubbing_gas)
|
||||||
|
var/transfer_moles = environment.gas[g]
|
||||||
|
if (specific_power_gas[g] > 0)
|
||||||
|
//if our flow rate is being limited by available power, the proportion of the filtered gas is based on mole ratio
|
||||||
|
transfer_moles = min(transfer_moles, total_transfer_moles*(environment.gas[g]/total_filterable_moles))
|
||||||
|
|
||||||
|
environment.gas[g] -= transfer_moles
|
||||||
|
air_contents.gas[g] += transfer_moles
|
||||||
|
power_draw += specific_power_gas[g]*transfer_moles
|
||||||
|
|
||||||
|
if (power_draw > 0)
|
||||||
|
air_contents.add_thermal_energy(power_draw)
|
||||||
|
|
||||||
|
//Remix the resulting gases
|
||||||
|
air_contents.update_values()
|
||||||
|
environment.update_values()
|
||||||
|
|
||||||
|
return power_draw
|
||||||
|
|
||||||
|
//siphons gas from environment and returns the power used, or -1 if no siphoning was done
|
||||||
|
/obj/machinery/atmospherics/unary/vent_scrubber/proc/siphon_gas(datum/gas_mixture/environment)
|
||||||
|
if (environment.total_moles < MINUMUM_MOLES_TO_PUMP)
|
||||||
|
return -1 //no point doing all this processing when source is a vacuum
|
||||||
|
|
||||||
|
var/transfer_moles = environment.total_moles
|
||||||
|
|
||||||
|
//limit flow rate from turfs
|
||||||
|
transfer_moles = min(transfer_moles, environment.total_moles*MAX_SIPHON_FLOWRATE/environment.volume) //group_multiplier gets divided out here
|
||||||
|
|
||||||
|
//Calculate the amount of energy required and limit transfer_moles based on available power
|
||||||
|
var/specific_power = calculate_specific_power(environment, air_contents)/ATMOS_PUMP_EFFICIENCY //this has to be calculated before we modify any gas mixtures
|
||||||
|
if (specific_power > 0)
|
||||||
|
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
||||||
|
|
||||||
|
if (transfer_moles < MINUMUM_MOLES_TO_PUMP)
|
||||||
|
return -1 //don't bother
|
||||||
|
|
||||||
|
var/power_draw = specific_power*transfer_moles
|
||||||
|
var/datum/gas_mixture/removed = environment.remove(transfer_moles)
|
||||||
|
if (power_draw > 0)
|
||||||
|
removed.add_thermal_energy(power_draw)
|
||||||
|
air_contents.merge(removed)
|
||||||
|
|
||||||
|
return power_draw
|
||||||
|
|
||||||
/obj/machinery/atmospherics/unary/vent_scrubber/hide(var/i) //to make the little pipe section invisible, the icon changes.
|
/obj/machinery/atmospherics/unary/vent_scrubber/hide(var/i) //to make the little pipe section invisible, the icon changes.
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|
||||||
|
|||||||
@@ -4,24 +4,16 @@ What are the archived variables for?
|
|||||||
This prevents race conditions that arise based on the order of tile processing.
|
This prevents race conditions that arise based on the order of tile processing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SPECIFIC_HEAT_TOXIN 200 // J/(mol*K)
|
#define SPECIFIC_HEAT_TOXIN 200
|
||||||
#define SPECIFIC_HEAT_AIR 20 // J/(mol*K)
|
#define SPECIFIC_HEAT_AIR 20
|
||||||
#define SPECIFIC_HEAT_CDO 30 // J/(mol*K)
|
#define SPECIFIC_HEAT_CDO 30
|
||||||
#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,phoron) \
|
#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,phoron) \
|
||||||
max(0, carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + phoron * SPECIFIC_HEAT_TOXIN)
|
max(0, carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + phoron * SPECIFIC_HEAT_TOXIN)
|
||||||
|
|
||||||
//we should really have a datum for each gas instead of a bunch of constants
|
|
||||||
#define MOL_MASS_O2 0.032 // kg/mol
|
|
||||||
#define MOL_MASS_N2 0.028 // kg/mol
|
|
||||||
#define MOL_MASS_CDO 0.044 // kg/mol
|
|
||||||
#define MOL_MASS_PHORON 0.289 // kg/mol
|
|
||||||
|
|
||||||
#define MINIMUM_HEAT_CAPACITY 0.0003
|
#define MINIMUM_HEAT_CAPACITY 0.0003
|
||||||
#define QUANTIZE(variable) (round(variable,0.0001))
|
#define QUANTIZE(variable) (round(variable,0.0001))
|
||||||
#define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer
|
#define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer
|
||||||
|
|
||||||
#define SPECIFIC_ENTROPY_VACUUM 1500 //technically vacuum doesn't have a specific entropy. Just use a really big number here to show that it's easy to add gas to vacuum and hard to take gas out.
|
|
||||||
|
|
||||||
/hook/startup/proc/createGasOverlays()
|
/hook/startup/proc/createGasOverlays()
|
||||||
plmaster = new /obj/effect/overlay()
|
plmaster = new /obj/effect/overlay()
|
||||||
plmaster.icon = 'icons/effects/tile_effects.dmi'
|
plmaster.icon = 'icons/effects/tile_effects.dmi'
|
||||||
@@ -36,11 +28,11 @@ What are the archived variables for?
|
|||||||
slmaster.mouse_opacity = 0
|
slmaster.mouse_opacity = 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy. //J/(mol*K)
|
/datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy.
|
||||||
|
|
||||||
/datum/gas/oxygen_agent_b/specific_heat = 300 //J/(mol*K)
|
/datum/gas/oxygen_agent_b/specific_heat = 300
|
||||||
|
|
||||||
/datum/gas/volatile_fuel/specific_heat = 30 //J/(mol*K)
|
/datum/gas/volatile_fuel/specific_heat = 30
|
||||||
|
|
||||||
/datum/gas
|
/datum/gas
|
||||||
var/moles = 0
|
var/moles = 0
|
||||||
@@ -149,65 +141,6 @@ What are the archived variables for?
|
|||||||
|
|
||||||
return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived)
|
return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived)
|
||||||
|
|
||||||
/datum/gas_mixture/proc/add_thermal_energy(var/thermal_energy)
|
|
||||||
//Purpose: Adjusting temperature based on thermal energy transfer
|
|
||||||
//Called by: Anyone who wants to add or remove energy from the gas mix
|
|
||||||
//Inputs: An amount of energy in J to be added. Negative values remove energy.
|
|
||||||
//Outputs: The actual thermal energy change. Only relevant if you are removing energy.
|
|
||||||
|
|
||||||
var/old_temperature = temperature
|
|
||||||
var/heat_capacity = heat_capacity()
|
|
||||||
|
|
||||||
temperature += thermal_energy/heat_capacity
|
|
||||||
if (temperature < TCMB)
|
|
||||||
temperature = TCMB
|
|
||||||
|
|
||||||
return (temperature - old_temperature)*heat_capacity
|
|
||||||
|
|
||||||
/datum/gas_mixture/proc/get_thermal_energy_change(var/new_temperature)
|
|
||||||
//Purpose: Determining how much thermal energy is required
|
|
||||||
//Called by: Anyone. Machines that want to adjust the temperature of a gas mix.
|
|
||||||
//Inputs: None
|
|
||||||
//Outputs: The amount of energy required to get to the new temperature in J. A negative value means that energy needs to be removed.
|
|
||||||
|
|
||||||
return heat_capacity()*(new_temperature - temperature)
|
|
||||||
|
|
||||||
|
|
||||||
//This is so overkill for spessmen it's hilarious.
|
|
||||||
//While this proc will return an accurate measure of the entropy, it's much easier to use the specific_entropy_change() proc.
|
|
||||||
/datum/gas_mixture/proc/specific_entropy()
|
|
||||||
//Purpose: Returning the specific entropy of the gas mix, i.e. the entropy gained or lost per mole of gas added or removed.
|
|
||||||
//Called by: Anyone who wants to know how much energy it takes to move gases around in a steady state process (e.g. gas pumps)
|
|
||||||
//Inputs: None
|
|
||||||
//Outputs: Specific Entropy.
|
|
||||||
|
|
||||||
//Jut assume everything is an ideal gas, so we can use the Ideal Gas Sackur-Tetrode equation.
|
|
||||||
//After we convert to moles and Liters and extract all those crazy constants inside the ln() we end up with:
|
|
||||||
//S = R * moles * ( ln[ constant * volume / moles * (molecular_mass * internal_energy / moles)^(3/2) ] + 5/2 )
|
|
||||||
//Where constant is IDEAL_GAS_ENTROPY_CONSTANT defined in setup.dm
|
|
||||||
|
|
||||||
//We need to do this calculation for each type of gas in the mix and add them all up, to properly capture the entropy of mixing.
|
|
||||||
//It would be nice if each gas type was a datum, then we could just iterate through a list
|
|
||||||
|
|
||||||
//the number of moles inside the square root gets divided out
|
|
||||||
var/sp_entropy_oxygen = ( log( IDEAL_GAS_ENTROPY_CONSTANT * volume / (oxygen + 0.001) * sqrt( ( MOL_MASS_O2 * SPECIFIC_HEAT_AIR * (temperature + 1) ) ** 3 ) + 1) + 5/2 )
|
|
||||||
|
|
||||||
var/sp_entropy_nitrogen = ( log( IDEAL_GAS_ENTROPY_CONSTANT * volume / (nitrogen + 0.001) * sqrt( ( MOL_MASS_N2 * SPECIFIC_HEAT_AIR * (temperature + 1) ) ** 3 ) + 1 ) + 5/2 )
|
|
||||||
|
|
||||||
var/sp_entropy_carbon_dioxide = ( log( IDEAL_GAS_ENTROPY_CONSTANT * volume / (carbon_dioxide + 0.001) * sqrt( ( MOL_MASS_CDO * SPECIFIC_HEAT_CDO * (temperature + 1) + 1 ) ** 3 ) ) + 5/2 )
|
|
||||||
|
|
||||||
var/sp_entropy_phoron = ( log( IDEAL_GAS_ENTROPY_CONSTANT * volume / (phoron + 0.001) * sqrt( ( MOL_MASS_PHORON * SPECIFIC_HEAT_TOXIN * (temperature + 1) ) ** 3 ) + 1 ) + 5/2 )
|
|
||||||
|
|
||||||
if (total_moles > 0)
|
|
||||||
var/oxygen_ratio = oxygen/total_moles
|
|
||||||
var/nitrogen_ratio = nitrogen/total_moles
|
|
||||||
var/carbon_dioxide_ratio = carbon_dioxide/total_moles
|
|
||||||
var/phoron_ratio = phoron/total_moles
|
|
||||||
|
|
||||||
return R_IDEAL_GAS_EQUATION * ( oxygen_ratio*sp_entropy_oxygen + nitrogen_ratio*sp_entropy_nitrogen + carbon_dioxide_ratio*sp_entropy_carbon_dioxide + phoron_ratio*sp_entropy_phoron )
|
|
||||||
|
|
||||||
return SPECIFIC_ENTROPY_VACUUM
|
|
||||||
|
|
||||||
/datum/gas_mixture/proc/total_moles()
|
/datum/gas_mixture/proc/total_moles()
|
||||||
return total_moles
|
return total_moles
|
||||||
/*var/moles = oxygen + carbon_dioxide + nitrogen + phoron
|
/*var/moles = oxygen + carbon_dioxide + nitrogen + phoron
|
||||||
|
|||||||
@@ -823,3 +823,21 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
|
|||||||
#define IS_UNATHI 4
|
#define IS_UNATHI 4
|
||||||
|
|
||||||
#define MAX_GEAR_COST 5 //Used in chargen for loadout limit.
|
#define MAX_GEAR_COST 5 //Used in chargen for loadout limit.
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
//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.
|
||||||
|
//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 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.
|
||||||
Reference in New Issue
Block a user