add sleeping for ZAS connection edges

Edges will sleep and fully balance if compare() passes.
also some small small xgm tweaks.

Signed-off-by: Mloc-Argent <colmohici@gmail.com>
This commit is contained in:
Mloc-Argent
2014-12-21 20:35:40 +00:00
parent fc203f186a
commit debba68c44
5 changed files with 141 additions and 62 deletions

View File

@@ -62,6 +62,7 @@ Class Procs:
/connection_edge/var/list/connecting_turfs = list() /connection_edge/var/list/connecting_turfs = list()
/connection_edge/var/direct = 0 /connection_edge/var/direct = 0
/connection_edge/var/sleeping = 1
/connection_edge/var/coefficient = 0 /connection_edge/var/coefficient = 0
@@ -88,6 +89,8 @@ Class Procs:
/connection_edge/proc/tick() /connection_edge/proc/tick()
/connection_edge/proc/recheck()
/connection_edge/proc/flow(list/movable, differential, repelled) /connection_edge/proc/flow(list/movable, differential, repelled)
for(var/i = 1; i <= movable.len; i++) for(var/i = 1; i <= movable.len; i++)
var/atom/movable/M = movable[i] var/atom/movable/M = movable[i]
@@ -147,35 +150,38 @@ Class Procs:
if(A.invalid || B.invalid) if(A.invalid || B.invalid)
erase() erase()
return return
//world << "[id]: Tick [air_master.current_cycle]: \..."
if(direct)
if(air_master.equivalent_pressure(A, B))
//world << "merged."
erase()
air_master.merge(A, B)
//world << "zones merged."
return
//air_master.equalize(A, B) var/equiv = A.air.share_ratio(B.air, coefficient)
A.air.share_ratio(B.air, coefficient)
air_master.mark_zone_update(A)
air_master.mark_zone_update(B)
//world << "equalized."
var/differential = A.air.return_pressure() - B.air.return_pressure() var/differential = A.air.return_pressure() - B.air.return_pressure()
if(abs(differential) < vsc.airflow_lightest_pressure) return if(abs(differential) >= vsc.airflow_lightest_pressure)
var/list/attracted
var/list/repelled
if(differential > 0)
attracted = A.movables()
repelled = B.movables()
else
attracted = B.movables()
repelled = A.movables()
var/list/attracted flow(attracted, abs(differential), 0)
var/list/repelled flow(repelled, abs(differential), 1)
if(differential > 0)
attracted = A.movables()
repelled = B.movables()
else
attracted = B.movables()
repelled = A.movables()
flow(attracted, abs(differential), 0) if(equiv)
flow(repelled, abs(differential), 1) if(direct)
erase()
air_master.merge(A, B)
return
else
A.air.equalize(B.air)
air_master.mark_edge_sleeping(src)
air_master.mark_zone_update(A)
air_master.mark_zone_update(B)
/connection_edge/zone/recheck()
if(!A.air.compare(B.air))
air_master.mark_edge_active(src)
//Helper proc to get connections for a zone. //Helper proc to get connections for a zone.
/connection_edge/zone/proc/get_connected_zone(zone/from) /connection_edge/zone/proc/get_connected_zone(zone/from)
@@ -214,20 +220,27 @@ Class Procs:
if(A.invalid) if(A.invalid)
erase() erase()
return return
//world << "[id]: Tick [air_master.current_cycle]: To [B]!"
//A.air.mimic(B, coefficient) var/equiv = A.air.share_space(air)
A.air.share_space(air, dbg_out)
air_master.mark_zone_update(A)
var/differential = A.air.return_pressure() - air.return_pressure() var/differential = A.air.return_pressure() - air.return_pressure()
if(abs(differential) < vsc.airflow_lightest_pressure) return if(abs(differential) >= vsc.airflow_lightest_pressure)
var/list/attracted = A.movables()
flow(attracted, abs(differential), differential < 0)
var/list/attracted = A.movables() if(equiv)
flow(attracted, abs(differential), differential < 0) A.air.copy_from(air)
air_master.mark_edge_sleeping(src)
air_master.mark_zone_update(A)
/connection_edge/unsimulated/recheck()
if(!A.air.compare(air))
air_master.mark_edge_active(src)
proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
//This implements a simplistic version of the Stefan-Boltzmann law. //This implements a simplistic version of the Stefan-Boltzmann law.
var/energy_delta = ((A.temperature - B.temperature) ** 4) * 5.6704e-8 * connecting_tiles * 2.5 var/energy_delta = ((A.temperature - B.temperature) ** 4) * STEFAN_BOLTZMANN_CONSTANT * connecting_tiles * 2.5
var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier)) var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier))
if(maximum_energy_delta > abs(energy_delta)) if(maximum_energy_delta > abs(energy_delta))
if(energy_delta < 0) if(energy_delta < 0)
@@ -235,4 +248,4 @@ proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
energy_delta = maximum_energy_delta energy_delta = maximum_energy_delta
A.temperature -= energy_delta / (A.heat_capacity() * A.group_multiplier) A.temperature -= energy_delta / (A.heat_capacity() * A.group_multiplier)
B.temperature += energy_delta / (B.heat_capacity() * B.group_multiplier) B.temperature += energy_delta / (B.heat_capacity() * B.group_multiplier)

