From bfb625fe0a973298adfe3171a97072439b05d52f Mon Sep 17 00:00:00 2001 From: Mark Suckerberg Date: Tue, 3 Dec 2024 17:15:45 -0600 Subject: [PATCH 1/4] attempt 1 --- code/datums/atmosphere/_atmosphere.dm | 32 +++++++++++++++++++ code/game/turfs/change_turf.dm | 2 ++ code/game/turfs/closed/minerals.dm | 1 - code/game/turfs/open/_open.dm | 2 +- code/game/turfs/open/floor/fancy_floor.dm | 2 +- code/game/turfs/open/floor/hull.dm | 3 -- .../turfs/open/floor/plating/misc_plating.dm | 10 +++--- code/game/turfs/open/space/space.dm | 1 - code/game/turfs/turf.dm | 3 -- .../environmental/LINDA_turf_tile.dm | 6 ---- .../atmospherics/gasmixtures/gas_mixture.dm | 2 +- .../awaymissions/mission_code/snowdin.dm | 1 - 12 files changed, 41 insertions(+), 24 deletions(-) diff --git a/code/datums/atmosphere/_atmosphere.dm b/code/datums/atmosphere/_atmosphere.dm index 0652ef5560f6..35c71e713884 100644 --- a/code/datums/atmosphere/_atmosphere.dm +++ b/code/datums/atmosphere/_atmosphere.dm @@ -19,6 +19,38 @@ /datum/atmosphere/proc/generate_gas_string() var/target_pressure = rand(minimum_pressure, maximum_pressure) var/pressure_scalar = target_pressure / maximum_pressure + var/temperature = rand(minimum_temp, maximum_temp) + + var/total_moles = target_pressure * CELL_VOLUME / (temperature * R_IDEAL_GAS_EQUATION) + + var/list/gas_weights = list() + var/sum + + for(var/gas in base_gases) + var/to_add = base_gases[gas] + gas_weights[gas] = to_add + sum += to_add + + for(var/gas in normal_gases) + var/to_add = normal_gases[gas] * rand(50, 200) / 100 * pressure_scalar + gas_weights[gas] += to_add + sum += to_add + + for(var/gas in restricted_gases) + if(!prob(restricted_chance)) + continue + var/to_add = restricted_gases[gas] * rand(50, 200) / 100 * pressure_scalar + gas_weights[gas] += to_add + sum += to_add + + var/list/string_builder = list() + for(var/gas in gas_weights) + var/real_weight = CEILING(gas_weights[gas] / sum * total_moles, 0.1) + string_builder += "[GLOB.gas_data.ids[gas]]=[real_weight]" + string_builder += "TEMP=[temperature]" + + gas_string = string_builder.Join(";") + return // First let's set up the gasmix and base gases for this template // We make the string from a gasmix in this proc because gases need to calculate their pressure diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index b7daf1547355..cae45d96dccc 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -335,6 +335,8 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( var/turf_count = LAZYLEN(atmos_adjacent_turfs) if(blocks_air || !turf_count) //if there weren't any open turfs, no need to update. return + if(!air) + Initalize_Atmos(0) var/datum/gas_mixture/total = new//Holders to assimilate air from nearby turfs diff --git a/code/game/turfs/closed/minerals.dm b/code/game/turfs/closed/minerals.dm index 1d6020490840..fdd12d7c9dfa 100644 --- a/code/game/turfs/closed/minerals.dm +++ b/code/game/turfs/closed/minerals.dm @@ -15,7 +15,6 @@ opacity = TRUE density = TRUE layer = EDGED_TURF_LAYER - initial_temperature = TCMB base_icon_state = "smoothrocks" var/smooth_icon = 'icons/turf/walls/smoothrocks.dmi' var/environment_type = "asteroid" diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index e2c6caa8be7e..571d824f2d5f 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -155,7 +155,7 @@ baseturfs = /turf/open/indestructible/airblock /turf/open/Initalize_Atmos(times_fired) - if(!istype(air, /datum/gas_mixture)) + if(!air) air = new(2500, src) air.copy_from_turf(src) update_air_ref(planetary_atmos ? AIR_REF_PLANETARY_TURF : AIR_REF_OPEN_TURF) diff --git a/code/game/turfs/open/floor/fancy_floor.dm b/code/game/turfs/open/floor/fancy_floor.dm index 2d043371a9bb..f1b4ce8002e2 100644 --- a/code/game/turfs/open/floor/fancy_floor.dm +++ b/code/game/turfs/open/floor/fancy_floor.dm @@ -85,7 +85,7 @@ return make_plating() /turf/open/floor/wood/cold - initial_temperature = 255.37 + //initial_temperature = 255.37 /turf/open/floor/wood/airless initial_gas_mix = AIRLESS_ATMOS diff --git a/code/game/turfs/open/floor/hull.dm b/code/game/turfs/open/floor/hull.dm index 67be2d8436f5..d50d9b5cecce 100644 --- a/code/game/turfs/open/floor/hull.dm +++ b/code/game/turfs/open/floor/hull.dm @@ -4,7 +4,6 @@ desc = "Sturdy exterior hull plating that separates you from the uncaring vacuum of space." icon_state = "regular_hull" initial_gas_mix = AIRLESS_ATMOS - initial_temperature = TCMB /turf/open/floor/engine/hull/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) //no rcd destroying this flooring if(passed_mode == RCD_DECONSTRUCT) @@ -21,9 +20,7 @@ /turf/open/floor/engine/hull/interior name = "interior hull plating" initial_gas_mix = OPENTURF_DEFAULT_ATMOS - initial_temperature = T20C /turf/open/floor/engine/hull/reinforced/interior name = "interior reinforced hull plating" initial_gas_mix = OPENTURF_DEFAULT_ATMOS - initial_temperature = T20C diff --git a/code/game/turfs/open/floor/plating/misc_plating.dm b/code/game/turfs/open/floor/plating/misc_plating.dm index 684420c8eb89..44f92deebb55 100644 --- a/code/game/turfs/open/floor/plating/misc_plating.dm +++ b/code/game/turfs/open/floor/plating/misc_plating.dm @@ -141,7 +141,6 @@ icon = 'icons/turf/snow.dmi' icon_state = "ice" initial_gas_mix = FROZEN_ATMOS - initial_temperature = 180 planetary_atmos = TRUE baseturfs = /turf/open/floor/plating/ice slowdown = 1 @@ -173,10 +172,10 @@ light_color = LIGHT_COLOR_LIGHT_CYAN /turf/open/floor/plating/ice/colder - initial_temperature = 140 + //initial_temperature = 140 /turf/open/floor/plating/ice/temperate - initial_temperature = 255.37 + //initial_temperature = 255.37 /turf/open/floor/plating/ice/break_tile() return @@ -208,7 +207,6 @@ icon = 'icons/turf/snow.dmi' icon_state = "snowplating" initial_gas_mix = FROZEN_ATMOS - initial_temperature = 180 attachment_holes = FALSE planetary_atmos = TRUE footstep = FOOTSTEP_SAND @@ -229,10 +227,10 @@ planetary_atmos = TRUE /turf/open/floor/plating/snowed/colder - initial_temperature = 140 + //initial_temperature = 140 /turf/open/floor/plating/snowed/temperatre - initial_temperature = 255.37 + //initial_temperature = 255.37 /turf/open/floor/plating/snowed/smoothed/icemoon initial_gas_mix = ICEMOON_DEFAULT_ATMOS diff --git a/code/game/turfs/open/space/space.dm b/code/game/turfs/open/space/space.dm index 0784f2a140a7..7f007e64873c 100644 --- a/code/game/turfs/open/space/space.dm +++ b/code/game/turfs/open/space/space.dm @@ -7,7 +7,6 @@ name = "\proper space" intact = 0 - initial_temperature = TCMB thermal_conductivity = 0 heat_capacity = 700000 initial_gas_mix = AIRLESS_ATMOS diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 4da6e25703bb..84784d26e943 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -15,9 +15,6 @@ GLOBAL_LIST_EMPTY(created_baseturf_lists) // This shouldn't be modified directly; use the helper procs, as many baseturf lists are shared between turfs. var/list/baseturfs = /turf/baseturf_bottom - /// How hot the turf is, in kelvin - var/initial_temperature = T20C - /// Used for fire, if a melting temperature was reached, it will be destroyed var/to_be_destroyed = 0 var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index d5c0a9fead1d..ad8f348396d2 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -27,12 +27,6 @@ var/list/atmos_overlay_types //gas IDs of current active gas overlays -/turf/open/Initialize(mapload, inherited_virtual_z) - air = new(2500,src) - air.copy_from_turf(src) - update_air_ref(planetary_atmos ? AIR_REF_PLANETARY_TURF : AIR_REF_OPEN_TURF) - return ..() - /turf/open/Destroy() if(active_hotspot) QDEL_NULL(active_hotspot) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 1aff4ddadb7f..29fb801869f0 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -187,7 +187,7 @@ GLOBAL_LIST_INIT(auxtools_atmos_initialized, FALSE) return copy /datum/gas_mixture/copy_from_turf(turf/model) - set_temperature(initial(model.initial_temperature)) + //set_temperature(initial(model.initial_temperature)) parse_gas_string(model.initial_gas_mix) return 1 diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index c205746b16f3..d3360c9a5dd9 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -3,7 +3,6 @@ /turf/open/floor/plasteel/dark/snowdin initial_gas_mix = FROZEN_ATMOS planetary_atmos = 1 - initial_temperature = 180 /turf/open/lava/plasma name = "liquid plasma" From e895774536ea995c9040278090041f0640ec299d Mon Sep 17 00:00:00 2001 From: Mark Suckerberg Date: Wed, 4 Dec 2024 00:10:53 -0600 Subject: [PATCH 2/4] kills initial_temperature --- .../IceRuins/icemoon_hydroponics_lab.dmm | 8 +--- code/datums/atmosphere/_atmosphere.dm | 38 ------------------- code/game/turfs/open/floor/fancy_floor.dm | 3 -- .../turfs/open/floor/plating/misc_plating.dm | 11 +----- .../atmospherics/gasmixtures/gas_mixture.dm | 1 - 5 files changed, 3 insertions(+), 58 deletions(-) diff --git a/_maps/RandomRuins/IceRuins/icemoon_hydroponics_lab.dmm b/_maps/RandomRuins/IceRuins/icemoon_hydroponics_lab.dmm index 67613238e83d..0a5f67672fb1 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_hydroponics_lab.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_hydroponics_lab.dmm @@ -281,9 +281,7 @@ /turf/open/floor/plasteel/tech, /area/ruin/powered/hydroponicslab) "gA" = ( -/turf/open/floor/plating/snowed/temperatre{ - initial_gas_mix = "ICEMOON_ATMOS" - }, +/turf/open/floor/plating/snowed, /area/overmap_encounter/planetoid/cave/explored) "gC" = ( /obj/structure/table, @@ -2173,9 +2171,7 @@ /area/ruin/powered/hydroponicslab) "Wi" = ( /obj/structure/marker_beacon, -/turf/open/floor/plating/snowed/temperatre{ - initial_gas_mix = "ICEMOON_ATMOS" - }, +/turf/open/floor/plating/snowed, /area/overmap_encounter/planetoid/cave/explored) "WK" = ( /obj/item/stack/cable_coil/yellow{ diff --git a/code/datums/atmosphere/_atmosphere.dm b/code/datums/atmosphere/_atmosphere.dm index 35c71e713884..6d4b8bdcc7f6 100644 --- a/code/datums/atmosphere/_atmosphere.dm +++ b/code/datums/atmosphere/_atmosphere.dm @@ -50,41 +50,3 @@ string_builder += "TEMP=[temperature]" gas_string = string_builder.Join(";") - return - - // First let's set up the gasmix and base gases for this template - // We make the string from a gasmix in this proc because gases need to calculate their pressure - var/datum/gas_mixture/gasmix = new - gasmix.set_temperature(rand(minimum_temp, maximum_temp)) - for(var/i in base_gases) - gasmix.set_moles(i, base_gases[i]) - - // Now let the random choices begin - var/datum/gas/gastype - var/amount - while(gasmix.return_pressure() < target_pressure) - if(!prob(restricted_chance)) - gastype = pick(normal_gases) - amount = normal_gases[gastype] - else - gastype = pick(restricted_gases) - amount = restricted_gases[gastype] - if(gasmix.get_moles(gastype)) - continue - - amount *= rand(50, 200) / 100 // Randomly modifes the amount from half to double the base for some variety - amount *= pressure_scalar // If we pick a really small target pressure we want roughly the same mix but less of it all - amount = CEILING(amount, 0.1) - - gasmix.set_moles(gastype, gasmix.get_moles(gastype) + amount) - - // That last one put us over the limit, remove some of it - while(gasmix.return_pressure() > target_pressure) - gasmix.set_moles(gastype, gasmix.get_moles(gastype) - (gasmix.get_moles(gastype) * 0.1)) - gasmix.set_moles(gastype, FLOOR(gasmix.get_moles(gastype), 0.1)) - // Now finally lets make that string - var/list/gas_string_builder = list() - for(var/i in gasmix.get_gases()) - gas_string_builder += "[GLOB.gas_data.ids[i]]=[gasmix.get_moles(i)]" - gas_string_builder += "TEMP=[gasmix.return_temperature()]" - gas_string = gas_string_builder.Join(";") diff --git a/code/game/turfs/open/floor/fancy_floor.dm b/code/game/turfs/open/floor/fancy_floor.dm index f1b4ce8002e2..ffc233b755f1 100644 --- a/code/game/turfs/open/floor/fancy_floor.dm +++ b/code/game/turfs/open/floor/fancy_floor.dm @@ -84,9 +84,6 @@ to_chat(user, "You forcefully pry off the planks, destroying them in the process.") return make_plating() -/turf/open/floor/wood/cold - //initial_temperature = 255.37 - /turf/open/floor/wood/airless initial_gas_mix = AIRLESS_ATMOS diff --git a/code/game/turfs/open/floor/plating/misc_plating.dm b/code/game/turfs/open/floor/plating/misc_plating.dm index 44f92deebb55..d5087dc5f6f3 100644 --- a/code/game/turfs/open/floor/plating/misc_plating.dm +++ b/code/game/turfs/open/floor/plating/misc_plating.dm @@ -171,11 +171,8 @@ light_power = 1 light_color = LIGHT_COLOR_LIGHT_CYAN -/turf/open/floor/plating/ice/colder - //initial_temperature = 140 - /turf/open/floor/plating/ice/temperate - //initial_temperature = 255.37 + initial_gas_mix = OPENTURF_DEFAULT_ATMOS /turf/open/floor/plating/ice/break_tile() return @@ -226,12 +223,6 @@ canSmoothWith = list(SMOOTH_GROUP_FLOOR_SNOWED) planetary_atmos = TRUE -/turf/open/floor/plating/snowed/colder - //initial_temperature = 140 - -/turf/open/floor/plating/snowed/temperatre - //initial_temperature = 255.37 - /turf/open/floor/plating/snowed/smoothed/icemoon initial_gas_mix = ICEMOON_DEFAULT_ATMOS diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 29fb801869f0..928013601a10 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -187,7 +187,6 @@ GLOBAL_LIST_INIT(auxtools_atmos_initialized, FALSE) return copy /datum/gas_mixture/copy_from_turf(turf/model) - //set_temperature(initial(model.initial_temperature)) parse_gas_string(model.initial_gas_mix) return 1 From 8f9b7a914c6395a572b7f563693044c9faa86b76 Mon Sep 17 00:00:00 2001 From: Mark Suckerberg Date: Wed, 4 Dec 2024 02:16:45 -0600 Subject: [PATCH 3/4] let's just readd these for now --- code/game/turfs/change_turf.dm | 2 -- code/modules/atmospherics/environmental/LINDA_turf_tile.dm | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index cae45d96dccc..b7daf1547355 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -335,8 +335,6 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( var/turf_count = LAZYLEN(atmos_adjacent_turfs) if(blocks_air || !turf_count) //if there weren't any open turfs, no need to update. return - if(!air) - Initalize_Atmos(0) var/datum/gas_mixture/total = new//Holders to assimilate air from nearby turfs diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index ad8f348396d2..d5c0a9fead1d 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -27,6 +27,12 @@ var/list/atmos_overlay_types //gas IDs of current active gas overlays +/turf/open/Initialize(mapload, inherited_virtual_z) + air = new(2500,src) + air.copy_from_turf(src) + update_air_ref(planetary_atmos ? AIR_REF_PLANETARY_TURF : AIR_REF_OPEN_TURF) + return ..() + /turf/open/Destroy() if(active_hotspot) QDEL_NULL(active_hotspot) From 6589a762ac0d37da579aa253ff2f2134747b072f Mon Sep 17 00:00:00 2001 From: Mark Suckerberg Date: Sun, 8 Dec 2024 00:23:57 -0600 Subject: [PATCH 4/4] Atmospheres unit test --- code/datums/atmosphere/_atmosphere.dm | 14 ++- code/datums/atmosphere/planetary.dm | 2 +- .../atmospherics/gasmixtures/reactions.dm | 9 +- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/atmospheres.dm | 99 +++++++++++++++++++ 5 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 code/modules/unit_tests/atmospheres.dm diff --git a/code/datums/atmosphere/_atmosphere.dm b/code/datums/atmosphere/_atmosphere.dm index 6d4b8bdcc7f6..f3b7fddf60e9 100644 --- a/code/datums/atmosphere/_atmosphere.dm +++ b/code/datums/atmosphere/_atmosphere.dm @@ -17,14 +17,20 @@ generate_gas_string() /datum/atmosphere/proc/generate_gas_string() + // Pure randomization var/target_pressure = rand(minimum_pressure, maximum_pressure) - var/pressure_scalar = target_pressure / maximum_pressure var/temperature = rand(minimum_temp, maximum_temp) + // This was used in the old method to keep ratios of gases "correct" even at different pressures. I'm not touching it + var/pressure_scalar = target_pressure / maximum_pressure + + // Get the total moles of gas in each turf, and then distribute the gases based on their weights var/total_moles = target_pressure * CELL_VOLUME / (temperature * R_IDEAL_GAS_EQUATION) + // The weight of each potential gas var/list/gas_weights = list() - var/sum + // The sum of all the weights, used to normalize them + var/sum = 0 for(var/gas in base_gases) var/to_add = base_gases[gas] @@ -32,6 +38,7 @@ sum += to_add for(var/gas in normal_gases) + // 0.5 to 2x the base amount var/to_add = normal_gases[gas] * rand(50, 200) / 100 * pressure_scalar gas_weights[gas] += to_add sum += to_add @@ -45,8 +52,9 @@ var/list/string_builder = list() for(var/gas in gas_weights) + // CEIL will make it inaccurate, but prettier var/real_weight = CEILING(gas_weights[gas] / sum * total_moles, 0.1) - string_builder += "[GLOB.gas_data.ids[gas]]=[real_weight]" + string_builder += "[gas]=[real_weight]" string_builder += "TEMP=[temperature]" gas_string = string_builder.Join(";") diff --git a/code/datums/atmosphere/planetary.dm b/code/datums/atmosphere/planetary.dm index 8a2d37ab2471..0b3a4776160f 100644 --- a/code/datums/atmosphere/planetary.dm +++ b/code/datums/atmosphere/planetary.dm @@ -186,7 +186,7 @@ ) normal_gases = list( GAS_O2=5, - GAS_H2O=7, + GAS_H2=7, GAS_N2=5, GAS_NITROUS=7, GAS_CO2=5, diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 10c4e9e417d0..d80be269eb00 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -292,7 +292,9 @@ /datum/gas_reaction/freonfire/init_reqs() min_requirements = list( GAS_O2 = MINIMUM_MOLE_COUNT, - GAS_FREON = MINIMUM_MOLE_COUNT + GAS_FREON = MINIMUM_MOLE_COUNT, + "TEMP" = FREON_LOWER_TEMPERATURE, + "MAX_TEMP" = FREON_MAXIMUM_BURN_TEMPERATURE ) /datum/gas_reaction/freonfire/react(datum/gas_mixture/air, datum/holder) @@ -533,7 +535,8 @@ GAS_O2 = 10, GAS_N2 = 20, GAS_BZ = 5, - "TEMP" = 200 + "TEMP" = 200, + "MAX_TEMP" = 250 ) /datum/gas_reaction/nitrousformation/react(datum/gas_mixture/air) @@ -543,8 +546,6 @@ var/energy_used = heat_efficency * NITROUS_FORMATION_ENERGY if ((air.get_moles(GAS_O2) - heat_efficency < 0)|| (air.get_moles(GAS_N2) - heat_efficency < 0)) //Shouldn't produce gas from nothing. return NO_REACTION - if (temperature > 250) //maximum allowed temperature for the reaction - return NO_REACTION air.adjust_moles(GAS_O2, -heat_efficency) air.adjust_moles(GAS_N2, -heat_efficency * 2) air.adjust_moles(GAS_NITROUS, heat_efficency) diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 3195d86e7fb7..7f49c7a39510 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -76,6 +76,7 @@ #include "icons/spritesheets.dm" #include "icons/worn_icons.dm" #include "anchored_mobs.dm" +#include "atmospheres.dm" #include "autowiki.dm" #include "bespoke_id.dm" #include "binary_insert.dm" diff --git a/code/modules/unit_tests/atmospheres.dm b/code/modules/unit_tests/atmospheres.dm new file mode 100644 index 000000000000..8c3febe737c5 --- /dev/null +++ b/code/modules/unit_tests/atmospheres.dm @@ -0,0 +1,99 @@ +/datum/unit_test/atmospheres + focus = TRUE + +/datum/unit_test/atmospheres/Run() + for(var/id in SSair.string_mixes) + var/datum/atmosphere/mix = SSair.string_mixes[id] + compare(mix) + +/datum/unit_test/atmospheres/proc/compare(datum/atmosphere/mix) + var/max_moles = mix.maximum_pressure * CELL_VOLUME / (mix.minimum_temp * R_IDEAL_GAS_EQUATION) + var/lowest_sum = get_min_sum(mix) + var/list/max_possible = list() + + for(var/gas_id in mix.base_gases) + var/value = mix.base_gases[gas_id] + + max_possible[gas_id] = value / (lowest_sum - value) * max_moles + + for(var/gas_id in mix.normal_gases) + var/value = mix.normal_gases[gas_id] + + max_possible[gas_id] = value * 2 / (lowest_sum - value * 2) * max_moles + + for(var/gas_id in mix.restricted_gases) + var/value = mix.restricted_gases[gas_id] * 2 + + max_possible[gas_id] += value / lowest_sum * max_moles + + for(var/datum/gas_reaction/reaction as anything in SSair.gas_reactions) + var/min_temp = reaction.min_requirements["TEMP"] || 0 + var/max_temp = reaction.min_requirements["MAX_TEMP"] || INFINITY + + if(max_temp < mix.minimum_temp) + continue + if(min_temp > mix.maximum_temp) + continue + + var/fire_reagents = reaction.min_requirements["FIRE_REAGENTS"] + if(fire_reagents) + var/oxidizer + var/fuel + + for(var/gas_id in max_possible) + var/datum/gas/gas = GLOB.gas_data.datums[gas_id] + if(gas.oxidation_rate > 0 && gas.oxidation_temperature && gas.oxidation_temperature < mix.maximum_temp && max_possible[gas_id] > fire_reagents) + oxidizer = gas + if(gas.fire_temperature && gas.fire_temperature < mix.maximum_temp) + fuel = gas + + if(!oxidizer || !fuel) + continue + + var/list/reqs = reaction.min_requirements - list("TEMP", "MAX_TEMP", "ENER", "FIRE_REAGENTS") + + //See if the reaction can be done in the worst case scenario mix + var/real_max_temp = max_temp + var/remaining_moles = max_moles + if(real_max_temp > mix.maximum_temp) + real_max_temp = mix.maximum_temp + remaining_moles = mix.maximum_pressure * CELL_VOLUME / (real_max_temp * R_IDEAL_GAS_EQUATION) + + var/reacted = TRUE + + var/gas_str = "TEMP=[real_max_temp];" + for(var/gas_id as anything in reqs) + if(!(gas_id in max_possible)) + reacted = FALSE + break + if(reqs[gas_id] > max_possible[gas_id]) + reacted = FALSE + break + if(reqs[gas_id] > remaining_moles) + reacted = FALSE + break + + remaining_moles -= reqs[gas_id] + gas_str += "[gas_id]=[reqs[gas_id]];" + + if(!reacted) + continue + + var/datum/gas_mixture/remaining = new /datum/gas_mixture + remaining.parse_gas_string(gas_str) + + if(reaction.react(remaining, src.run_loc_bottom_left) != NO_REACTION) + TEST_FAIL("Reaction \"[reaction]\" could happen in [mix]") + else + TEST_NOTICE(src, "Reaction \"[reaction]\"- could get constantly called in [mix]") + + +/datum/unit_test/atmospheres/proc/get_min_sum(datum/atmosphere/mix) + . = 0 + + for(var/gas_id in mix.base_gases) + . += mix.base_gases[gas_id] + for(var/gas_id in mix.normal_gases) + . += mix.normal_gases[gas_id] * 0.5 + + return .