mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Moves around some ZAS stuff and fixes some things in FEA gas mixtures.
ShareSpace now can take a gas mixture as an argument, alongside the usual list of tiles. Three new procs on gas mixtures, add() multiply() and divide(). Self explanatory. Zones with unsimulated tiles that sleep will now reset themselves to the average air. assume_air will only add air to sleeping zones with unsimulated tiles if it can wake the zone up. Signed-off-by: Mloc <colmohici@gmail.com>
This commit is contained in:
@@ -965,6 +965,7 @@ What are the archived variables for?
|
||||
//Outputs: 1 if can rebuild, 0 if not.
|
||||
if(!sample) return 0
|
||||
|
||||
|
||||
if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen)))
|
||||
return 0
|
||||
@@ -972,52 +973,61 @@ What are the archived variables for?
|
||||
((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen)))
|
||||
return 0
|
||||
if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
|
||||
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
|
||||
return 0
|
||||
if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins)))
|
||||
return 0
|
||||
|
||||
|
||||
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
|
||||
((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature)))
|
||||
//world << "temp fail [temperature] & [sample.temperature]"
|
||||
return 0
|
||||
|
||||
var/check_moles
|
||||
if(sample.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sample.trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((corresponding.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (corresponding.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
check_moles = corresponding.moles
|
||||
else
|
||||
check_moles = 0
|
||||
|
||||
if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((check_moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (check_moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sample.trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
check_moles = corresponding.moles
|
||||
else
|
||||
check_moles = 0
|
||||
|
||||
if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles)))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/compare_unsim(turf/list/samples)
|
||||
//Purpose: Compares a list of unsimulated tiles to self to see if within acceptable ranges that group processing may be enabled
|
||||
//Called by: ZAS sleeping detection.
|
||||
//Inputs: List of unsimulated turfs to compare to
|
||||
//Outputs: 1 if within an acceptable range to sleep, 0 otherwise.
|
||||
var/datum/gas_mixture/after_share = new
|
||||
after_share.copy_from(src)
|
||||
/datum/gas_mixture/proc/add(datum/gas_mixture/right_side)
|
||||
oxygen += right_side.oxygen
|
||||
carbon_dioxide += right_side.carbon_dioxide
|
||||
nitrogen += right_side.nitrogen
|
||||
toxins += right_side.toxins
|
||||
|
||||
ShareSpace(after_share, samples)
|
||||
if(trace_gases.len || right_side.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in right_side.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
corresponding.moles += trace_gas.moles
|
||||
|
||||
return src.compare(after_share)
|
||||
update_values()
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side)
|
||||
//Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle
|
||||
@@ -1025,18 +1035,42 @@ What are the archived variables for?
|
||||
//Inputs: Gas mix to remove
|
||||
//Outputs: 1
|
||||
|
||||
oxygen -= right_side.oxygen
|
||||
carbon_dioxide -= right_side.carbon_dioxide
|
||||
nitrogen -= right_side.nitrogen
|
||||
toxins -= right_side.toxins
|
||||
oxygen = max(oxygen - right_side.oxygen)
|
||||
carbon_dioxide = max(carbon_dioxide - right_side.carbon_dioxide)
|
||||
nitrogen = max(nitrogen - right_side.nitrogen)
|
||||
toxins = max(toxins - right_side.toxins)
|
||||
|
||||
if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
|
||||
if(trace_gases.len || right_side.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in right_side.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
if(corresponding)
|
||||
corresponding.moles = max(0, corresponding.moles - trace_gas.moles)
|
||||
|
||||
corresponding.moles -= trace_gas.moles
|
||||
update_values()
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/multiply(factor)
|
||||
oxygen *= factor
|
||||
carbon_dioxide *= factor
|
||||
nitrogen *= factor
|
||||
toxins *= factor
|
||||
|
||||
if(trace_gases && trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
trace_gas.moles *= factor
|
||||
|
||||
update_values()
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/divide(factor)
|
||||
oxygen /= factor
|
||||
carbon_dioxide /= factor
|
||||
nitrogen /= factor
|
||||
toxins /= factor
|
||||
|
||||
if(trace_gases && trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
trace_gas.moles /= factor
|
||||
|
||||
update_values()
|
||||
return 1
|
||||
|
||||
@@ -10,6 +10,9 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
var/list/contents //All the tiles that are contained in this zone.
|
||||
var/list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
|
||||
|
||||
var/datum/gas_mixture/air_unsim //Overall average of the air in connected unsimualted tiles.
|
||||
var/unsim_air_needs_update = 0 //Set to 1 on geometry changes, marks air_unsim as needing update.
|
||||
|
||||
var/list/connections //connection objects which refer to connections with other zones, e.g. through a door.
|
||||
var/list/direct_connections //connections which directly connect two zones.
|
||||
|
||||
@@ -126,6 +129,8 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
unsimulated_tiles += T
|
||||
contents -= T
|
||||
|
||||
unsim_air_needs_update = 1
|
||||
|
||||
/zone/proc/RemoveTurf(turf/T)
|
||||
//Same, but in reverse.
|
||||
if(istype(T, /turf/simulated))
|
||||
@@ -146,6 +151,45 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
if(!unsimulated_tiles.len)
|
||||
unsimulated_tiles = null
|
||||
|
||||
unsim_air_needs_update = 1
|
||||
|
||||
//Updates the air_unsim var
|
||||
/zone/proc/UpdateUnsimAvg()
|
||||
if(!unsim_air_needs_update)
|
||||
return
|
||||
|
||||
unsim_air_needs_update = 0
|
||||
|
||||
if(!air_unsim)
|
||||
air_unsim = new /datum/gas_mixture
|
||||
|
||||
air_unsim.oxygen = 0
|
||||
air_unsim.nitrogen = 0
|
||||
air_unsim.carbon_dioxide = 0
|
||||
air_unsim.toxins = 0
|
||||
air_unsim.temperature = 0
|
||||
|
||||
var/correction_ratio = max(1, max(max(1, air.group_multiplier) + 3, 1) + unsimulated_tiles.len) / unsimulated_tiles.len
|
||||
|
||||
for(var/turf/T in unsimulated_tiles)
|
||||
if(!istype(T, /turf/simulated))
|
||||
air_unsim.oxygen += T.oxygen
|
||||
air_unsim.carbon_dioxide += T.carbon_dioxide
|
||||
air_unsim.nitrogen += T.nitrogen
|
||||
air_unsim.toxins += T.toxins
|
||||
air_unsim.temperature += T.temperature/unsimulated_tiles.len
|
||||
|
||||
//These values require adjustment in order to properly represent a room of the specified size.
|
||||
air_unsim.oxygen *= correction_ratio
|
||||
air_unsim.carbon_dioxide *= correction_ratio
|
||||
air_unsim.nitrogen *= correction_ratio
|
||||
air_unsim.toxins *= correction_ratio
|
||||
|
||||
air_unsim.group_multiplier = unsimulated_tiles.len
|
||||
|
||||
air_unsim.update_values()
|
||||
return
|
||||
|
||||
//////////////
|
||||
//PROCESSING//
|
||||
//////////////
|
||||
@@ -180,20 +224,23 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
|
||||
progress = "problem with: ShareSpace()"
|
||||
|
||||
if(unsim_air_needs_update)
|
||||
unsim_air_needs_update = 0
|
||||
UpdateUnsimAvg()
|
||||
|
||||
if(unsimulated_tiles)
|
||||
if(locate(/turf/simulated) in unsimulated_tiles)
|
||||
for(var/turf/simulated/T in unsimulated_tiles)
|
||||
unsimulated_tiles -= T
|
||||
|
||||
if(unsimulated_tiles.len)
|
||||
var/old_pressure = air.return_pressure()
|
||||
var/moved_air = ShareSpace(air,unsimulated_tiles)
|
||||
var/moved_air = ShareSpace(air, air_unsim)
|
||||
|
||||
if(!air.compare(air_unsim))
|
||||
interactions_with_unsim++
|
||||
|
||||
if(moved_air > vsc.airflow_lightest_pressure)
|
||||
AirflowSpace(src)
|
||||
|
||||
if(old_pressure && (moved_air / old_pressure) > MINIMUM_AIR_RATIO_TO_SUSPEND) //Check if we've moved enough air to be considered awake.
|
||||
interactions_with_unsim++
|
||||
else
|
||||
unsimulated_tiles = null
|
||||
|
||||
@@ -310,11 +357,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
Z.interactions_with_neighbors++
|
||||
interactions_with_neighbors++
|
||||
|
||||
if(!interactions_with_neighbors && !interactions_with_unsim)
|
||||
SetStatus(ZONE_SLEEPING)
|
||||
if(!interactions_with_neighbors && !interactions_with_unsim)
|
||||
SetStatus(ZONE_SLEEPING)
|
||||
|
||||
interactions_with_neighbors = 0
|
||||
interactions_with_unsim = 0
|
||||
interactions_with_neighbors = 0
|
||||
interactions_with_unsim = 0
|
||||
|
||||
progress = "all components completed successfully, the problem is not here"
|
||||
|
||||
@@ -327,6 +374,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
else if(status == ZONE_ACTIVE && new_status == ZONE_SLEEPING)
|
||||
air_master.active_zones.Remove(src)
|
||||
status = ZONE_SLEEPING
|
||||
|
||||
if(unsimulated_tiles && unsimulated_tiles.len)
|
||||
UpdateUnsimAvg()
|
||||
air.copy_from(air_unsim)
|
||||
|
||||
if(!archived_air)
|
||||
archived_air = new
|
||||
archived_air.copy_from(air)
|
||||
@@ -342,12 +394,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
var/difference = 0
|
||||
|
||||
if(unsimulated_tiles && unsimulated_tiles.len)
|
||||
if(air.compare_unsim(unsimulated_tiles))
|
||||
UpdateUnsimAvg()
|
||||
if(!air.compare(air_unsim))
|
||||
difference = 1
|
||||
|
||||
if(!difference)
|
||||
for(var/zone/Z in connected_zones) //Check adjacent zones for air difference.
|
||||
if(air.compare(Z.air))
|
||||
if(!air.compare(Z.air))
|
||||
difference = 1
|
||||
break
|
||||
|
||||
@@ -362,11 +415,20 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
return air.merge(giver)
|
||||
|
||||
else
|
||||
if(unsimulated_tiles && unsimulated_tiles.len)
|
||||
UpdateUnsimAvg()
|
||||
var/datum/gas_mixture/compare_air = new
|
||||
compare_air.copy_from(giver)
|
||||
compare_air.add(air_unsim)
|
||||
compare_air.divide(air.group_multiplier)
|
||||
|
||||
if(air_unsim.compare(compare_air))
|
||||
return 0
|
||||
|
||||
var/result = air.merge(giver)
|
||||
|
||||
if(!archived_air.compare(air))
|
||||
SetStatus(ZONE_ACTIVE)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -443,6 +505,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
if(H)
|
||||
var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
else
|
||||
H = new G.type
|
||||
@@ -451,6 +514,15 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
for(var/datum/gas/G in B.trace_gases)
|
||||
var/datum/gas/H = locate(G.type) in A.trace_gases
|
||||
if(H)
|
||||
H = new G.type
|
||||
A.trace_gases += H
|
||||
var/G_avg = (G.moles*size) / (size+share_size)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
A.update_values()
|
||||
B.update_values()
|
||||
|
||||
@@ -459,7 +531,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
|
||||
proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
//A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room.
|
||||
if(!unsimulated_tiles || !unsimulated_tiles.len)
|
||||
if(!unsimulated_tiles)
|
||||
return 0
|
||||
|
||||
var
|
||||
@@ -472,6 +544,22 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
|
||||
size = max(1,A.group_multiplier)
|
||||
|
||||
var/tileslen
|
||||
var/share_size
|
||||
|
||||
if(istype(unsimulated_tiles, /datum/gas_mixture))
|
||||
var/datum/gas_mixture/avg_unsim = unsimulated_tiles
|
||||
unsim_oxygen = avg_unsim.oxygen
|
||||
unsim_co2 = avg_unsim.carbon_dioxide
|
||||
unsim_nitrogen = avg_unsim.nitrogen
|
||||
unsim_plasma = avg_unsim.toxins
|
||||
unsim_temperature = avg_unsim.temperature
|
||||
share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier)
|
||||
tileslen = avg_unsim.group_multiplier
|
||||
|
||||
else if(istype(unsimulated_tiles, /list))
|
||||
if(!unsimulated_tiles.len)
|
||||
return 0
|
||||
// We use the same size for the potentially single space tile
|
||||
// as we use for the entire room. Why is this?
|
||||
// Short answer: We do not want larger rooms to depressurize more
|
||||
@@ -479,20 +567,25 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
// oh-shit effect when large rooms get breached, but still having small
|
||||
// rooms remain pressurized for long enough to make escape possible.
|
||||
share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len)
|
||||
correction_ratio = share_size / unsimulated_tiles.len
|
||||
var/correction_ratio = share_size / unsimulated_tiles.len
|
||||
|
||||
for(var/turf/T in unsimulated_tiles)
|
||||
unsim_oxygen += T.oxygen
|
||||
unsim_co2 += T.carbon_dioxide
|
||||
unsim_nitrogen += T.nitrogen
|
||||
unsim_plasma += T.toxins
|
||||
unsim_temperature += T.temperature/unsimulated_tiles.len
|
||||
for(var/turf/T in unsimulated_tiles)
|
||||
unsim_oxygen += T.oxygen
|
||||
unsim_co2 += T.carbon_dioxide
|
||||
unsim_nitrogen += T.nitrogen
|
||||
unsim_plasma += T.toxins
|
||||
unsim_temperature += T.temperature/unsimulated_tiles.len
|
||||
|
||||
//These values require adjustment in order to properly represent a room of the specified size.
|
||||
unsim_oxygen *= correction_ratio
|
||||
unsim_co2 *= correction_ratio
|
||||
unsim_nitrogen *= correction_ratio
|
||||
unsim_plasma *= correction_ratio
|
||||
tileslen = unsimulated_tiles.len
|
||||
|
||||
else //invalid input type
|
||||
return 0
|
||||
|
||||
//These values require adjustment in order to properly represent a room of the specified size.
|
||||
unsim_oxygen *= correction_ratio
|
||||
unsim_co2 *= correction_ratio
|
||||
unsim_nitrogen *= correction_ratio
|
||||
unsim_plasma *= correction_ratio
|
||||
unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma)
|
||||
|
||||
var
|
||||
@@ -517,8 +610,8 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
if((full_heat_capacity + unsim_heat_capacity) > 0)
|
||||
temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity)
|
||||
|
||||
if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
||||
ratio = sharing_lookup_table[unsimulated_tiles.len]
|
||||
if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
||||
ratio = sharing_lookup_table[tileslen]
|
||||
|
||||
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg )
|
||||
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )
|
||||
|
||||
Reference in New Issue
Block a user