View File

@@ -75,6 +75,7 @@ Class Procs:
/datum/controller/air_system/var/list/zones_to_update = list() /datum/controller/air_system/var/list/zones_to_update = list()
/datum/controller/air_system/var/list/active_fire_zones = list() /datum/controller/air_system/var/list/active_fire_zones = list()
/datum/controller/air_system/var/list/active_hotspots = list() /datum/controller/air_system/var/list/active_hotspots = list()
/datum/controller/air_system/var/list/active_edges = list()
/datum/controller/air_system/var/active_zones = 0 /datum/controller/air_system/var/active_zones = 0
@@ -97,7 +98,7 @@ Class Procs:
set background = 1 set background = 1
#endif #endif
world << "\red \b Processing Geometry..." world << "<span class='danger'>Processing Geometry...</span>"
sleep(-1) sleep(-1)
var/start_time = world.timeofday var/start_time = world.timeofday
@@ -108,10 +109,15 @@ Class Procs:
simulated_turf_count++ simulated_turf_count++
S.update_air_properties() S.update_air_properties()
world << {"<font color='red'><b>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</b> world << {"<span class='danger'>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</b></span>
<span class='info'>
Total Simulated Turfs: [simulated_turf_count] Total Simulated Turfs: [simulated_turf_count]
Total Zones: [zones.len] Total Zones: [zones.len]
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]</font>"} Total Edges: [edges.len]
Total Active Edges: [active_edges.len ? "<span class='danger'>[active_edges.len]</span>" : "None"]
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]</font>
</span>"}
// spawn Start() // spawn Start()
@@ -169,7 +175,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
if(.) if(.)
tick_progress = "processing edges" tick_progress = "processing edges"
for(var/connection_edge/edge in edges) for(var/connection_edge/edge in active_edges)
edge.tick() edge.tick()
//Process fire zones. //Process fire zones.
@@ -299,6 +305,22 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
zones_to_update.Add(Z) zones_to_update.Add(Z)
Z.needs_update = 1 Z.needs_update = 1
/datum/controller/air_system/proc/mark_edge_sleeping(connection_edge/E)
#ifdef ZASDBG
ASSERT(istype(E)
#endif
if(E.sleeping) return
active_edges.Remove(E)
E.sleeping = 1
/datum/controller/air_system/proc/mark_edge_active(connection_edge/E)
#ifdef ZASDBG
ASSERT(istype(E)
#endif
if(!E.sleeping) return
active_edges.Add(E)
E.sleeping = 0
/datum/controller/air_system/proc/equivalent_pressure(zone/A, zone/B) /datum/controller/air_system/proc/equivalent_pressure(zone/A, zone/B)
return A.air.compare(B.air) return A.air.compare(B.air)
@@ -309,12 +331,14 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
if(edge.contains_zone(B)) return edge if(edge.contains_zone(B)) return edge
var/connection_edge/edge = new/connection_edge/zone(A,B) var/connection_edge/edge = new/connection_edge/zone(A,B)
edges.Add(edge) edges.Add(edge)
edge.recheck()
return edge return edge
else else
for(var/connection_edge/unsimulated/edge in A.edges) for(var/connection_edge/unsimulated/edge in A.edges)
if(has_same_air(edge.B,B)) return edge if(has_same_air(edge.B,B)) return edge
var/connection_edge/edge = new/connection_edge/unsimulated(A,B) var/connection_edge/edge = new/connection_edge/unsimulated(A,B)
edges.Add(edge) edges.Add(edge)
edge.recheck()
return edge return edge
/datum/controller/air_system/proc/has_same_air(turf/A, turf/B) /datum/controller/air_system/proc/has_same_air(turf/A, turf/B)
@@ -325,5 +349,6 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
if(A.temperature != B.temperature) return 0 if(A.temperature != B.temperature) return 0
return 1 return 1
/datum/controller/air_system/proc/remove_edge(connection/c) /datum/controller/air_system/proc/remove_edge(connection_edge/E)
edges.Remove(c) edges.Remove(E)
if(!E.sleeping) active_edges.Remove(E)

View File

@@ -138,6 +138,10 @@ Class Procs:
graphic_add.len = 0 graphic_add.len = 0
graphic_remove.len = 0 graphic_remove.len = 0
for(var/connection_edge/E in edges)
if(E.sleeping)
E.recheck()
/zone/proc/dbg_data(mob/M) /zone/proc/dbg_data(mob/M)
M << name M << name
for(var/g in air.gas) for(var/g in air.gas)

View File

@@ -17,7 +17,8 @@
//List of active tile overlays for this gas_mixture. Updated by check_tile_graphic() //List of active tile overlays for this gas_mixture. Updated by check_tile_graphic()
var/list/graphic = list() var/list/graphic = list()
//Takes a gas string, and the amount of moles to adjust by. Calls update_values() if update isn't 0.
//Takes a gas string and the amount of moles to adjust by. Calls update_values() if update isn't 0.
/datum/gas_mixture/proc/adjust_gas(gasid, moles, update = 1) /datum/gas_mixture/proc/adjust_gas(gasid, moles, update = 1)
if(moles == 0) if(moles == 0)
return return
@@ -30,6 +31,7 @@
if(update) if(update)
update_values() update_values()
//Same as adjust_gas(), but takes a temperature which is mixed in with the gas. //Same as adjust_gas(), but takes a temperature which is mixed in with the gas.
/datum/gas_mixture/proc/adjust_gas_temp(gasid, moles, temp, update = 1) /datum/gas_mixture/proc/adjust_gas_temp(gasid, moles, temp, update = 1)
if(moles == 0) if(moles == 0)
@@ -50,7 +52,8 @@
if(update) if(update)
update_values() update_values()
//Variadic version of adjust_gas(). Takes any number of gas and mole pairs, and applies them.
//Variadic version of adjust_gas(). Takes any number of gas and mole pairs and applies them.
/datum/gas_mixture/proc/adjust_multi() /datum/gas_mixture/proc/adjust_multi()
ASSERT(!(args.len % 2)) ASSERT(!(args.len % 2))
@@ -59,7 +62,8 @@
update_values() update_values()
//Variadic version of adjust_gas_temp(). Takes any number of gas, mole, and temperature tuples, and applies them.
//Variadic version of adjust_gas_temp(). Takes any number of gas, mole and temperature associations and applies them.
/datum/gas_mixture/proc/adjust_multi_temp() /datum/gas_mixture/proc/adjust_multi_temp()
ASSERT(!(args.len % 3)) ASSERT(!(args.len % 3))
@@ -68,8 +72,10 @@
update_values() update_values()
//Merges all the gas from another mixture into this one. Respects group_multipliers and adjusts temperature correctly. //Merges all the gas from another mixture into this one. Respects group_multipliers and adjusts temperature correctly.
/datum/gas_mixture/proc/merge(datum/gas_mixture/giver) //Does not modify giver in any way.
/datum/gas_mixture/proc/merge(const/datum/gas_mixture/giver)
if(!giver) if(!giver)
return return
@@ -89,6 +95,25 @@
update_values() update_values()
/datum/gas_mixture/proc/equalize(datum/gas_mixture/sharer)
for(var/g in sharer.gas)
var/comb = gas[g] + sharer.gas[g]
comb /= volume + sharer.volume
gas[g] = comb * volume
sharer.gas[g] = comb * sharer.volume
var/our_heatcap = heat_capacity()
var/share_heatcap = sharer.heat_capacity()
temperature = 0
if(our_heatcap + share_heatcap)
temperature = ((temperature * our_heatcap) + (sharer.temperature * share_heatcap)) / (our_heatcap + share_heatcap)
sharer.temperature = temperature
return 1
//Returns the heat capacity of the gas mix based on the specific heat of the gases. //Returns the heat capacity of the gas mix based on the specific heat of the gases.
/datum/gas_mixture/proc/heat_capacity() /datum/gas_mixture/proc/heat_capacity()
. = 0 . = 0
@@ -96,11 +121,12 @@
. += gas_data.specific_heat[g] * gas[g] . += gas_data.specific_heat[g] * gas[g]
. *= group_multiplier . *= group_multiplier
//Adds or removes thermal energy. Returns the actual thermal energy change, as in the case of removing energy we can't go below TCMB. //Adds or removes thermal energy. Returns the actual thermal energy change, as in the case of removing energy we can't go below TCMB.
/datum/gas_mixture/proc/add_thermal_energy(var/thermal_energy) /datum/gas_mixture/proc/add_thermal_energy(var/thermal_energy)
if (total_moles == 0) if (total_moles == 0)
return 0 return 0
var/heat_capacity = heat_capacity() var/heat_capacity = heat_capacity()
if (thermal_energy < 0) if (thermal_energy < 0)
if (temperature < TCMB) if (temperature < TCMB)
@@ -114,43 +140,47 @@
/datum/gas_mixture/proc/get_thermal_energy_change(var/new_temperature) /datum/gas_mixture/proc/get_thermal_energy_change(var/new_temperature)
return heat_capacity()*(max(new_temperature, 0) - temperature) return heat_capacity()*(max(new_temperature, 0) - temperature)
//Technically vacuum doesn't have a specific entropy. Just use a really big number (infinity would be ideal) here so that it's easy to add gas to vacuum and hard to take gas out. //Technically vacuum doesn't have a specific entropy. Just use a really big number (infinity would be ideal) here so that it's easy to add gas to vacuum and hard to take gas out.
#define SPECIFIC_ENTROPY_VACUUM 150000 #define SPECIFIC_ENTROPY_VACUUM 150000
//Returns the ideal gas specific entropy of the whole mix. This is the entropy per mole of /mixed/ gas. //Returns the ideal gas specific entropy of the whole mix. This is the entropy per mole of /mixed/ gas.
/datum/gas_mixture/proc/specific_entropy() /datum/gas_mixture/proc/specific_entropy()
if (!gas.len || total_moles == 0) if (!gas.len || total_moles == 0)
return SPECIFIC_ENTROPY_VACUUM return SPECIFIC_ENTROPY_VACUUM
. = 0 . = 0
for(var/g in gas) for(var/g in gas)
. += gas[g] * specific_entropy_gas(g) . += gas[g] * specific_entropy_gas(g)
. /= total_moles . /= total_moles
/* /*
It's arguable whether this should even be called entropy anymore. It's more "based on" entropy than actually entropy now. It's arguable whether this should even be called entropy anymore. It's more "based on" entropy than actually entropy now.
Returns the ideal gas specific entropy of a specific gas in the mix. This is the entropy due to that gas per mole of /that/ gas in the mixture, not the entropy due to that gas per mole of gas mixture. Returns the ideal gas specific entropy of a specific gas in the mix. This is the entropy due to that gas per mole of /that/ gas in the mixture, not the entropy due to that gas per mole of gas mixture.
For the purposes of SS13, the specific entropy is just a number that tells you how hard it is to move gas. You can replace this with whatever you want. For the purposes of SS13, the specific entropy is just a number that tells you how hard it is to move gas. You can replace this with whatever you want.
Just remember that returning a SMALL number == adding gas to this gas mix is HARD, taking gas away is EASY, and that returning a LARGE number means the opposite (so a vacuum should approach infinity). Just remember that returning a SMALL number == adding gas to this gas mix is HARD, taking gas away is EASY, and that returning a LARGE number means the opposite (so a vacuum should approach infinity).
So returning a constant/(partial pressure) would probably do what most players expect. Although the version I have implemented below is a bit more nuanced than simply 1/P in that it scales in a way So returning a constant/(partial pressure) would probably do what most players expect. Although the version I have implemented below is a bit more nuanced than simply 1/P in that it scales in a way
which is bit more realistic (natural log), and returns a fairly accurate entropy around room temperatures and pressures. which is bit more realistic (natural log), and returns a fairly accurate entropy around room temperatures and pressures.
*/ */
/datum/gas_mixture/proc/specific_entropy_gas(var/gasid) /datum/gas_mixture/proc/specific_entropy_gas(var/gasid)
if (!(gasid in gas) || gas[gasid] == 0) if (!(gasid in gas) || gas[gasid] == 0)
return SPECIFIC_ENTROPY_VACUUM //that gas isn't here return SPECIFIC_ENTROPY_VACUUM //that gas isn't here
//group_multiplier gets divided out in volume/gas[gasid] - also, V/(m*T) = R/(partial pressure) //group_multiplier gets divided out in volume/gas[gasid] - also, V/(m*T) = R/(partial pressure)
var/molar_mass = gas_data.molar_mass[gasid] var/molar_mass = gas_data.molar_mass[gasid]
var/specific_heat = gas_data.specific_heat[gasid] var/specific_heat = gas_data.specific_heat[gasid]
return R_IDEAL_GAS_EQUATION * ( log( (IDEAL_GAS_ENTROPY_CONSTANT*volume/(gas[gasid] * temperature)) * (molar_mass*specific_heat*temperature)**(2/3) + 1 ) + 15 ) return R_IDEAL_GAS_EQUATION * ( log( (IDEAL_GAS_ENTROPY_CONSTANT*volume/(gas[gasid] * temperature)) * (molar_mass*specific_heat*temperature)**(2/3) + 1 ) + 15 )
//alternative, simpler equation //alternative, simpler equation
//var/partial_pressure = gas[gasid] * R_IDEAL_GAS_EQUATION * temperature / volume //var/partial_pressure = gas[gasid] * R_IDEAL_GAS_EQUATION * temperature / volume
//return R_IDEAL_GAS_EQUATION * ( log (1 + IDEAL_GAS_ENTROPY_CONSTANT/partial_pressure) + 20 ) //return R_IDEAL_GAS_EQUATION * ( log (1 + IDEAL_GAS_ENTROPY_CONSTANT/partial_pressure) + 20 )
//Updates the total_moles count and trims any empty gases. //Updates the total_moles count and trims any empty gases.
/datum/gas_mixture/proc/update_values() /datum/gas_mixture/proc/update_values()
total_moles = 0 total_moles = 0
@@ -160,12 +190,14 @@
else else
total_moles += gas[g] total_moles += gas[g]
//Returns the pressure of the gas mix. Only accurate if there have been no gas modifications since update_values() has been called. //Returns the pressure of the gas mix. Only accurate if there have been no gas modifications since update_values() has been called.
/datum/gas_mixture/proc/return_pressure() /datum/gas_mixture/proc/return_pressure()
if(volume) if(volume)
return total_moles * R_IDEAL_GAS_EQUATION * temperature / volume return total_moles * R_IDEAL_GAS_EQUATION * temperature / volume
return 0 return 0
//Removes moles from the gas mixture and returns a gas_mixture containing the removed air. //Removes moles from the gas mixture and returns a gas_mixture containing the removed air.
/datum/gas_mixture/proc/remove(amount) /datum/gas_mixture/proc/remove(amount)
amount = min(amount, total_moles * group_multiplier) //Can not take more air than the gas mixture has! amount = min(amount, total_moles * group_multiplier) //Can not take more air than the gas mixture has!
@@ -184,6 +216,7 @@
return removed return removed
//Removes a ratio of gas from the mixture and returns a gas_mixture containing the removed air. //Removes a ratio of gas from the mixture and returns a gas_mixture containing the removed air.
/datum/gas_mixture/proc/remove_ratio(ratio, out_group_multiplier = 1) /datum/gas_mixture/proc/remove_ratio(ratio, out_group_multiplier = 1)
if(ratio <= 0) if(ratio <= 0)
@@ -205,6 +238,7 @@
return removed return removed
//Removes moles from the gas mixture, limited by a given flag. Returns a gax_mixture containing the removed air. //Removes moles from the gas mixture, limited by a given flag. Returns a gax_mixture containing the removed air.
/datum/gas_mixture/proc/remove_by_flag(flag, amount) /datum/gas_mixture/proc/remove_by_flag(flag, amount)
if(!flag || amount <= 0) if(!flag || amount <= 0)
@@ -228,8 +262,9 @@
return removed return removed
//Copies gas and temperature from another gas_mixture. //Copies gas and temperature from another gas_mixture.
/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample) /datum/gas_mixture/proc/copy_from(const/datum/gas_mixture/sample)
gas = sample.gas.Copy() gas = sample.gas.Copy()
temperature = sample.temperature temperature = sample.temperature
@@ -237,8 +272,9 @@
return 1 return 1
//Checks if we are within acceptable range of another gas_mixture to suspend processing or merge. //Checks if we are within acceptable range of another gas_mixture to suspend processing or merge.
/datum/gas_mixture/proc/compare(datum/gas_mixture/sample) /datum/gas_mixture/proc/compare(const/datum/gas_mixture/sample)
if(!sample) return 0 if(!sample) return 0
var/list/marked = list() var/list/marked = list()
@@ -264,9 +300,11 @@
return 1 return 1
/datum/gas_mixture/proc/react(atom/dump_location) /datum/gas_mixture/proc/react(atom/dump_location)
zburn(null) zburn(null)
//Rechecks the gas_mixture and adjusts the graphic list if needed. //Rechecks the gas_mixture and adjusts the graphic list if needed.
//Two lists can be passed by reference if you need know specifically which graphics were added and removed. //Two lists can be passed by reference if you need know specifically which graphics were added and removed.
/datum/gas_mixture/proc/check_tile_graphic(list/graphic_add = null, list/graphic_remove = null) /datum/gas_mixture/proc/check_tile_graphic(list/graphic_add = null, list/graphic_remove = null)
@@ -293,6 +331,7 @@
graphic -= graphic_remove graphic -= graphic_remove
. = 1 . = 1
//Simpler version of merge(), adjusts gas amounts directly and doesn't account for temperature or group_multiplier. //Simpler version of merge(), adjusts gas amounts directly and doesn't account for temperature or group_multiplier.
/datum/gas_mixture/proc/add(datum/gas_mixture/right_side) /datum/gas_mixture/proc/add(datum/gas_mixture/right_side)
for(var/g in right_side.gas) for(var/g in right_side.gas)
@@ -301,6 +340,7 @@
update_values() update_values()
return 1 return 1
//Simpler version of remove(), adjusts gas amounts directly and doesn't account for group_multiplier. //Simpler version of remove(), adjusts gas amounts directly and doesn't account for group_multiplier.
/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side) /datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side)
for(var/g in right_side.gas) for(var/g in right_side.gas)
@@ -309,6 +349,7 @@
update_values() update_values()
return 1 return 1
//Multiply all gas amounts by a factor. //Multiply all gas amounts by a factor.
/datum/gas_mixture/proc/multiply(factor) /datum/gas_mixture/proc/multiply(factor)
for(var/g in gas) for(var/g in gas)
@@ -317,6 +358,7 @@
update_values() update_values()
return 1 return 1
//Divide all gas amounts by a factor. //Divide all gas amounts by a factor.
/datum/gas_mixture/proc/divide(factor) /datum/gas_mixture/proc/divide(factor)
for(var/g in gas) for(var/g in gas)
@@ -325,6 +367,7 @@
update_values() update_values()
return 1 return 1
//Shares gas with another gas_mixture based on the amount of connecting tiles and a fixed lookup table. //Shares gas with another gas_mixture based on the amount of connecting tiles and a fixed lookup table.
/datum/gas_mixture/proc/share_ratio(datum/gas_mixture/other, connecting_tiles, share_size = null, one_way = 0) /datum/gas_mixture/proc/share_ratio(datum/gas_mixture/other, connecting_tiles, share_size = null, one_way = 0)
var/static/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66) var/static/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66)
@@ -369,19 +412,13 @@
update_values() update_values()
other.update_values() other.update_values()
if(compare(other)) return 1 return compare(other)
else return 0
//A wrapper around share_ratio for spacing gas at the same rate as if it were going into a large airless room. //A wrapper around share_ratio for spacing gas at the same rate as if it were going into a large airless room.
/datum/gas_mixture/proc/share_space(datum/gas_mixture/unsim_air) /datum/gas_mixture/proc/share_space(datum/gas_mixture/unsim_air)
if(!unsim_air) return share_ratio(unsim_air, unsim_air.group_multiplier, max(1, max(group_multiplier + 3, 1) + unsim_air.group_multiplier), one_way = 1)
return 0
var/old_pressure = return_pressure()
share_ratio(unsim_air, unsim_air.group_multiplier, max(1, max(group_multiplier + 3, 1) + unsim_air.group_multiplier), one_way = 1)
return abs(old_pressure - return_pressure())
//Equalizes a list of gas mixtures. Used for pipe networks. //Equalizes a list of gas mixtures. Used for pipe networks.
/proc/equalize_gases(datum/gas_mixture/list/gases) /proc/equalize_gases(datum/gas_mixture/list/gases)

