From eda6a4d2e2cd9b8ec85cf419e1c68bc09d6e385b Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 11 Jun 2021 05:23:24 -0700 Subject: [PATCH] Aaaa --- code/__DEFINES/atmospherics.dm | 4 +- code/__DEFINES/maths.dm | 11 +- code/__DEFINES/mobs.dm | 4 +- .../atmospherics/auxgm/breathing_classes.dm | 37 ++ code/modules/atmospherics/auxgm/gas_types.dm | 170 +++++++++ .../modules/atmospherics/gasmixtures/auxgm.dm | 124 +++++++ .../atmospherics/gasmixtures/gas_mixture.dm | 11 - .../atmospherics/gasmixtures/gas_types.dm | 227 ------------ .../atmospherics/gasmixtures/reactions.dm | 52 ++- code/modules/mob/living/carbon/life.dm | 10 +- code/modules/surgery/organs/lungs.dm | 343 ++++++------------ tgstation.dme | 4 +- 12 files changed, 517 insertions(+), 480 deletions(-) create mode 100644 code/modules/atmospherics/auxgm/breathing_classes.dm create mode 100644 code/modules/atmospherics/auxgm/gas_types.dm create mode 100644 code/modules/atmospherics/gasmixtures/auxgm.dm delete mode 100644 code/modules/atmospherics/gasmixtures/gas_types.dm diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 7514715bc4..b2566278a6 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -265,7 +265,9 @@ #define GAS_METHANE "methane" #define GAS_METHYL_BROMIDE "methyl_bromide" -#define GAS_FLAG_DANGEROUS (1<<0) +#define GAS_FLAG_DANGEROUS (1<<0) +#define GAS_FLAG_BREATH_PROC (1<<1) + //HELPERS #define PIPING_LAYER_SHIFT(T, PipingLayer) \ if(T.dir & (NORTH|SOUTH)) { \ diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index 4c9c195def..9e96c6a559 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -212,12 +212,17 @@ /// Like DT_PROB_RATE but easier to use, simply put `if(DT_PROB(10, 5))` #define DT_PROB(prob_per_second_percent, delta_time) (prob(100*DT_PROB_RATE((prob_per_second_percent)/100, (delta_time)))) // ) - +/// Taxicab distance--gets you the **actual** time it takes to get from one turf to another due to how we calculate diagonal movement #define MANHATTAN_DISTANCE(a, b) (abs(a.x - b.x) + abs(a.y - b.y)) +// ) +/// A function that exponentially approaches a maximum value of L +/// k is the rate at which is approaches L, x_0 is the point where the function = 0 #define LOGISTIC_FUNCTION(L,k,x,x_0) (L/(1+(NUM_E**(-k*(x-x_0))))) - +// ) /// Make sure something is a boolean TRUE/FALSE 1/0 value, since things like bitfield & bitflag doesn't always give 1s and 0s. #define FORCE_BOOLEAN(x) ((x)? TRUE : FALSE) - +// ) +/// Gives the number of pixels in an orthogonal line of tiles. #define TILES_TO_PIXELS(tiles) (tiles * PIXELS) +// ) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 3026be9d46..850a2b0f39 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -345,5 +345,5 @@ #define SPAWN_MEGAFAUNA "bluh bluh huge boss" // / Breathing types. Lungs can access either by these or by a string, which will be considered a gas ID. -#define BREATH_OXY 0 -#define BREATH_PLASMA 1 +#define BREATH_OXY /datum/breathing_class/oxygen +#define BREATH_PLASMA /datum/breathing_class/plasma diff --git a/code/modules/atmospherics/auxgm/breathing_classes.dm b/code/modules/atmospherics/auxgm/breathing_classes.dm new file mode 100644 index 0000000000..7aeb5d82e7 --- /dev/null +++ b/code/modules/atmospherics/auxgm/breathing_classes.dm @@ -0,0 +1,37 @@ +// Breathing classes are, yes, just a list of gases, associated with numbers. +// But they're very simple: pluoxium's status as O2 * 8 is represented here, +// with a single line of code, no hardcoding and special-casing across the codebase. +// Not only that, but they're very general: you could have a negative value +// to simulate asphyxiants, e.g. if I add krypton it could go into the oxygen +// breathing class at -7, simulating krypton narcosis. + +/datum/breathing_class + var/list/gases = null + var/list/products = null + var/danger_reagent = null + var/low_alert_category = "not_enough_oxy" + var/low_alert_datum = /obj/screen/alert/not_enough_oxy + var/high_alert_category = "too_much_oxy" + var/high_alert_datum = /obj/screen/alert/too_much_oxy + +/datum/breathing_class/oxygen + gases = list( + GAS_O2 = 1 + GAS_PLUOXIUM = 8, + GAS_CO2 = -0.7, // CO2 isn't actually toxic, just an asphyxiant + ) + products = list( + GAS_CO2 = 1 + ) + +/datum/breathing_class/plasma + gases = list( + GAS_PLASMA = 1 + ) + products = list( + GAS_CO2 = 1 + ) + low_alert_category = "not_enough_tox" + low_alert_datum = /obj/screen/alert/not_enough_tox + high_alert_category = "too_much_tox" + high_alert_datum = /obj/screen/alert/too_much_tox diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm new file mode 100644 index 0000000000..7ff7b674e8 --- /dev/null +++ b/code/modules/atmospherics/auxgm/gas_types.dm @@ -0,0 +1,170 @@ +/datum/gas/oxygen + id = GAS_O2 + specific_heat = 20 + name = "Oxygen" + oxidation_temperature = T0C - 100 // it checks max of this and fire temperature, so rarely will things spontaneously combust + +/datum/gas/nitrogen + id = GAS_N2 + specific_heat = 20 + breath_alert_info = list( + not_enough_alert = list( + alert_category = "not_enough_nitro", + alert_type = /obj/screen/alert/not_enough_nitro + ) + too_much_alert = list( + alert_category = "too_much_nitro", + alert_type = /obj/screen/alert/too_much_nitro + ) + ) + name = "Nitrogen" + +/datum/gas/carbon_dioxide //what the fuck is this? + id = GAS_CO2 + specific_heat = 30 + name = "Carbon Dioxide" + breath_results = GAS_O2 + breath_alert_info = list( + not_enough_alert = list( + alert_category = "not_enough_co2", + alert_type = /obj/screen/alert/not_enough_co2 + ) + too_much_alert = list( + alert_category = "too_much_co2", + alert_type = /obj/screen/alert/too_much_co2 + ) + ) + breath_reagent_dangerous = /datum/reagent/co2_toxic + fusion_power = 3 + +/datum/gas/plasma + id = GAS_PLASMA + specific_heat = 200 + name = "Plasma" + gas_overlay = "plasma" + moles_visible = MOLES_GAS_VISIBLE + flags = GAS_FLAG_DANGEROUS + // no fire info cause it has its own bespoke reaction for trit generation reasons + +/datum/gas/water_vapor + id = GAS_H2O + specific_heat = 40 + name = "Water Vapor" + gas_overlay = "water_vapor" + moles_visible = MOLES_GAS_VISIBLE + fusion_power = 8 + breath_reagent = /datum/reagent/water + +/datum/gas/hypernoblium + id = GAS_HYPERNOB + specific_heat = 2000 + name = "Hyper-noblium" + gas_overlay = "freon" + moles_visible = MOLES_GAS_VISIBLE + +/datum/gas/nitrous_oxide + id = GAS_NITROUS + specific_heat = 40 + name = "Nitrous Oxide" + gas_overlay = "nitrous_oxide" + moles_visible = MOLES_GAS_VISIBLE * 2 + flags = GAS_FLAG_DANGEROUS + fire_products = list(GAS_N2 = 1) + oxidation_rate = 0.5 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 + +/datum/gas/nitryl + id = GAS_NITRYL + specific_heat = 20 + name = "Nitryl" + gas_overlay = "nitryl" + moles_visible = MOLES_GAS_VISIBLE + flags = GAS_FLAG_DANGEROUS + fusion_power = 15 + fire_products = list(GAS_N2 = 0.5) + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + +/datum/gas/tritium + id = GAS_TRITIUM + specific_heat = 10 + name = "Tritium" + gas_overlay = "tritium" + moles_visible = MOLES_GAS_VISIBLE + flags = GAS_FLAG_DANGEROUS + fusion_power = 1 + /* + these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons + fire_provides = list(GAS_H2O = 2) + fire_burn_rate = 2 + fire_energy_released = FIRE_HYDROGEN_ENERGY_RELEASED + fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + */ + +/datum/gas/bz + id = GAS_BZ + specific_heat = 20 + name = "BZ" + flags = GAS_FLAG_DANGEROUS + fusion_power = 8 + +/datum/gas/stimulum + id = GAS_STIMULUM + specific_heat = 5 + name = "Stimulum" + fusion_power = 7 + +/datum/gas/pluoxium + id = GAS_PLUOXIUM + specific_heat = 80 + name = "Pluoxium" + fusion_power = 10 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 + oxidation_rate = 8 + +/datum/gas/miasma + id = GAS_MIASMA + specific_heat = 20 + fusion_power = 50 + name = "Miasma" + gas_overlay = "miasma" + moles_visible = MOLES_GAS_VISIBLE * 60 + +/datum/gas/methane + id = GAS_METHANE + specific_heat = 30 + name = "Methane" + breath_results = GAS_METHYL_BROMIDE + fire_provides = list(GAS_CO2 = 1, GAS_H2O = 2) + fire_burn_rate = 0.5 + breath_alert_info = list( + not_enough_alert = list( + alert_category = "not_enough_ch4", + alert_type = /obj/screen/alert/not_enough_ch4 + ) + too_much_alert = list( + alert_category = "too_much_ch4", + alert_type = /obj/screen/alert/too_much_ch4 + ) + ) + fire_energy_released = FIRE_CARBON_ENERGY_RELEASED + fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + +/datum/gas/methyl_bromide + id = GAS_METHYL_BROMIDE + specific_heat = 42 + name = "Methyl Bromide" + flags = GAS_FLAG_DANGEROUS + breath_alert_info = list( + not_enough_alert = list( + alert_category = "not_enough_ch3br", + alert_type = /obj/screen/alert/not_enough_ch3br + ) + too_much_alert = list( + alert_category = "too_much_ch3br", + alert_type = /obj/screen/alert/too_much_ch3br + ) + ) + fire_provides = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BZ = 0.5) + fire_energy_released = FIRE_CARBON_ENERGY_RELEASED + fire_burn_rate = 0.5 + fire_temperature = 808 // its autoignition, it apparently doesn't spark readily, so i don't put it lower diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm new file mode 100644 index 0000000000..9f489c7384 --- /dev/null +++ b/code/modules/atmospherics/gasmixtures/auxgm.dm @@ -0,0 +1,124 @@ +GLOBAL_LIST_INIT(hardcoded_gases, list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLASMA)) //the main four gases, which were at one time hardcoded +GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLUOXIUM, GAS_STIMULUM, GAS_NITRYL))) //unable to react amongst themselves + +// Auxgm +// It's a send-up of XGM, like what baystation got. +// It's got the same architecture as XGM, but it's structured +// differently to make it more convenient for auxmos. + +// Most important compared to TG is that it does away with hardcoded typepaths, +// which lead to problems on the auxmos end anyway. We cache the string value +// references on the Rust end, so no performance is lost here. + +// Also allows you to add new gases at runtime + +/proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas + +/datum/auxgm + var/list/datums = list() + var/list/specific_heats = list() + var/list/names = list() + var/list/visibility = list() + var/list/overlays = list() + var/list/flags = list() + var/list/ids = list() + var/list/typepaths = list() + var/list/fusion_powers = list() + var/list/breathing_classes = list() + var/list/breath_results = list() + var/list/breath_reagents = list() + var/list/breath_reagents_dangerous = list() + var/list/breath_alert_info = list() + var/list/oxidation_temperatures = list() + var/list/oxidation_rates = list() + var/list/fire_temperatures = list() + var/list/fire_enthalpies = list() + var/list/fire_products = list() + var/list/fire_burn_rates = list() + + +/datum/gas + var/id = "" + var/specific_heat = 0 + var/name = "" + var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi + var/moles_visible = null + var/flags = NONE //currently used by canisters + var/fusion_power = 0 // How much the gas destabilizes a fusion reaction + var/breath_results = GAS_CO2 // what breathing this breathes out + var/breath_reagent = null // what breathing this adds to your reagents + var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold + var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something + var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none + var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material + var/fire_temperature = null // temperature above which gas may catch fire; null for none + var/list/fire_products = null // what results when this gas is burned (oxidizer or fuel); null for none + var/fire_energy_released = 0 // how much energy is released per mole of fuel burned + var/fire_burn_rate = 1 // how many moles are burned per product released + +/datum/gas/proc/breath(partial_pressure, light_threshold, heavy_threshold, moles, mob/living/carbon/C, obj/item/organ/lungs/lungs) + // This is only called on gases with the GAS_FLAG_BREATH_PROC flag. When possible, do NOT use this-- + // greatly prefer just adding a reagent. This is mostly around for legacy reasons. + return null + +/datum/auxgm/add_gas(datum/gas/gas) + var/g = gas.id + if(g) + datums[g] = gas + specific_heats[g] = gas.specific_heat + names[g] = gas.name + if(gas.moles_visible) + visibility[g] = gas.moles_visible + overlays[g] = new /list(FACTOR_GAS_VISIBLE_MAX) + for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX) + overlays[g][i] = new /obj/effect/overlay/gas(gas.gas_overlay, i * 255 / FACTOR_GAS_VISIBLE_MAX) + else + visibility[g] = 0 + overlays[g] = 0 + flags[g] = gas.flags + ids[g] = g + typepaths[g] = gas_path + fusion_powers[g] = gas.fusion_power + + if(gas.breath_alert_info) + breath_alert_info[g] = gas.breath_alert_info + breath_results[g] = gas.breath_results + if(gas.breath_reagent) + breath_reagents[g] = gas.breath_reagent + if(gas.breath_reagent_dangerous) + breath_reagents_dangerous[g] = gas.breath_reagent_dangerous + + if(gas.oxidation_temperature) + oxidation_temperatures[g] = gas.oxidation_temperature + oxidation_rates[g] = gas.oxidation_rate + if(gas.fire_products) + fire_products[g] = gas.fire_products + fire_enthalpies[g] = gas.fire_energy_released + else if(gas.fire_temperature) + fire_temperatures[g] = gas.fire_temperature + fire_burn_rates[g] = gas.fire_burn_rate + if(gas.fire_products) + fire_products[g] = gas.fire_products + fire_enthalpies[g] = gas.fire_energy_released + + _auxtools_register_gas(gas) + +/datum/auxgm/New() + for(var/gas_path in subtypesof(/datum/gas)) + var/datum/gas/gas = new gas_path + add_gas(gas) + +GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) + +/obj/effect/overlay/gas + icon = 'icons/effects/atmospherics.dmi' + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + anchored = TRUE // should only appear in vis_contents, but to be safe + layer = FLY_LAYER + appearance_flags = TILE_BOUND + vis_flags = NONE + +/obj/effect/overlay/gas/New(state, alph) + . = ..() + icon_state = state + alpha = alph diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 016d17811f..d415536c4d 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -314,17 +314,6 @@ GLOBAL_LIST_INIT(auxtools_atmos_initialized,FALSE) if (. & STOP_REACTIONS) break */ -//Takes the amount of the gas you want to PP as an argument -//So I don't have to do some hacky switches/defines/magic strings -//eg: -//Tox_PP = get_partial_pressure(gas_mixture.toxins) -//O2_PP = get_partial_pressure(gas_mixture.oxygen) - -/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure) - return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME -//inverse -/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure) - return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature()) /datum/gas_mixture/proc/set_analyzer_results(instability) if(!analyzer_results) diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm deleted file mode 100644 index d7f94b0236..0000000000 --- a/code/modules/atmospherics/gasmixtures/gas_types.dm +++ /dev/null @@ -1,227 +0,0 @@ -GLOBAL_LIST_INIT(hardcoded_gases, list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLASMA)) //the main four gases, which were at one time hardcoded -GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLUOXIUM, GAS_STIMULUM, GAS_NITRYL))) //unable to react amongst themselves - -// Auxgm -// It's a send-up of XGM, like what baystation got. -// It's got the same architecture as XGM, but it's structured -// differently to make it more convenient for auxmos. - -// Most important compared to TG is that it does away with hardcoded typepaths, -// which lead to problems on the auxmos end anyway. We cache the string value -// references on the Rust end, so no performance is lost here. - -// Also allows you to add new gases at runtime - -/proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas - -/datum/auxgm - var/list/datums = list() - var/list/specific_heats = list() - var/list/names = list() - var/list/visibility = list() - var/list/overlays = list() - var/list/flags = list() - var/list/ids = list() - var/list/typepaths = list() - var/list/fusion_powers = list() - -/datum/auxgm/add_gas(datum/gas/gas) - var/g = gas.id - if(g) - datums[g] = gas - specific_heats[g] = gas.specific_heat - names[g] = gas.name - if(gas.moles_visible) - visibility[g] = gas.moles_visible - overlays[g] = new /list(FACTOR_GAS_VISIBLE_MAX) - for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX) - overlays[g][i] = new /obj/effect/overlay/gas(gas.gas_overlay, i * 255 / FACTOR_GAS_VISIBLE_MAX) - else - visibility[g] = 0 - overlays[g] = 0 - flags[g] = gas.flags - ids[g] = g - typepaths[g] = gas_path - fusion_powers[g] = gas.fusion_power - _auxtools_register_gas(gas) - -/datum/auxgm/New() - for(var/gas_path in subtypesof(/datum/gas)) - var/datum/gas/gas = new gas_path - add_gas(gas) - -GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) - -/datum/breath_info - var/breathing_power = 1 // how much this gas counts for good-breath - var/breathing_class = null // what type of breath this is; lungs can also use gas IDs directly - var/breath_results = GAS_CO2 // what breathing a mole of this results in - -/datum/oxidation_info - var/oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST // temperature above which this gas is an oxidizer - var/list/oxidation_provides = list() // a list of elements this gas provides in combustion - -/datum/gas - var/id = "" - var/specific_heat = 0 - var/name = "" - var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi - var/moles_visible = null - var/flags = NONE //currently used by canisters - var/fusion_power = 0 // How much the gas destabilizes a fusion reaction - var/breathing_power = 1 // how much this gas counts for good-breath - var/breathing_class = null // what type of breath this is; lungs can also use gas IDs directly - var/breath_results = GAS_CO2 // what breathing a mole of this results in - var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none - var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material - var/oxidation_energy_released = 0 // how many moles are released per mole burned - var/list/oxidation_products = null // extra results from oxidizing this (per mole); null for none - var/fire_temperature = null // temperature above which gas may catch fire; null for none - var/list/fire_provides = null // what elements this gas provides as fuel for combustion; null for none - var/fire_energy_released = 0 // how much energy is released per mole of fuel burned - var/fire_burn_rate = 1 // how many moles are burned per product released - -/datum/gas/oxygen - id = GAS_O2 - specific_heat = 20 - name = "Oxygen" - breathing_class = BREATH_OXY - oxidation_temperature = T0C - 100 // it checks max of this and fire temperature, so rarely will things spontaneously combust - -/datum/gas/nitrogen - id = GAS_N2 - specific_heat = 20 - name = "Nitrogen" - -/datum/gas/carbon_dioxide //what the fuck is this? - id = GAS_CO2 - specific_heat = 30 - name = "Carbon Dioxide" - fusion_power = 3 - -/datum/gas/plasma - id = GAS_PLASMA - specific_heat = 200 - name = "Plasma" - gas_overlay = "plasma" - moles_visible = MOLES_GAS_VISIBLE - flags = GAS_FLAG_DANGEROUS - breathing_class = BREATH_PLASMA - // no fire info cause it has its own bespoke reaction for trit generation reasons - -/datum/gas/water_vapor - id = GAS_H2O - specific_heat = 40 - name = "Water Vapor" - gas_overlay = "water_vapor" - moles_visible = MOLES_GAS_VISIBLE - fusion_power = 8 - -/datum/gas/hypernoblium - id = GAS_HYPERNOB - specific_heat = 2000 - name = "Hyper-noblium" - gas_overlay = "freon" - moles_visible = MOLES_GAS_VISIBLE - -/datum/gas/nitrous_oxide - id = GAS_NITROUS - specific_heat = 40 - name = "Nitrous Oxide" - gas_overlay = "nitrous_oxide" - moles_visible = MOLES_GAS_VISIBLE * 2 - flags = GAS_FLAG_DANGEROUS - oxidation_products = list(GAS_N2 = 1) - oxidation_rate = 0.5 - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 - -/datum/gas/nitryl - id = GAS_NITRYL - specific_heat = 20 - name = "Nitryl" - gas_overlay = "nitryl" - moles_visible = MOLES_GAS_VISIBLE - flags = GAS_FLAG_DANGEROUS - fusion_power = 15 - oxidation_products = list(GAS_N2 = 0.5) - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 - -/datum/gas/tritium - id = GAS_TRITIUM - specific_heat = 10 - name = "Tritium" - gas_overlay = "tritium" - moles_visible = MOLES_GAS_VISIBLE - flags = GAS_FLAG_DANGEROUS - fusion_power = 1 - /* - these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons - fire_provides = list(GAS_H2O = 2) - fire_burn_rate = 2 - fire_energy_released = FIRE_HYDROGEN_ENERGY_RELEASED - fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 - */ - -/datum/gas/bz - id = GAS_BZ - specific_heat = 20 - name = "BZ" - flags = GAS_FLAG_DANGEROUS - fusion_power = 8 - -/datum/gas/stimulum - id = GAS_STIMULUM - specific_heat = 5 - name = "Stimulum" - fusion_power = 7 - -/datum/gas/pluoxium - id = GAS_PLUOXIUM - specific_heat = 80 - name = "Pluoxium" - fusion_power = 10 - breathing_power = 8 - breathing_class = CLASS_OXY - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 - oxidation_rate = 8 - -/datum/gas/miasma - id = GAS_MIASMA - specific_heat = 20 - fusion_power = 50 - name = "Miasma" - gas_overlay = "miasma" - moles_visible = MOLES_GAS_VISIBLE * 60 - -/datum/gas/methane - id = GAS_METHANE - specific_heat = 30 - name = "Methane" - fire_provides = list(GAS_CO2 = 1, GAS_H2O = 2) - fire_burn_rate = 0.5 - fire_energy_released = FIRE_CARBON_ENERGY_RELEASED - fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - -/datum/gas/methyl_bromide - id = GAS_METHYL_BROMIDE - specific_heat = 42 - name = "Methyl Bromide" - flags = GAS_FLAG_DANGEROUS - fire_provides = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BZ = 0.5) - fire_energy_released = FIRE_CARBON_ENERGY_RELEASED - fire_burn_rate = 0.5 - fire_temperature = 808 // its autoignition, it apparently doesn't spark readily, so i don't put it lower - - -/obj/effect/overlay/gas - icon = 'icons/effects/atmospherics.dmi' - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - anchored = TRUE // should only appear in vis_contents, but to be safe - layer = FLY_LAYER - appearance_flags = TILE_BOUND - vis_flags = NONE - -/obj/effect/overlay/gas/New(state, alph) - . = ..() - icon_state = state - alpha = alph diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index d523b2afda..7a6c545a94 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -253,8 +253,56 @@ /datum/gas_reaction/genericfire/react(datum/gas_mixture/air, datum/holder) var/temperature = air.return_temperature() var/list/oxidation_temps = GLOB.gas_data.oxidation_temps - for(var/datum/gas/G in air.get_gases()) - + var/list/oxidation_rates = GLOB.gas_data.oxidation_rates + var/oxidation_power = 0 + var/list/burn_results = list() + var/list/fuels = list() + var/list/oxidizers = list() + var/list/fuel_rates = GLOB.gas_data.fuel_rates + var/total_fuel = 0 + var/energy_released = 0 + for(var/G in air.get_gases()) + var/oxidation_temp = oxidation_temps[G] + if(oxidation_temp && oxidation_temp > temperature) + var/temperature_scale = max(0, 1-(temperature / oxidation_temp)) + var/amt = air.get_moles(G) * temperature_scale + oxidizers[G] = amt + oxidation_power += amt * oxidation_rates[G] + else + var/fuel_temp = fuel_temps[G] + if(fuel_temp && fuel_temp > temperature) + var/amt = (air.get_moles(G) / fuel_rates[G]) * max(0, 1-(temperature / fuel_temp)) + fuels[G] = amt // we have to calculate the actual amount we're using after we get all oxidation together + total_fuel += amt + if(oxidation_power <= 0 || total_fuel <= 0) + return NO_REACTION + var/oxidation_ratio = oxidation_power / total_fuel + if(oxidation_ratio > 1) + for(var/oxidizer in oxidizers) + oxidizers[oxidizer] /= oxidation_ratio + else if oxidation_ratio < 1 + for(var/fuel in fuels) + fuels[fuel] *= oxidation_ratio + fuels += oxidizers + var/list/fire_products = GLOB.gas_data.fire_products + var/list/fire_enthalpies = GLOB.gas_data.fire_enthalpies + for(var/fuel in fuels + oxidizers) + var/amt = fuels[fuel] + if(!burn_results[fuel]) + burn_results[fuel] = 0 + burn_results[fuel] -= amt + energy_released += amt * fire_enthalpies[fuel] + for(var/product in fire_products[fuel]) + if(!burn_results[product]) + burn_results[product] = 0 + burn_results[o] += amt + var/final_energy = air.thermal_energy() + energy_released + for(var/result in burn_results) + air.adjust_moles(result, burn_results[result]) + air.set_temperature(final_energy / air.heat_capacity()) + var/list/cached_results = air.reaction_results + cached_results["fire"] = min(total_fuel, oxidation_power) * 2 + return cached_results["fire"] ? REACTING : NO_REACTION //fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again! diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index d5f59e2441..aee341f62b 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -163,11 +163,11 @@ var/SA_para_min = 1 var/SA_sleep_min = 5 var/oxygen_used = 0 - var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME - - var/O2_partialpressure = (breath.get_moles(GAS_O2)/breath.total_moles())*breath_pressure - var/Toxins_partialpressure = (breath.get_moles(GAS_PLASMA)/breath.total_moles())*breath_pressure - var/CO2_partialpressure = (breath.get_moles(GAS_CO2)/breath.total_moles())*breath_pressure + var/moles = breath.total_moles() + var/breath_pressure = (moles*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME + var/O2_partialpressure = ((breath.get_moles(GAS_O2)/moles)*breath_pressure) + (((breath.get_moles(GAS_PLUOXIUM)*8)/moles)*breath_pressure) + var/Toxins_partialpressure = (breath.get_moles(GAS_PLASMA)/moles)*breath_pressure + var/CO2_partialpressure = (breath.get_moles(GAS_CO2)/moles)*breath_pressure //OXYGEN diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index a17a281147..51bf87f717 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -27,22 +27,33 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/salbutamol = 5) //Breath damage + var/breathing_class = BREATH_OXY // can be a gas instead of a breathing class + var/safe_breath_min = 16 + var/safe_breath_max = 50 + var/safe_breath_dam_min = MIN_TOXIC_GAS_DAMAGE + var/safe_breath_dam_max = MAX_TOXIC_GAS_DAMAGE + var/safe_damage_type = OXY + var/list/gas_min = list() + var/list/gas_max = list( + GAS_CO2 = 10, // Yes it's an arbitrary value who cares? + GAS_METHYL_BROMIDE = 1, + GAS_PLASMA = MOLES_GAS_VISIBLE + ) + var/list/gas_damage = list( + "default" = list( + min = MIN_TOXIC_GAS_DAMAGE, + max = MAX_TOXIC_GAS_DAMAGE, + damage_type = OXY + ) + GAS_PLASMA = list( + min = MIN_TOXIC_GAS_DAMAGE, + max = MAX_TOXIC_GAS_DAMAGE, + damage_type = TOX + ) + ) - var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa - var/safe_oxygen_max = 50 // Too much of a good thing, in kPa as well. - var/safe_nitro_min = 0 - var/safe_nitro_max = 0 - var/safe_co2_min = 0 - var/safe_co2_max = 10 // Yes it's an arbitrary value who cares? - var/safe_toxins_min = 0 - var/safe_toxins_max = MOLES_GAS_VISIBLE - var/safe_ch3br_min = 0 - var/safe_ch3br_max = 1 //problematic even at low concentrations - var/safe_methane_min = 0 - var/safe_methane_max = 0 - var/SA_para_min = 1 //Sleeping agent - var/SA_sleep_min = 5 //Sleeping agent - var/BZ_trip_balls_min = 1 //BZ gas + var/light_effect_resistance = 1 // PP at which light snowflake effects happen + var/heavy_effect_resistance = 5 // PP at which heavy snowflake effects happen var/gas_stimulation_min = 0.002 //Nitryl and Stimulum var/oxy_breath_dam_min = MIN_TOXIC_GAS_DAMAGE @@ -81,7 +92,14 @@ var/crit_stabilizing_reagent = /datum/reagent/medicine/epinephrine - +/obj/item/organ/lungs/New() + gas_min[breathing_class] = safe_breath_min + gas_max[breathing_class] = safe_breath_max + gas_damage[breathing_class] = list( + min = safe_breath_dam_min, + max = safe_breath_dam_max, + damage_type = safe_damage_type + ) //TODO: lung health affects lung function /obj/item/organ/lungs/onDamage(damage_mod) //damage might be too low atm. @@ -128,221 +146,98 @@ H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) H.failed_last_breath = TRUE - if(safe_oxygen_min) - H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) - else if(safe_toxins_min) - H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) - else if(safe_co2_min) - H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) - else if(safe_nitro_min) - H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro) - else if(safe_ch3br_min) - H.throw_alert("not_enough_ch3br", /obj/screen/alert/not_enough_ch3br) + var/list/alert = GLOB.gas_data.breath_alert_info[breathing_class]["not_enough_alert"] + H.throw_alert(alert["alert_category"], alert["alert_type"]) return FALSE + #define PP_MOLES(X) ((X / total_moles) * pressure)) + + #define PP(air, gas) PP_MOLES(air.get_moles(gas)) + var/gas_breathed = 0 - //Partial pressures in our breath - var/O2_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_O2))+(8*breath.get_breath_partial_pressure(breath.get_moles(GAS_PLUOXIUM))) - var/N2_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_N2)) - var/Toxins_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_PLASMA)) - var/CO2_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_CO2)) - var/CH4_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_METHANE)) - var/CH3Br_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_METHYL_BROMIDE)) - - - //-- OXY --// - - //Too much oxygen! //Yes, some species may not like it. - if(safe_oxygen_max) - if((O2_pp > safe_oxygen_max) && safe_oxygen_max == 0) //I guess plasma men technically need to have a check. - var/ratio = (breath.get_moles(GAS_O2)/safe_oxygen_max) * 10 - H.apply_damage_type(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) - H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) - - else if((O2_pp > safe_oxygen_max) && !(safe_oxygen_max == 0)) //Why yes, this is like too much CO2 and spahget. Dirty lizards. - if(!H.o2overloadtime) - H.o2overloadtime = world.time - else if(world.time - H.o2overloadtime > 120) - H.Dizzy(10) // better than a minute of you're fucked KO, but certainly a wake up call. Honk. - H.adjustOxyLoss(3) - if(world.time - H.o2overloadtime > 300) - H.adjustOxyLoss(8) - if(prob(20)) - H.emote("cough") - H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) - + var/pressure = breath.return_pressure() + var/total_moles = breath.total_moles() + var/list/breath_alert_info = GLOB.gas_data.breath_alert_info + var/list/breath_results = GLOB.gas_data.breath_results + var/list/mole_adjustments = list() + for(var/entry in gas_min) + var/required_pp = 0 + var/required_moles = 0 + var/safe_min = gas_min[entry] + var/datum/breathing_class/breathing_class = entry + var/alert_category = "" + var/alert_type = null + if(istype(breathing_class)) // breathing classes are numbers while gases are strings so internally this is how we do it + var/list/gases = initial(breathing_class.gases) + var/list/products = initial(breathing_class.products) + alert_category = initial(breathing_class.low_alert_category) + alert_type = initial(breathing_class.low_alert_type) + for(var/gas in gases) + var/moles = breath.get_moles(gas) + var/multiplier = gases[gas] + mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - moles : -moles + required_moles += moles + required_pp += PP_MOLES(moles) * multiplier + var/to_add = moles * multiplier + for(var/product in products) + mole_adjustments[product] = (product in mole_adjustments) ? mole_adjustments[product] + to_add : to_add else - H.o2overloadtime = 0 - H.clear_alert("too_much_oxy") - - //Too little oxygen! - if(safe_oxygen_min) - if(O2_pp < safe_oxygen_min) - gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.get_moles(GAS_O2)) - H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) - else - H.failed_last_breath = FALSE - if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-breathModifier) //More damaged lungs = slower oxy rate up to a factor of half - gas_breathed = breath.get_moles(GAS_O2) - H.clear_alert("not_enough_oxy") - - //Exhale - breath.adjust_moles(GAS_O2, -gas_breathed) - breath.adjust_moles(GAS_CO2, gas_breathed) - gas_breathed = 0 - - //-- Nitrogen --// - - //Too much nitrogen! - if(safe_nitro_max) - if(N2_pp > safe_nitro_max) - var/ratio = (breath.get_moles(GAS_N2)/safe_nitro_max) * 10 - H.apply_damage_type(clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) - H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro) - H.losebreath += 2 - else - H.clear_alert("too_much_nitro") - - //Too little nitrogen! - if(safe_nitro_min) - if(N2_pp < safe_nitro_min) - gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.get_moles(GAS_N2)) - H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro) + required_moles = breath.get_moles(entry) + required_pp = PP_MOLES(required_moles) + var/list/alert = breath_alert_info[entry]["not_enough_alert"] + alert_category = alert["alert_category"] + alert_type = alert["alert_type"] + mole_adjustments[entry] = -required_moles + mole_adjustments[breath_results[entry]] = required_moles + if(required_pp < safe_min) + var/multiplier = handle_too_little_breath(H, required_pp, safe_min, required_moles) / required_moles + for(var/entry in mole_adjustments) + mole_adjustments[entry] *= multiplier + H.throw_alert(alert_category, alert_type) else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) H.adjustOxyLoss(-breathModifier) - gas_breathed = breath.get_moles(GAS_N2) - H.clear_alert("nitro") - - //Exhale - breath.adjust_moles(GAS_N2, -gas_breathed) - breath.adjust_moles(GAS_CO2, gas_breathed) - gas_breathed = 0 - - //-- CO2 --// - - //CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick. - if(safe_co2_max) - if(CO2_pp > safe_co2_max) - if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so. - H.co2overloadtime = world.time - else if(world.time - H.co2overloadtime > 120) - H.Unconscious(60) - H.apply_damage_type(3, co2_damage_type) // Lets hurt em a little, let them know we mean business - if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good! - H.apply_damage_type(8, co2_damage_type) - H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2) - if(prob(20)) // Lets give them some chance to know somethings not right though I guess. - H.emote("cough") - + H.clear_alert(alert_category) + var/list/danger_reagents = GLOB.gas_data.breath_reagents_dangerous + for(var/entry in gas_max) + var/found_pp = 0 + var/datum/breathing_class/breathing_class = entry + var/datum/reagent/danger_reagent = null + var/alert_category = "" + var/alert_type = null + if(istype(breathing_class)) + var/list/gases = initial(breathing_class.gases) + alert_category = initial(breathing_class.high_alert_category) + alert_type = initial(breathing_class.high_alert_type) + danger_reagent = initial(breathing_class.danger_reagent) + for(var/gas in gases) + found_pp +== PP(breath, breathing_class) else - H.co2overloadtime = 0 - H.clear_alert("too_much_co2") + danger_reagent = danger_reagents[entry] + var/list/alert = breath_alert_info[entry]["too_much_alert"] + alert_category = alert["alert_category"] + alert_type = alert["alert_type"] + found_pp = PP(breath, entry) + if(found_pp > gas_max[entry]) + if(istype(danger_reagent)) + H.reagents.add_reagent(danger_reagent,1) + if(gas_flags[gas] & GAS_FLAG_BREATH_PROC) + gas_datums[gas].breath(PP_MOLES(moles), light_effect_resistance, heavy_effect_resistance, moles, H, src) + var/list/damage_info = gas_damage[entry] + var/dam = found_pp / gas_max[entry] * 10 + H.apply_damage_type(clamp(ratio, damage_info["min"], damage_info["max"]), damage_info["damage_type"]) + var/list/breath_reagents = GLOB.gas_data.breath_reagents + var/list/gas_flags = GLOB.gas_data.flags + var/list/gas_datums = GLOB.gas_data.datums + for(var/gas in breath.get_gases()) + if(gas in breath_reagents) + var/datum/reagent/R = breath_reagents[gas] + H.reagents.add_reagent(R, PP(breath,gas)) + mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - breath.get_moles(gas) : -breath.get_moles(gas) - //Too little CO2! - if(safe_co2_min) - if(CO2_pp < safe_co2_min) - gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.get_moles(GAS_CO2)) - H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) - else - H.failed_last_breath = FALSE - if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-breathModifier) - gas_breathed = breath.get_moles(GAS_CO2) - H.clear_alert("not_enough_co2") - - //Exhale - breath.adjust_moles(GAS_CO2, -gas_breathed) - breath.adjust_moles(GAS_O2, gas_breathed) - gas_breathed = 0 - - - //-- TOX --// - - //Too much toxins! - if(safe_toxins_max) - if(Toxins_pp > safe_toxins_max) - var/ratio = (breath.get_moles(GAS_PLASMA)/safe_toxins_max) * 10 - H.apply_damage_type(clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) - H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) - else - H.clear_alert("too_much_tox") - - - //Too little toxins! - if(safe_toxins_min) - if(Toxins_pp < safe_toxins_min) - gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.get_moles(GAS_PLASMA)) - H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) - else - H.failed_last_breath = FALSE - if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-breathModifier) - gas_breathed = breath.get_moles(GAS_PLASMA) - H.clear_alert("not_enough_tox") - - //Exhale - breath.adjust_moles(GAS_PLASMA, -gas_breathed) - breath.adjust_moles(GAS_CO2, gas_breathed) - gas_breathed = 0 - -//-- METHANE --// - - //Too much methane! - if(safe_methane_max) - if(CH4_pp > safe_methane_max) //Same effect as excess nitrogen, generally nontoxic - var/ratio = (breath.get_moles(GAS_METHANE)/safe_methane_max) * 10 - H.apply_damage_type(clamp(ratio, methane_breath_dam_min, methane_breath_dam_max), methane_damage_type) - H.throw_alert("too_much_ch4", /obj/screen/alert/too_much_ch4) - H.losebreath += 2 - else - H.clear_alert("too_much_ch4") - //Too little methane! - if(safe_methane_min) - if(CH4_pp < safe_methane_min) - gas_breathed = handle_too_little_breath(H, CH4_pp, safe_methane_min, breath.get_moles(GAS_METHANE)) - H.throw_alert("not_enough_ch4", /obj/screen/alert/not_enough_ch4) - else - H.failed_last_breath = FALSE - if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-breathModifier) - gas_breathed = breath.get_moles(GAS_METHANE) - H.clear_alert("not_enough_ch4") - - //Exhale - breath.adjust_moles(GAS_METHANE, -gas_breathed) - breath.adjust_moles(GAS_METHYL_BROMIDE, gas_breathed) - gas_breathed = 0 - -//-- CH3BR --// - - //Too much methyl bromide! - if(safe_ch3br_max) - if(CH3Br_pp > safe_ch3br_max) - if(prob(CH3Br_pp/0.5)) - H.adjustOrganLoss(ORGAN_SLOT_LUNGS, 3, 150) //Inhaling this is a bad idea - if(prob(CH3Br_pp/2)) - to_chat(H, "Your throat closes up!") - H.silent = max(H.silent, 3) - H.throw_alert("too_much_ch3br", /obj/screen/alert/too_much_ch3br) - else - H.clear_alert("too_much_ch3br") - //Too little methyl bromide! - if(safe_ch3br_min) - if(CH3Br_pp < safe_ch3br_min) - gas_breathed = handle_too_little_breath(H, CH3Br_pp, safe_ch3br_min, breath.get_moles(GAS_METHYL_BROMIDE)) - H.throw_alert("not_enough_ch3br", /obj/screen/alert/not_enough_ch3br) - else - H.failed_last_breath = FALSE - if(H.health >= H.crit_threshold) - H.adjustOxyLoss(-breathModifier) - gas_breathed = breath.get_moles(GAS_METHYL_BROMIDE) - H.clear_alert("not_enough_ch3br") - - //-- TRACES --// + breath.adjust_from_list(mole_adjustments) if(breath) // If there's some other shit in the air lets deal with it here. @@ -373,14 +268,6 @@ H.hallucination += 5 H.reagents.add_reagent(/datum/reagent/bz_metabolites,1) - - // Tritium - var/trit_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_TRITIUM)) - if (trit_pp > 50) - H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up. - else - H.radiation += trit_pp/10 - // Nitryl var/nitryl_pp = breath.get_breath_partial_pressure(breath.get_moles(GAS_NITRYL)) if (prob(nitryl_pp)) diff --git a/tgstation.dme b/tgstation.dme index 27df3307ef..df3bb258c7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1790,11 +1790,13 @@ #include "code\modules\asset_cache\transports\asset_transport.dm" #include "code\modules\asset_cache\transports\webroot_transport.dm" #include "code\modules\atmospherics\multiz.dm" +#include "code\modules\atmospherics\auxgm\breathing_classes.dm" +#include "code\modules\atmospherics\auxgm\gas_types.dm" #include "code\modules\atmospherics\environmental\LINDA_fire.dm" #include "code\modules\atmospherics\environmental\LINDA_system.dm" #include "code\modules\atmospherics\environmental\LINDA_turf_tile.dm" +#include "code\modules\atmospherics\gasmixtures\auxgm.dm" #include "code\modules\atmospherics\gasmixtures\gas_mixture.dm" -#include "code\modules\atmospherics\gasmixtures\gas_types.dm" #include "code\modules\atmospherics\gasmixtures\immutable_mixtures.dm" #include "code\modules\atmospherics\gasmixtures\reactions.dm" #include "code\modules\atmospherics\machinery\airalarm.dm"