Merge pull request #15011 from Putnam3145/lavaland-random-atmos

Port of randomized planet atmos
This commit is contained in:
silicons
2021-08-26 21:39:23 -07:00
committed by GitHub
8 changed files with 166 additions and 8 deletions

View File

@@ -155,10 +155,10 @@
//LAVALAND
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300"
#define LAVALAND_DEFAULT_ATMOS "LAVALAND_ATMOS"
//SNOSTATION
#define ICEMOON_DEFAULT_ATMOS "o2=17;n2=63;TEMP=180"
#define ICEMOON_DEFAULT_ATMOS "ICEMOON_ATMOS"
//ATMOSIA GAS MONITOR TAGS
#define ATMOS_GAS_MONITOR_INPUT_O2 "o2_in"

View File

@@ -37,7 +37,8 @@ SUBSYSTEM_DEF(air)
//atmos singletons
var/list/gas_reactions = list()
var/list/atmos_gen
var/list/planetary = list() //auxmos already caches static planetary mixes but could be convenient to do so here too
//Special functions lists
var/list/turf/open/high_pressure_delta = list()
@@ -475,6 +476,20 @@ SUBSYSTEM_DEF(air)
return pipe_init_dirs_cache[type]["[dir]"]
/datum/controller/subsystem/air/proc/generate_atmos()
atmos_gen = list()
for(var/T in subtypesof(/datum/atmosphere))
var/datum/atmosphere/atmostype = T
atmos_gen[initial(atmostype.id)] = new atmostype
/datum/controller/subsystem/air/proc/preprocess_gas_string(gas_string)
if(!atmos_gen)
generate_atmos()
if(!atmos_gen[gas_string])
return gas_string
var/datum/atmosphere/mix = atmos_gen[gas_string]
return mix.gas_string
#undef SSAIR_PIPENETS
#undef SSAIR_ATMOSMACHINERY
#undef SSAIR_EXCITEDGROUPS

View File

@@ -0,0 +1,60 @@
/datum/atmosphere
var/gas_string
var/id
var/list/base_gases // A list of gases to always have
var/list/normal_gases // A list of allowed gases:base_amount
var/list/restricted_gases // A list of allowed gases like normal_gases but each can only be selected a maximum of one time
var/restricted_chance = 10 // Chance per iteration to take from restricted gases
var/minimum_pressure
var/maximum_pressure
var/minimum_temp
var/maximum_temp
/datum/atmosphere/New()
generate_gas_string()
/datum/atmosphere/proc/generate_gas_string()
var/list/spicy_gas = restricted_gases.Copy()
var/target_pressure = rand(minimum_pressure, maximum_pressure)
var/pressure_scale = 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/gastype
var/amount
while(gasmix.return_pressure() < target_pressure)
if(!prob(restricted_chance) || !length(spicy_gas))
gastype = pick(normal_gases)
amount = normal_gases[gastype]
else
gastype = pick(spicy_gas)
amount = spicy_gas[gastype]
spicy_gas -= gastype //You can only pick each restricted gas once
amount *= rand(50, 200) / 100 // Randomly modifes the amount from half to double the base for some variety
amount *= pressure_scale // 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.adjust_moles(gastype, amount)
// That last one put us over the limit, remove some of it
if(gasmix.return_pressure() > target_pressure)
var/moles_to_remove = (1 - target_pressure / gasmix.return_pressure()) * gasmix.total_moles()
gasmix.adjust_moles(gastype, -moles_to_remove)
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/id in gasmix.get_gases())
gas_string_builder += "[id]=[gasmix.get_moles(id)]"
gas_string_builder += "TEMP=[gasmix.return_temperature()]"
gas_string = gas_string_builder.Join(";")

View File

