Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atmospheres Refactor #3878

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions _maps/RandomRuins/IceRuins/icemoon_hydroponics_lab.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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{
Expand Down
72 changes: 37 additions & 35 deletions code/datums/atmosphere/_atmosphere.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,44 @@
generate_gas_string()

/datum/atmosphere/proc/generate_gas_string()
// Pure randomization
var/target_pressure = rand(minimum_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

// 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)
// 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()
// 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]
gas_weights[gas] = to_add
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

for(var/gas in restricted_gases)
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(";")
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)
// CEIL will make it inaccurate, but prettier
var/real_weight = CEILING(gas_weights[gas] / sum * total_moles, 0.1)
string_builder += "[gas]=[real_weight]"
string_builder += "TEMP=[temperature]"

gas_string = string_builder.Join(";")
2 changes: 1 addition & 1 deletion code/datums/atmosphere/planetary.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion code/game/turfs/closed/minerals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion code/game/turfs/open/_open.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 0 additions & 3 deletions code/game/turfs/open/floor/fancy_floor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@
to_chat(user, "<span class='notice'>You forcefully pry off the planks, destroying them in the process.</span>")
return make_plating()

/turf/open/floor/wood/cold
initial_temperature = 255.37

/turf/open/floor/wood/airless
initial_gas_mix = AIRLESS_ATMOS

Expand Down
3 changes: 0 additions & 3 deletions code/game/turfs/open/floor/hull.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
13 changes: 1 addition & 12 deletions code/game/turfs/open/floor/plating/misc_plating.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -172,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
Expand Down Expand Up @@ -208,7 +204,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
Expand All @@ -228,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

Expand Down
1 change: 0 additions & 1 deletion code/game/turfs/open/space/space.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
name = "\proper space"
intact = 0

initial_temperature = TCMB
thermal_conductivity = 0
heat_capacity = 700000
initial_gas_mix = AIRLESS_ATMOS
Expand Down
3 changes: 0 additions & 3 deletions code/game/turfs/turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion code/modules/atmospherics/gasmixtures/gas_mixture.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 5 additions & 4 deletions code/modules/atmospherics/gasmixtures/reactions.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
1 change: 0 additions & 1 deletion code/modules/awaymissions/mission_code/snowdin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions code/modules/unit_tests/_unit_tests.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
99 changes: 99 additions & 0 deletions code/modules/unit_tests/atmospheres.dm
Original file line number Diff line number Diff line change
@@ -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 .
Loading