View File

@@ -9,7 +9,7 @@
#define IDEAL_GAS_ENTROPY_CONSTANT 1164 //(mol^3 * s^3) / (kg^3 * L). Equal to (4*pi/(avrogadro's number * planck's constant)^2)^(3/2) / (avrogadro's number * 1000 Liters per m^3). #define IDEAL_GAS_ENTROPY_CONSTANT 1164 //(mol^3 * s^3) / (kg^3 * L). Equal to (4*pi/(avrogadro's number * planck's constant)^2)^(3/2) / (avrogadro's number * 1000 Liters per m^3).
//radiation constants //radiation constants
#define STEFAN_BOLTZMANN_CONSTANT 0.0000000567 //W/(m^2*K^4) #define STEFAN_BOLTZMANN_CONSTANT 5.6704e-8 //W/(m^2*K^4)
#define COSMIC_RADIATION_TEMPERATURE 3.15 //K #define COSMIC_RADIATION_TEMPERATURE 3.15 //K
#define AVERAGE_SOLAR_RADIATION 200 //W/m^2. Kind of arbitrary. Really this should depend on the sun position much like solars. #define AVERAGE_SOLAR_RADIATION 200 //W/m^2. Kind of arbitrary. Really this should depend on the sun position much like solars.
#define RADIATOR_OPTIMUM_PRESSURE 110 //kPa at 20 C #define RADIATOR_OPTIMUM_PRESSURE 110 //kPa at 20 C