@@ -0,0 +1,52 @@
// Atmos types used for planetary airs
/datum/atmosphere/lavaland
id = LAVALAND_DEFAULT_ATMOS
base_gases = list(
GAS_O2=5,
GAS_N2=10,
)
normal_gases = list(
GAS_O2=10,
GAS_N2=10,
GAS_CO2=10,
)
restricted_gases = list(
GAS_PLASMA=0.1,
GAS_BZ=1.2,
GAS_METHANE=1.0,
GAS_METHYL_BROMIDE=0.1,
)
restricted_chance = 30
minimum_pressure = HAZARD_LOW_PRESSURE + 10
maximum_pressure = LAVALAND_EQUIPMENT_EFFECT_PRESSURE - 1
minimum_temp = BODYTEMP_COLD_DAMAGE_LIMIT + 1
maximum_temp = 350
/datum/atmosphere/icemoon
id = ICEMOON_DEFAULT_ATMOS
base_gases = list(
GAS_O2=5,
GAS_N2=10,
)
normal_gases = list(
GAS_O2=10,
GAS_N2=10,
GAS_CO2=10,
)
restricted_gases = list(
GAS_PLASMA=0.1,
GAS_METHANE=1.0,
GAS_METHYL_BROMIDE=0.1,
)
restricted_chance = 10
minimum_pressure = HAZARD_LOW_PRESSURE + 10
maximum_pressure = LAVALAND_EQUIPMENT_EFFECT_PRESSURE - 1
minimum_temp = 180
maximum_temp = 180

View File

@@ -32,6 +32,11 @@
if(!blocks_air)
air = new(2500,src)
air.copy_from_turf(src)
if(planetary_atmos && !(initial_gas_mix in SSair.planetary))
var/datum/gas_mixture/mix = new
mix.parse_gas_string(initial_gas_mix)
mix.mark_immutable()
SSair.planetary[initial_gas_mix] = mix
update_air_ref(planetary_atmos ? 1 : 2)
. = ..()

View File

@@ -261,6 +261,8 @@ we use a hook instead
return 1
/datum/gas_mixture/parse_gas_string(gas_string)
gas_string = SSair.preprocess_gas_string(gas_string)
var/list/gas = params2list(gas_string)
if(gas["TEMP"])
var/temp = text2num(gas["TEMP"])

View File

@@ -54,7 +54,8 @@
var/SA_para_min = 1 //nitrous values
var/SA_sleep_min = 5
var/BZ_trip_balls_min = 1 //BZ gas
var/BZ_trip_balls_min = 0.1 //BZ gas
var/BZ_brain_damage_min = 1
var/gas_stimulation_min = 0.002 //Nitryl and Stimulum
var/cold_message = "your face freezing and an icicle forming"
@@ -269,13 +270,13 @@
// BZ
var/bz_pp = PP(breath, GAS_BZ)
if(bz_pp > BZ_trip_balls_min)
if(bz_pp > BZ_brain_damage_min)
H.hallucination += 10
H.reagents.add_reagent(/datum/reagent/bz_metabolites,5)
if(prob(33))
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
else if(bz_pp > 0.01)
else if(bz_pp > BZ_trip_balls_min)
H.hallucination += 5
H.reagents.add_reagent(/datum/reagent/bz_metabolites,1)
@@ -476,7 +477,7 @@
)
SA_para_min = 30
SA_sleep_min = 50
BZ_trip_balls_min = 30
BZ_brain_damage_min = 30
emp_vulnerability = 3
cold_level_1_threshold = 200
@@ -509,8 +510,29 @@
heat_level_2_threshold = 600 // up 200 from level 1, 1000 is silly but w/e for level 3
/obj/item/organ/lungs/ashwalker/populate_gas_info()
// humans usually breathe 21 but require 16/17, so 80% - 1, which is more lenient but it's fine
#define SAFE_THRESHOLD_RATIO 0.8
var/datum/gas_mixture/breath = SSair.planetary[LAVALAND_DEFAULT_ATMOS] // y'all know
var/pressure = breath.return_pressure()
var/total_moles = breath.total_moles()
for(var/id in breath.get_gases())
var/this_pressure = PP(breath, id)
var/req_pressure = (this_pressure * SAFE_THRESHOLD_RATIO) - 1
if(req_pressure > 0)
gas_min[id] = req_pressure
if(id in gas_max)
gas_max[id] += this_pressure
var/bz = breath.get_moles(GAS_BZ)
if(bz)
BZ_trip_balls_min += bz
BZ_brain_damage_min += bz
gas_max[GAS_N2] = PP(breath, GAS_N2) + 5
var/o2_pp = PP(breath, GAS_O2)
safe_breath_min = 0.3 * o2_pp
safe_breath_max = 1.3 * o2_pp
..()
gas_max[GAS_N2] = 28
#undef SAFE_THRESHOLD_RATIO
/obj/item/organ/lungs/slime
name = "vacuole"