mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-14 04:02:31 +00:00
Some cleanup for pumps and vent pumps
This commit is contained in:
@@ -50,6 +50,7 @@
|
|||||||
#include "code\_onclick\hud\screen_objects.dm"
|
#include "code\_onclick\hud\screen_objects.dm"
|
||||||
#include "code\ATMOSPHERICS\_atmos_setup.dm"
|
#include "code\ATMOSPHERICS\_atmos_setup.dm"
|
||||||
#include "code\ATMOSPHERICS\atmospherics.dm"
|
#include "code\ATMOSPHERICS\atmospherics.dm"
|
||||||
|
#include "code\ATMOSPHERICS\atmospherics_helpers.dm"
|
||||||
#include "code\ATMOSPHERICS\datum_pipe_network.dm"
|
#include "code\ATMOSPHERICS\datum_pipe_network.dm"
|
||||||
#include "code\ATMOSPHERICS\datum_pipeline.dm"
|
#include "code\ATMOSPHERICS\datum_pipeline.dm"
|
||||||
#include "code\ATMOSPHERICS\he_pipes.dm"
|
#include "code\ATMOSPHERICS\he_pipes.dm"
|
||||||
|
|||||||
23
code/ATMOSPHERICS/atmospherics_helpers.dm
Normal file
23
code/ATMOSPHERICS/atmospherics_helpers.dm
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//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
|
||||||
|
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
||||||
|
var/specific_entropy = sink.specific_entropy() - source.specific_entropy() //environment is gaining moles, air_contents is loosing
|
||||||
|
var/specific_power = 0 // W/mol
|
||||||
|
|
||||||
|
//If specific_entropy is < 0 then transfer_moles is limited by how powerful the pump is
|
||||||
|
if (specific_entropy < 0)
|
||||||
|
specific_power = -specific_entropy*air_temperature //how much power we need per mole
|
||||||
|
|
||||||
|
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.
|
||||||
|
/obj/machinery/atmospherics/proc/handle_pump_power_draw(var/usage_amount)
|
||||||
|
if (usage_amount > active_power_usage - 5)
|
||||||
|
update_use_power(2)
|
||||||
|
else
|
||||||
|
update_use_power(1)
|
||||||
|
|
||||||
|
if (usage_amount > idle_power_usage)
|
||||||
|
use_power(round(usage_amount)) //in practice it's pretty rare that we will get here, so calling use_power() is alright.
|
||||||
|
|
||||||
@@ -80,34 +80,35 @@ Thus, the two variables affect pump operation are set in New():
|
|||||||
if(pressure_delta > 0.01 && (source.total_moles() > 0) && (source.temperature > 0 || sink.temperature > 0))
|
if(pressure_delta > 0.01 && (source.total_moles() > 0) && (source.temperature > 0 || sink.temperature > 0))
|
||||||
//Figure out how much gas to transfer
|
//Figure out how much gas to transfer
|
||||||
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
||||||
var/transfer_moles = calc_transfer_amount(pressure_delta)
|
|
||||||
|
|
||||||
//Calculate the amount of energy required
|
var/output_volume = sink.volume
|
||||||
var/specific_entropy = sink.specific_entropy() - source.specific_entropy() //air2 is gaining moles, air1 is loosing
|
if (network2 && network2.air_transient)
|
||||||
var/specific_power = 0 // W/mol
|
output_volume = network2.air_transient.volume //use the network volume if we can get it
|
||||||
|
|
||||||
//If specific_entropy is < 0 then transfer_moles is limited by how powerful the pump is
|
//Return the number of moles that would have to be transfered to bring sink to the target pressure
|
||||||
if (specific_entropy < 0)
|
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
||||||
specific_power = -specific_entropy*air_temperature //how much power we need per mole
|
|
||||||
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
|
||||||
|
|
||||||
//Actually transfer the gas
|
//Actually transfer the gas
|
||||||
var/input_pressure = source.return_pressure()
|
|
||||||
|
//Calculate the amount of energy required
|
||||||
|
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)
|
var/datum/gas_mixture/removed = source.remove(transfer_moles)
|
||||||
if (input_pressure > 0)
|
last_flow_rate = (removed.total_moles()/(removed.total_moles() + source.total_moles()))*source.volume
|
||||||
last_flow_rate = removed.total_moles()*R_IDEAL_GAS_EQUATION*removed.temperature/input_pressure
|
|
||||||
|
|
||||||
sink.merge(removed)
|
if (power_draw > 0)
|
||||||
|
|
||||||
//If specific_entropy is < 0 then extra power needs to be supplied to move gas
|
|
||||||
if (specific_entropy < 0)
|
|
||||||
//pump draws power and heats gas according to 2nd law of thermodynamics
|
|
||||||
var/power_draw = round(transfer_moles*specific_power)
|
|
||||||
sink.add_thermal_energy(power_draw)
|
sink.add_thermal_energy(power_draw)
|
||||||
handle_power_draw(power_draw)
|
handle_power_draw(power_draw)
|
||||||
|
last_power_draw = power_draw
|
||||||
else
|
else
|
||||||
handle_power_draw(idle_power_usage)
|
handle_power_draw(idle_power_usage)
|
||||||
|
last_power_draw = idle_power_usage
|
||||||
|
|
||||||
|
sink.merge(removed)
|
||||||
|
|
||||||
if(network1)
|
if(network1)
|
||||||
network1.update = 1
|
network1.update = 1
|
||||||
@@ -120,19 +121,6 @@ Thus, the two variables affect pump operation are set in New():
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/obj/machinery/atmospherics/binary/pump/proc/calc_transfer_amount(var/pressure_delta)
|
|
||||||
var/datum/gas_mixture/source = air1
|
|
||||||
var/datum/gas_mixture/sink = air2
|
|
||||||
|
|
||||||
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
|
||||||
|
|
||||||
var/output_volume = sink.volume
|
|
||||||
if (network2 && network2.air_transient)
|
|
||||||
output_volume = network2.air_transient.volume //use the network volume if we can get it
|
|
||||||
|
|
||||||
//Return 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)
|
|
||||||
|
|
||||||
//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 so that we only have to call use_power() when the pump is loaded but not at full load.
|
||||||
/obj/machinery/atmospherics/binary/pump/proc/handle_power_draw(var/usage_amount)
|
/obj/machinery/atmospherics/binary/pump/proc/handle_power_draw(var/usage_amount)
|
||||||
if (usage_amount > active_power_usage - 5)
|
if (usage_amount > active_power_usage - 5)
|
||||||
@@ -141,7 +129,7 @@ Thus, the two variables affect pump operation are set in New():
|
|||||||
update_use_power(1)
|
update_use_power(1)
|
||||||
|
|
||||||
if (usage_amount > idle_power_usage)
|
if (usage_amount > idle_power_usage)
|
||||||
use_power(round(usage_amount)) //in practice it's pretty rare that we will get here, so calling use_power() is alright.
|
use_power(usage_amount) //in practice it's pretty rare that we will get here, so calling use_power() is alright.
|
||||||
|
|
||||||
last_power_draw = usage_amount
|
last_power_draw = usage_amount
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#define DEFAULT_PRESSURE_DELTA 10000
|
||||||
|
|
||||||
#define EXTERNAL_PRESSURE_BOUND ONE_ATMOSPHERE
|
#define EXTERNAL_PRESSURE_BOUND ONE_ATMOSPHERE
|
||||||
#define INTERNAL_PRESSURE_BOUND 0
|
#define INTERNAL_PRESSURE_BOUND 0
|
||||||
#define PRESSURE_CHECKS 1
|
#define PRESSURE_CHECKS 1
|
||||||
@@ -49,6 +51,9 @@
|
|||||||
var/radio_filter_out
|
var/radio_filter_out
|
||||||
var/radio_filter_in
|
var/radio_filter_in
|
||||||
|
|
||||||
|
//this is used to ensure process() is run before broadcasting status
|
||||||
|
var/broadcast_status_update = 0
|
||||||
|
|
||||||
/obj/machinery/atmospherics/unary/vent_pump/on
|
/obj/machinery/atmospherics/unary/vent_pump/on
|
||||||
on = 1
|
on = 1
|
||||||
icon_state = "map_vent_out"
|
icon_state = "map_vent_out"
|
||||||
@@ -87,9 +92,6 @@
|
|||||||
return
|
return
|
||||||
if (!node)
|
if (!node)
|
||||||
on = 0
|
on = 0
|
||||||
//broadcast_status() // from now air alarm/control computer should request update purposely --rastaf0
|
|
||||||
if(!on)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
overlays.Cut()
|
overlays.Cut()
|
||||||
|
|
||||||
@@ -145,140 +147,90 @@
|
|||||||
if(welded)
|
if(welded)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(pump_direction) //internal -> external
|
|
||||||
pump_to_external()
|
|
||||||
else //external -> internal
|
|
||||||
pump_to_internal()
|
|
||||||
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/atmospherics/unary/vent_pump/proc/pump_to_external()
|
|
||||||
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 = 10000
|
var/pressure_delta = DEFAULT_PRESSURE_DELTA
|
||||||
|
|
||||||
|
if(pressure_delta > 0.5)
|
||||||
|
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))
|
pressure_delta = min(pressure_delta, external_pressure_bound - environment_pressure) //increasing the pressure here
|
||||||
if(pressure_checks & PRESSURE_CHECK_INTERNAL)
|
if(pressure_checks & PRESSURE_CHECK_INTERNAL)
|
||||||
pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound))
|
pressure_delta = min(pressure_delta, air_contents.return_pressure() - internal_pressure_bound) //decreasing the pressure here
|
||||||
|
|
||||||
if(pressure_delta > 0.5 && (air_contents.temperature > 0 || environment.temperature > 0))
|
//Unfortunately there's no good way to get the volume of the room, so assume 10 tiles
|
||||||
//Figure out how much gas to transfer
|
//We will overshoot in small rooms when dealing with huge pressures but it won't be so bad
|
||||||
|
|
||||||
//unfortunately there's no good way to get the volume of the room, so assume 10 tiles
|
|
||||||
//we might overshoot in small rooms when dealing with huge pressures but it won't be so bad
|
|
||||||
var/output_volume = environment.volume * 10
|
var/output_volume = environment.volume * 10
|
||||||
var/air_temperature = environment.temperature? environment.temperature : 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)
|
||||||
|
|
||||||
//Calculate the amount of energy required
|
transfer_gas(air_contents, environment, transfer_moles)
|
||||||
var/specific_entropy = environment.specific_entropy() - air_contents.specific_entropy() //environment is gaining moles, air_contents is loosing
|
else //external -> internal
|
||||||
var/specific_power = 0 // W/mol
|
|
||||||
|
|
||||||
//If specific_entropy is < 0 then transfer_moles is limited by how powerful the pump is
|
|
||||||
if (specific_entropy < 0)
|
|
||||||
specific_power = -specific_entropy*air_temperature //how much power we need per mole
|
|
||||||
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
|
||||||
|
|
||||||
//Get the gas to be transferred
|
|
||||||
var/input_pressure = air_contents.return_pressure()
|
|
||||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
|
||||||
|
|
||||||
if (isnull(removed)) //not sure why this would happen, but it does at the very beginning of the game
|
|
||||||
update_use_power(0)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (input_pressure > 0)
|
|
||||||
last_flow_rate = removed.total_moles()*R_IDEAL_GAS_EQUATION*removed.temperature/input_pressure
|
|
||||||
|
|
||||||
//If specific_entropy is < 0 then extra power needs to be supplied to move gas
|
|
||||||
if (specific_entropy < 0)
|
|
||||||
//pump draws power and heats gas according to 2nd law of thermodynamics
|
|
||||||
var/power_draw = round(transfer_moles*specific_power)
|
|
||||||
removed.add_thermal_energy(power_draw)
|
|
||||||
handle_power_draw(power_draw)
|
|
||||||
else
|
|
||||||
handle_power_draw(idle_power_usage)
|
|
||||||
|
|
||||||
loc.assume_air(removed)
|
|
||||||
|
|
||||||
if(network)
|
|
||||||
network.update = 1
|
|
||||||
else
|
|
||||||
update_use_power(0)
|
|
||||||
|
|
||||||
//This is largely identical to pump_to_external(), except since the source and sink are two different types we can't just reuse the same proc :(
|
|
||||||
/obj/machinery/atmospherics/unary/vent_pump/proc/pump_to_internal()
|
|
||||||
var/datum/gas_mixture/environment = loc.return_air()
|
|
||||||
var/environment_pressure = environment.return_pressure()
|
|
||||||
|
|
||||||
var/pressure_delta = 10000
|
|
||||||
|
|
||||||
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
||||||
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
|
pressure_delta = min(pressure_delta, environment_pressure - external_pressure_bound) //decreasing the pressure here
|
||||||
if(pressure_checks & PRESSURE_CHECK_INTERNAL)
|
if(pressure_checks & PRESSURE_CHECK_INTERNAL)
|
||||||
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure()))
|
pressure_delta = min(pressure_delta, internal_pressure_bound - air_contents.return_pressure()) //increasing the pressure here
|
||||||
|
|
||||||
if(pressure_delta > 0.5 && (air_contents.temperature > 0 || environment.temperature > 0))
|
|
||||||
//Figure out how much gas to transfer
|
|
||||||
var/output_volume = air_contents.volume
|
var/output_volume = air_contents.volume
|
||||||
if (network && network.air_transient)
|
if (network && network.air_transient)
|
||||||
output_volume = network.air_transient.volume //use the network volume if we can get it
|
output_volume = network.air_transient.volume //use the network volume if we can get it
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
//Calculate the amount of energy required
|
transfer_gas(environment, air_contents, transfer_moles)
|
||||||
var/specific_entropy = air_contents.specific_entropy() - environment.specific_entropy() //air_contents is gaining moles, environment is loosing
|
|
||||||
var/specific_power = 0 // W/mol
|
|
||||||
|
|
||||||
//If specific_entropy is < 0 then transfer_moles is limited by how powerful the pump is
|
|
||||||
if (specific_entropy < 0)
|
|
||||||
specific_power = -specific_entropy*air_temperature //how much power we need per mole
|
|
||||||
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
|
||||||
|
|
||||||
//Get the gas to be transferred
|
|
||||||
var/input_pressure = environment.return_pressure()
|
|
||||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
|
||||||
|
|
||||||
if (isnull(removed)) //in space
|
|
||||||
update_use_power(0)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (input_pressure > 0)
|
|
||||||
last_flow_rate = removed.total_moles()*R_IDEAL_GAS_EQUATION*removed.temperature/input_pressure
|
|
||||||
|
|
||||||
//If specific_entropy is < 0 then extra power needs to be supplied to move gas
|
|
||||||
if (specific_entropy < 0)
|
|
||||||
//pump draws power and heats gas according to 2nd law of thermodynamics
|
|
||||||
var/power_draw = round(transfer_moles*specific_power)
|
|
||||||
removed.add_thermal_energy(power_draw)
|
|
||||||
handle_power_draw(power_draw)
|
|
||||||
else
|
|
||||||
handle_power_draw(idle_power_usage)
|
|
||||||
|
|
||||||
air_contents.merge(removed)
|
|
||||||
|
|
||||||
if(network)
|
if(network)
|
||||||
network.update = 1
|
network.update = 1
|
||||||
else
|
else
|
||||||
update_use_power(0)
|
update_use_power(0)
|
||||||
|
|
||||||
//This proc handles power usages so that we only have to call use_power() when the pump is loaded but not at full load.
|
process_broadcast_status()
|
||||||
/obj/machinery/atmospherics/unary/vent_pump/proc/handle_power_draw(var/usage_amount)
|
|
||||||
if (usage_amount > active_power_usage - 5)
|
return 1
|
||||||
update_use_power(2)
|
|
||||||
|
/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)
|
||||||
|
update_use_power(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
//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
|
||||||
|
if (specific_power > 0)
|
||||||
|
transfer_moles = min(transfer_moles, active_power_usage / specific_power)
|
||||||
|
|
||||||
|
//Get the gas to be transferred
|
||||||
|
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
|
||||||
|
return
|
||||||
|
|
||||||
|
last_flow_rate = (removed.total_moles()/(removed.total_moles() + source.total_moles()))*source.volume
|
||||||
|
|
||||||
|
var/power_draw = specific_power*transfer_moles
|
||||||
|
if (power_draw > 0)
|
||||||
|
removed.add_thermal_energy(power_draw)
|
||||||
|
handle_pump_power_draw(power_draw)
|
||||||
|
last_power_draw = power_draw
|
||||||
else
|
else
|
||||||
update_use_power(1)
|
handle_pump_power_draw(idle_power_usage)
|
||||||
|
last_power_draw = idle_power_usage
|
||||||
|
|
||||||
if (usage_amount > idle_power_usage)
|
//merge the removed gas into the sink
|
||||||
use_power(round(usage_amount))
|
sink.merge(removed)
|
||||||
|
|
||||||
last_power_draw = usage_amount
|
/* Uncomment this in case it actually matters whether we call assume_air() or just merge with the returned air directly
|
||||||
|
if (istype(sink, /datum/gas_mixture)
|
||||||
|
var/datum/gas_mixture/M = sink
|
||||||
|
M.merge(removed)
|
||||||
|
else if (istype(sink, /turf)
|
||||||
|
var/turf/T = sink
|
||||||
|
T.assume_air(removed)
|
||||||
|
*/
|
||||||
|
|
||||||
//Radio remote control
|
//Radio remote control
|
||||||
|
|
||||||
@@ -289,6 +241,14 @@
|
|||||||
radio_connection = radio_controller.add_object(src, frequency,radio_filter_in)
|
radio_connection = radio_controller.add_object(src, frequency,radio_filter_in)
|
||||||
|
|
||||||
/obj/machinery/atmospherics/unary/vent_pump/proc/broadcast_status()
|
/obj/machinery/atmospherics/unary/vent_pump/proc/broadcast_status()
|
||||||
|
broadcast_status_update = 1
|
||||||
|
|
||||||
|
|
||||||
|
/obj/machinery/atmospherics/unary/vent_pump/proc/process_broadcast_status()
|
||||||
|
if (!broadcast_status_update)
|
||||||
|
return 0
|
||||||
|
broadcast_status_update = 0
|
||||||
|
|
||||||
if(!radio_connection)
|
if(!radio_connection)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
{{:value.title}}:
|
{{:value.title}}:
|
||||||
</div>
|
</div>
|
||||||
<div class="itemContent" style="width: 70px; text-align: right">
|
<div class="itemContent" style="width: 70px; text-align: right">
|
||||||
{{:value.powerLoad}} W
|
{{:value.powerLoad}} W
|
||||||
</div>
|
</div>
|
||||||
<div class="itemContent" style="width: 105px">
|
<div class="itemContent" style="width: 105px">
|
||||||
|
|
||||||
@@ -136,8 +136,8 @@
|
|||||||
<div class="itemLabel">
|
<div class="itemLabel">
|
||||||
Total Load:
|
Total Load:
|
||||||
</div>
|
</div>
|
||||||
<div class="itemContent" style="width: 70px; text-align: right">
|
<div class="itemContent">
|
||||||
{{:data.totalLoad}} W
|
{{:data.totalLoad}} W
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user