diff --git a/auxmos.dll b/auxmos.dll index d16063c4e4..a5fc480d10 100644 Binary files a/auxmos.dll and b/auxmos.dll differ diff --git a/auxmos.pdb b/auxmos.pdb index 86b751346e..12fb921360 100644 Binary files a/auxmos.pdb and b/auxmos.pdb differ diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index c1e4f0af9b..1eafe07b13 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -128,6 +128,7 @@ #define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) #define TANK_MIN_RELEASE_PRESSURE 0 #define TANK_DEFAULT_RELEASE_PRESSURE 17 +#define TANK_POST_FRAGMENT_REACTIONS 5 //CANATMOSPASS #define ATMOS_PASS_YES 1 @@ -260,6 +261,7 @@ #define GAS_HYPERNOB "nob" #define GAS_NITROUS "n2o" #define GAS_NITRYL "no2" +#define GAS_HYDROGEN "hydrogen" #define GAS_TRITIUM "tritium" #define GAS_BZ "bz" #define GAS_STIMULUM "stim" @@ -267,9 +269,16 @@ #define GAS_MIASMA "miasma" #define GAS_METHANE "methane" #define GAS_METHYL_BROMIDE "methyl_bromide" +#define GAS_BROMINE "bromine" +#define GAS_AMMONIA "ammonia" +#define GAS_FLUORINE "fluorine" +#define GAS_ETHANOL "ethanol" + +#define GAS_GROUP_CHEMICALS "Chemicals" #define GAS_FLAG_DANGEROUS (1<<0) #define GAS_FLAG_BREATH_PROC (1<<1) +#define GAS_FLAG_CHEMICAL (1<<2) //SUPERMATTER DEFINES #define HEAT_PENALTY "heat penalties" diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 33683d20ef..d0d6f24343 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -25,6 +25,9 @@ /// Do not allow this random event to continue. #define CANCEL_PRE_RANDOM_EVENT (1<<0) +/// called by auxgm add_gas: (gas_id) +#define COMSIG_GLOB_NEW_GAS "!new_gas" + // signals from globally accessible objects /// from SSsun when the sun changes position : (primary_sun, suns) #define COMSIG_SUN_MOVED "sun_moved" diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index b5d322a091..fad53e4830 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -13,7 +13,7 @@ #define NITRYL_FORMATION_ENERGY 100000 #define TRITIUM_BURN_OXY_FACTOR 100 #define TRITIUM_BURN_TRIT_FACTOR 10 -#define TRITIUM_BURN_RADIOACTIVITY_FACTOR 50000 //The neutrons gotta go somewhere. Completely arbitrary number. +#define TRITIUM_BURN_RADIOACTIVITY_FACTOR 5000 //The neutrons gotta go somewhere. Completely arbitrary number. #define TRITIUM_MINIMUM_RADIATION_ENERGY 0.1 //minimum 0.01 moles trit or 10 moles oxygen to start producing rads #define SUPER_SATURATION_THRESHOLD 96 #define STIMULUM_HEAT_SCALE 100000 diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index 60effc7265..4b8b2c797e 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -73,4 +73,6 @@ TECHWEB_POINT_TYPE_GENERIC = "General Research"\ ) -#define TECHWEB_BOMB_POINTCAP 50000 //Adjust as needed; Stops toxins from nullifying RND progression mechanics. Current Value Cap Radius: 100 +#define BOMB_TARGET_POINTS 50000 //Adjust as needed. Actual hard cap is double this, but will never be reached due to hyperbolic curve. +#define BOMB_TARGET_SIZE 200 // The shockwave radius required for a bomb to get TECHWEB_BOMB_MIDPOINT points. +#define BOMB_SUB_TARGET_EXPONENT 2 // The power of the points curve below the target size. Higher = less points for worse bombs, below target. diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 6f5d2ebe57..7329dd653f 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -116,6 +116,11 @@ SUBSYSTEM_DEF(air) /datum/controller/subsystem/air/proc/auxtools_update_reactions() +/datum/controller/subsystem/air/proc/add_reaction(datum/gas_reaction/r) + gas_reactions += r + sortTim(gas_reactions, /proc/cmp_gas_reaction) + auxtools_update_reactions() + /proc/reset_all_air() SSair.can_fire = 0 message_admins("Air reset begun.") diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 3ff75495e6..27b591d374 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -194,22 +194,19 @@ GLOBAL_LIST_EMPTY(doppler_arrays) /*****The Point Calculator*****/ - if(orig_light < 10) + if(orig_light < 5) say("Explosion not large enough for research calculations.") return - else - point_gain = (100000 * orig_light) / (orig_light + 5000) + else if(orig_light < BOMB_TARGET_SIZE) // we want to give fewer points if below the target; this curve does that + point_gain = (BOMB_TARGET_POINTS * orig_light ** BOMB_SUB_TARGET_EXPONENT) / (BOMB_TARGET_SIZE**BOMB_SUB_TARGET_EXPONENT) + else // once we're at the target, switch to a hyperbolic function so we can't go too far above it, but bigger bombs always get more points + point_gain = (BOMB_TARGET_POINTS * 2 * orig_light) / (orig_light + BOMB_TARGET_SIZE) /*****The Point Capper*****/ if(point_gain > linked_techweb.largest_bomb_value) - if(point_gain <= TECHWEB_BOMB_POINTCAP || linked_techweb.largest_bomb_value < TECHWEB_BOMB_POINTCAP) - var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math - linked_techweb.largest_bomb_value = point_gain - point_gain -= old_tech_largest_bomb_value - point_gain = min(point_gain,TECHWEB_BOMB_POINTCAP) - else - linked_techweb.largest_bomb_value = TECHWEB_BOMB_POINTCAP - point_gain = 1000 + var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math + linked_techweb.largest_bomb_value = point_gain + point_gain -= old_tech_largest_bomb_value var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI) if(D) D.adjust_money(point_gain) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index b77e4a8ba0..ef798ae631 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -291,8 +291,8 @@ message_admins("Explosive tank rupture! Last key to touch the tank was [src.fingerprintslast].") log_game("Explosive tank rupture! Last key to touch the tank was [src.fingerprintslast].") //Give the gas a chance to build up more pressure through reacting - air_contents.react(src) - air_contents.react(src) + for(var/i in 1 to TANK_POST_FRAGMENT_REACTIONS) + air_contents.react(src) pressure = air_contents.return_pressure() var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm index 6faa3d55d6..8c9b1495c6 100644 --- a/code/modules/atmospherics/auxgm/gas_types.dm +++ b/code/modules/atmospherics/auxgm/gas_types.dm @@ -43,6 +43,7 @@ ) ) fusion_power = 3 + enthalpy = -393500 /datum/gas/plasma id = GAS_PLASMA @@ -54,7 +55,10 @@ heat_penalty = 15 transmit_modifier = 4 powermix = 1 - // no fire info cause it has its own bespoke reaction for trit generation reasons + fire_burn_rate = OXYGEN_BURN_RATE_BASE // named when plasma fires were the only fires, surely + fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + fire_products = "plasma_fire" + enthalpy = FIRE_PLASMA_ENERGY_RELEASED // 3000000, 3 megajoules, 3000 kj /datum/gas/water_vapor id = GAS_H2O @@ -64,6 +68,7 @@ moles_visible = MOLES_GAS_VISIBLE fusion_power = 8 heat_penalty = 8 + enthalpy = -241800 // FIRE_HYDROGEN_ENERGY_RELEASED is actually what this was supposed to be powermix = 1 breath_reagent = /datum/reagent/water @@ -84,6 +89,7 @@ fire_products = list(GAS_N2 = 1) oxidation_rate = 0.5 oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 + enthalpy = 81600 heat_resistance = 6 /datum/gas/nitryl @@ -95,8 +101,22 @@ flags = GAS_FLAG_DANGEROUS fusion_power = 15 fire_products = list(GAS_N2 = 0.5) + enthalpy = 33200 oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 +/datum/gas/hydrogen + id = GAS_HYDROGEN + specific_heat = 10 + name = "Hydrogen" + flags = GAS_FLAG_DANGEROUS + fusion_power = 0 + powermix = 1 + heat_penalty = 3 + transmit_modifier = 10 + fire_products = list(GAS_H2O = 2) + fire_burn_rate = 2 + fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + /datum/gas/tritium id = GAS_TRITIUM specific_heat = 10 @@ -108,13 +128,10 @@ powermix = 1 heat_penalty = 10 transmit_modifier = 30 - /* - these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons - fire_provides = list(GAS_H2O = 2) + fire_products = list(GAS_H2O = 2) fire_burn_rate = 2 - fire_energy_released = FIRE_HYDROGEN_ENERGY_RELEASED + fire_radiation_released = 50 // arbitrary number, basically 60 moles of trit burning will just barely start to harm you fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 - */ /datum/gas/bz id = GAS_BZ @@ -124,6 +141,7 @@ fusion_power = 8 powermix = 1 heat_penalty = 5 + enthalpy = FIRE_CARBON_ENERGY_RELEASED // it is a mystery transmit_modifier = -2 radioactivity_modifier = 5 @@ -139,7 +157,8 @@ name = "Pluoxium" fusion_power = 10 oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 1000 // it is VERY stable - oxidation_rate = 8 + oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT + enthalpy = -50000 // but it reduces the heat output a bit powermix = -1 heat_penalty = -1 transmit_modifier = -5 @@ -172,7 +191,7 @@ alert_type = /atom/movable/screen/alert/too_much_ch4 ) ) - fire_energy_released = FIRE_CARBON_ENERGY_RELEASED + enthalpy = -74600 fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST /datum/gas/methyl_bromide @@ -192,7 +211,28 @@ alert_type = /atom/movable/screen/alert/too_much_ch3br ) ) - fire_products = 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_products = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BROMINE = 0.5) + enthalpy = -35400 + fire_burn_rate = 4 / 7 // oh no fire_temperature = 808 // its autoignition, it apparently doesn't spark readily, so i don't put it lower + +/datum/gas/bromine + id = GAS_BROMINE + specific_heat = 76 + name = "Bromine" + flags = GAS_FLAG_DANGEROUS + group = GAS_GROUP_CHEMICALS + enthalpy = 193 // yeah it's small but it's good to include it + breath_reagent = /datum/reagent/bromine + +/datum/gas/ammonia + id = GAS_AMMONIA + specific_heat = 35 + name = "Ammonia" + flags = GAS_FLAG_DANGEROUS + group = GAS_GROUP_CHEMICALS + enthalpy = -45900 + breath_reagent = /datum/reagent/ammonia + fire_products = list(GAS_H2O = 1.5, GAS_N2 = 0.5) + fire_burn_rate = 4/3 + fire_temperature = 924 diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm index 4aa68aa710..2e5dd716ed 100644 --- a/code/modules/atmospherics/gasmixtures/auxgm.dm +++ b/code/modules/atmospherics/gasmixtures/auxgm.dm @@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA /proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas /datum/auxgm + var/done_initializing = FALSE var/list/datums = list() var/list/specific_heats = list() var/list/names = list() @@ -32,30 +33,34 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/list/oxidation_temperatures = list() var/list/oxidation_rates = list() var/list/fire_temperatures = list() - var/list/fire_enthalpies = list() + var/list/enthalpies = list() var/list/fire_products = list() var/list/fire_burn_rates = list() var/list/supermatter = list() - + var/list/groups_by_gas = list() + var/list/groups = list() /datum/gas var/id = "" var/specific_heat = 0 var/name = "" var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi + var/color = "#ffff" var/moles_visible = null var/flags = NONE //currently used by canisters + var/group = null // groups for scrubber/filter listing 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/datum/reagent/breath_reagent = null // what breathing this adds to your reagents + var/datum/reagent/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/enthalpy = 0 // Standard enthalpy of formation in joules, used for fires var/fire_burn_rate = 1 // how many moles are burned per product released + var/fire_radiation_released = 0 // How much radiation is released when this gas burns var/powermix = 0 // how much this gas contributes to the supermatter's powermix ratio var/heat_penalty = 0 // heat and waste penalty from having the supermatter crystal surrounded by this gas; negative numbers reduce var/transmit_modifier = 0 // bonus to supermatter power generation (multiplicative, since it's % based, and divided by 10) @@ -94,21 +99,31 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA 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 + enthalpies[g] = gas.enthalpy 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 + enthalpies[g] = gas.enthalpy + if(gas.group) + if(!(gas.group in groups)) + groups[gas.group] = list() + groups[gas.group] += gas + groups_by_gas[g] = gas.group add_supermatter_properties(gas) _auxtools_register_gas(gas) + if(done_initializing) + for(var/r in SSair.gas_reactions) + var/datum/gas_reaction/R = r + R.init_reqs() + SSair.auxtools_update_reactions() + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_GAS, g) /proc/finalize_gas_refs() @@ -127,6 +142,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA for(var/breathing_class_path in subtypesof(/datum/breathing_class)) var/datum/breathing_class/class = new breathing_class_path breathing_classes[breathing_class_path] = class + done_initializing = TRUE finalize_gas_refs() diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 19cd865bd0..a6429a0754 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -53,23 +53,68 @@ id = "vapor" /datum/gas_reaction/water_vapor/init_reqs() - min_requirements = list(GAS_H2O = MOLES_GAS_VISIBLE) + min_requirements = list( + GAS_H2O = MOLES_GAS_VISIBLE, + "MAX_TEMP" = T0C + 40 + ) /datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder) - var/turf/open/location = isturf(holder) ? holder : null - . = NO_REACTION + var/turf/open/location = holder + if(!istype(location)) + return NO_REACTION if (air.return_temperature() <= WATER_VAPOR_FREEZE) if(location && location.freon_gas_act()) - . = REACTING + return REACTING else if(location && location.water_vapor_gas_act()) air.adjust_moles(GAS_H2O,-MOLES_GAS_VISIBLE) - . = REACTING + return REACTING // no test cause it's entirely based on location +/datum/gas_reaction/condensation + priority = 0 + name = "Condensation" + id = "condense" + exclude = TRUE + var/datum/reagent/condensing_reagent + +/datum/gas_reaction/condensation/New(datum/reagent/R) + . = ..() + if(!istype(R)) + return + min_requirements = list( + "MAX_TEMP" = initial(R.boiling_point) + ) + min_requirements[R.get_gas()] = MOLES_GAS_VISIBLE + name = "[R.name] condensation" + id = "[R.type] condensation" + condensing_reagent = R + exclude = FALSE + +/datum/gas_reaction/condensation/react(datum/gas_mixture/air, datum/holder) + . = NO_REACTION + var/turf/open/location = holder + if(!istype(location)) + return + var/temperature = air.return_temperature() + var/static/datum/reagents/reagents_holder = new + reagents_holder.clear_reagents() + reagents_holder.chem_temp = temperature + var/G = condensing_reagent.get_gas() + var/amt = air.get_moles(G) + air.adjust_moles(G, -min(initial(condensing_reagent.condensation_amount), amt)) + reagents_holder.add_reagent(condensing_reagent, amt) + . = REACTING + for(var/atom/movable/AM in location) + if(location.intact && AM.level == 1) + continue + reagents_holder.reaction(AM, TOUCH) + reagents_holder.reaction(location, TOUCH) + //tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic /datum/gas_reaction/tritfire priority = -1 //fire should ALWAYS be last, but tritium fires happen before plasma fires + exclude = TRUE // generic fire now takes care of this name = "Tritium Combustion" id = "tritfire" @@ -88,9 +133,9 @@ item.temperature_expose(air, temperature, CELL_VOLUME) location.temperature_expose(air, temperature, CELL_VOLUME) -/proc/radiation_burn(turf/open/location, energy_released) +/proc/radiation_burn(turf/open/location, rad_power) if(istype(location) && prob(10)) - radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR) + radiation_pulse(location, rad_power) /datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder) var/energy_released = 0 @@ -151,6 +196,7 @@ /datum/gas_reaction/plasmafire priority = -2 //fire should ALWAYS be last, but plasma fires happen after tritium fires name = "Plasma Combustion" + exclude = TRUE // generic fire now takes care of this id = "plasmafire" /datum/gas_reaction/plasmafire/init_reqs() @@ -300,7 +346,7 @@ fuels[fuel] *= oxidation_ratio fuels += oxidizers var/list/fire_products = GLOB.gas_data.fire_products - var/list/fire_enthalpies = GLOB.gas_data.fire_enthalpies + var/list/fire_enthalpies = GLOB.gas_data.enthalpies for(var/fuel in fuels + oxidizers) var/amt = fuels[fuel] if(!burn_results[fuel]) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 2313d9c71d..5ea4be80cb 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -535,7 +535,7 @@ for(var/device_id in A.air_scrub_names) send_signal(device_id, list( "power" = 1, - "set_filters" = list(GAS_CO2, GAS_MIASMA), + "set_filters" = list(GAS_CO2, GAS_MIASMA, GAS_GROUP_CHEMICALS), "scrubbing" = 1, "widenet" = 0, )) @@ -554,6 +554,7 @@ GAS_MIASMA, GAS_PLASMA, GAS_H2O, + GAS_HYDROGEN, GAS_HYPERNOB, GAS_NITROUS, GAS_NITRYL, @@ -562,7 +563,8 @@ GAS_STIMULUM, GAS_PLUOXIUM, GAS_METHANE, - GAS_METHYL_BROMIDE + GAS_METHYL_BROMIDE, + GAS_GROUP_CHEMICALS ), "scrubbing" = 1, "widenet" = 1, @@ -582,9 +584,16 @@ )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 1, "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE*2 + "set_external_pressure" = ONE_ATMOSPHERE*1.4 + )) + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE/1.4 )) if(AALARM_MODE_REFILL) for(var/device_id in A.air_scrub_names) @@ -596,10 +605,15 @@ )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 1, "checks" = 1, "set_external_pressure" = ONE_ATMOSPHERE * 3 )) + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 0, + )) if(AALARM_MODE_PANIC, AALARM_MODE_REPLACEMENT) for(var/device_id in A.air_scrub_names) @@ -610,8 +624,14 @@ )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 0 )) + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 1, + "checks" = 0 + )) if(AALARM_MODE_SIPHON) for(var/device_id in A.air_scrub_names) send_signal(device_id, list( @@ -621,9 +641,14 @@ )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 0 )) - + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 1, + "checks" = 0 + )) if(AALARM_MODE_OFF) for(var/device_id in A.air_scrub_names) send_signal(device_id, list( @@ -641,8 +666,12 @@ for(var/device_id in A.air_vent_names) send_signal(device_id, list( "power" = 1, - "checks" = 2, - "set_internal_pressure" = 0 + "checks" = 0, + "is_pressurizing" = 1 + )) + send_signal(device_id, list( + "power" = 0, + "is_siphoning" = 1 )) /obj/machinery/airalarm/update_icon_state() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 4182f5ceca..b6d03bd0a7 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -100,7 +100,10 @@ if(transfer_ratio > 0) if(filter_type && air2.return_pressure() <= 9000) - air1.scrub_into(air2, transfer_ratio, list(filter_type)) + if(filter_type in GLOB.gas_data.groups) + air1.scrub_into(air2, transfer_ratio, GLOB.gas_data.groups[filter_type]) + else + air1.scrub_into(air2, transfer_ratio, list(filter_type)) if(air3.return_pressure() <= 9000) air1.transfer_ratio_to(air3, transfer_ratio) @@ -125,8 +128,10 @@ data["filter_types"] = list() data["filter_types"] += list(list("name" = "Nothing", "id" = "", "selected" = !filter_type)) for(var/id in GLOB.gas_data.ids) - data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type))) - + if(!(id in GLOB.gas_data.groups_by_gas)) + data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type))) + for(var/group in GLOB.gas_data.groups) + data["filter_types"] += list(list("name" = group, "id" = group, "selected" = (group == filter_type))) return data /obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index a3644ed084..deafe7a9f0 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -178,6 +178,9 @@ var/mob/signal_sender = signal.data["user"] + if((("is_siphoning" in signal.data) && pump_direction == RELEASING) || (("is_pressurizing" in signal.data) && pump_direction == SIPHONING)) + return + if("purge" in signal.data) pressure_checks &= ~EXT_BOUND pump_direction = SIPHONING diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 90d5f077a5..098618bc65 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -18,7 +18,8 @@ var/id_tag = null var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing - var/filter_types = list(GAS_CO2) + var/filter_types = list(GAS_CO2, GAS_MIASMA, GAS_GROUP_CHEMICALS) + var/list/clean_filter_types = null var/volume_rate = 200 var/widenet = 0 //is this scrubber acting on the 3x3 area around it. var/list/turf/adjacent_turfs = list() @@ -34,6 +35,16 @@ ..() if(!id_tag) id_tag = assign_uid_vents() + generate_clean_filter_types() + RegisterSignal(SSdcs,COMSIG_GLOB_NEW_GAS,.proc/generate_clean_filter_types) + +/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/generate_clean_filter_types() + clean_filter_types = list() + for(var/id in filter_types) + if(id in GLOB.gas_data.groups) + clean_filter_types += GLOB.gas_data.groups[id] + else + clean_filter_types += id /obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy() var/area/A = get_base_area(src) @@ -95,7 +106,11 @@ var/list/f_types = list() for(var/id in GLOB.gas_data.ids) - f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types))) + if(!(id in GLOB.gas_data.groups_by_gas)) + f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types))) + + for(var/group in GLOB.gas_data.groups) + f_types += list(list("gas_id" = group, "gas_name" = group, "enabled" = (group in filter_types))) var/datum/signal/signal = new(list( "tag" = id_tag, @@ -147,11 +162,11 @@ var/datum/gas_mixture/environment = tile.return_air() var/datum/gas_mixture/air_contents = airs[1] - if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(filter_types)) + if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(clean_filter_types)) return FALSE if(scrubbing & SCRUBBING) - environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types) + environment.scrub_into(air_contents, volume_rate/environment.return_volume(), clean_filter_types) tile.air_update_turf() @@ -205,11 +220,13 @@ if("toggle_filter" in signal.data) filter_types ^= signal.data["toggle_filter"] + generate_clean_filter_types() if("set_filters" in signal.data) filter_types = list() for(var/gas in signal.data["set_filters"]) filter_types += gas + generate_clean_filter_types() if("init" in signal.data) name = signal.data["init"] diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 7c563b3cb1..2899f0ca11 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -825,7 +825,7 @@ pH = REAGENT_NORMAL_PH return 0 -/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1) +/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1, from_gas = 0) var/react_type if(isliving(A)) react_type = "LIVING" @@ -849,7 +849,7 @@ touch_protection = L.get_permeability_protection() R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection) if("TURF") - R.reaction_turf(A, R.volume * volume_modifier, show_message) + R.reaction_turf(A, R.volume * volume_modifier, show_message, from_gas) if("OBJ") R.reaction_obj(A, R.volume * volume_modifier, show_message) @@ -859,17 +859,16 @@ return FALSE //Returns the average specific heat for all reagents currently in this holder. -/datum/reagents/proc/specific_heat() +/datum/reagents/proc/heat_capacity() . = 0 - var/cached_amount = total_volume //cache amount var/list/cached_reagents = reagent_list //cache reagents for(var/I in cached_reagents) var/datum/reagent/R = I - . += R.specific_heat * (R.volume / cached_amount) + . += R.specific_heat * R.volume /datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000) - var/S = specific_heat() - chem_temp = clamp(chem_temp + (J / (S * total_volume)), min_temp, max_temp) + var/S = heat_capacity() + chem_temp = clamp(chem_temp + (J / S), min_temp, max_temp) if(istype(my_atom, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RC = my_atom RC.temp_check() diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index b2978f3066..128c4ed3cb 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -390,11 +390,11 @@ var/datum/reagent/R = GLOB.chemical_reagents_list[reagent] if(R) var/state = "Unknown" - if(initial(R.reagent_state) == 1) + if(initial(R.reagent_state) == SOLID) state = "Solid" - else if(initial(R.reagent_state) == 2) + else if(initial(R.reagent_state) == LIQUID) state = "Liquid" - else if(initial(R.reagent_state) == 3) + else if(initial(R.reagent_state) == GAS) state = "Gas" var/const/P = 3 //The number of seconds between life ticks var/T = initial(R.metabolization_rate) * (60 / P) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index fecb9e3dbf..9845903e21 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -53,6 +53,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/chemical_flags = REAGENT_ORGANIC_PROCESS // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME, REAGENT_ORGANIC_PROCESS, REAGENT_ROBOTIC_PROCESS var/value = REAGENT_VALUE_NONE //How much does it sell for in cargo? var/datum/material/material //are we made of material? + var/gas = null //do we have an associated gas? (expects a string, not a datum typepath!) + var/boiling_point = null // point at which this gas boils; if null, will never boil (and thus not become a gas) + var/condensation_amount = 1 + var/molarity = 5 // How many units per mole of this reagent. Technically this is INVERSE molarity, but hey. /datum/reagent/New() . = ..() @@ -77,10 +81,23 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) return 1 /datum/reagent/proc/reaction_obj(obj/O, volume) - return + if(O && volume && boiling_point) + var/temp = holder ? holder.chem_temp : T20C + if(temp > boiling_point) + O.atmos_spawn_air("[get_gas()]=[volume/molarity];TEMP=[temp]") -/datum/reagent/proc/reaction_turf(turf/T, volume) - return +/datum/reagent/proc/reaction_turf(turf/T, volume, show_message, from_gas) + if(!from_gas && boiling_point) + var/temp = holder?.chem_temp + if(!temp) + if(isopenturf(T)) + var/turf/open/O = T + var/datum/gas_mixture/air = O.return_air() + temp = air.return_temperature() + else + temp = T20C + if(temp > boiling_point) + T.atmos_spawn_air("[get_gas()]=[volume/molarity];TEMP=[temp]") /datum/reagent/proc/on_mob_life(mob/living/carbon/M) current_cycle++ @@ -235,6 +252,44 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) return rs.Join(" | ") +/datum/reagent/proc/define_gas() + if(reagent_state == SOLID) + return null // doesn't make that much sense + var/list/cached_reactions = GLOB.chemical_reactions_list + for(var/reaction in cached_reactions[src.type]) + var/datum/chemical_reaction/C = reaction + if(!istype(C)) + continue + if(C.required_reagents.len < 2) // no reagents that react on their own + return null + var/datum/gas/G = new + G.id = "[src.type]" + G.name = name + G.specific_heat = specific_heat / 10 + G.color = color + G.breath_reagent = src.type + G.group = GAS_GROUP_CHEMICALS + return G + +/datum/reagent/proc/create_gas() + var/datum/gas/G = define_gas() + if(istype(G)) // if this reagent should never be a gas, define_gas may return null + GLOB.gas_data.add_gas(G) + var/datum/gas_reaction/condensation/condensation_reaction = new(src) // did you know? you can totally just add new reactions at runtime. it's allowed + SSair.add_reaction(condensation_reaction) + return G + + +/datum/reagent/proc/get_gas() + if(gas) + return gas + else + var/datum/auxgm/cached_gas_data = GLOB.gas_data + . = "[src.type]" + if(!(. in cached_gas_data.ids)) + create_gas() + + //For easy bloodsucker disgusting and blood removal /datum/reagent/proc/disgust_bloodsucker(mob/living/carbon/C, disgust, blood_change, blood_puke = TRUE, force) if(AmBloodsucker(C)) diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 2f8ab6b8e6..04dc8a0d26 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -14,6 +14,7 @@ taste_description = "alcohol" var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning pH = 7.33 + boiling_point = 351.38 value = REAGENT_VALUE_VERY_COMMON //don't bother tweaking all drinks values, way too many can easily be done roundstart or with an upgraded dispenser. /* @@ -85,6 +86,31 @@ All effects don't start immediately, but rather get worse over time; the rate is // +10% success propability on each step, useful while operating in less-than-perfect conditions return ..() +/datum/reagent/consumable/ethanol/define_gas() // So that all alcohols have the same gas, i.e. "ethanol" + var/datum/gas/G = new + G.id = GAS_ETHANOL + G.name = "Ethanol" + G.enthalpy = -234800 + G.specific_heat = 38 + G.fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5) + G.fire_burn_rate = 1 / 3 + G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + G.color = "#404030" + G.breath_reagent = /datum/reagent/consumable/ethanol + G.group = GAS_GROUP_CHEMICALS + return G + +/datum/reagent/consumable/ethanol/get_gas() + var/datum/auxgm/cached_gas_data = GLOB.gas_data + . = GAS_ETHANOL + if(!(. in cached_gas_data.ids)) + var/datum/gas/G = define_gas() + if(istype(G)) + cached_gas_data.add_gas(G) + else // this codepath should probably not happen at all, since we never use get_gas() on anything with no boiling point + return null + + /datum/reagent/consumable/ethanol/beer name = "Beer" description = "An alcoholic beverage brewed since ancient times on Old Earth. Still popular today." diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 26d248169a..ec628255fa 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -909,20 +909,11 @@ description = "A colorless, odorless gas. Grows on trees but is still pretty valuable." reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 + gas = GAS_O2 + boiling_point = 90.188 taste_mult = 0 // oderless and tasteless pH = 9.2//It's acutally a huge range and very dependant on the chemistry but pH is basically a made up var in it's implementation anyways - -/datum/reagent/oxygen/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]") - -/datum/reagent/oxygen/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]") - return + molarity = 2 /datum/reagent/copper name = "Copper" @@ -943,26 +934,18 @@ name = "Nitrogen" description = "A colorless, odorless, tasteless gas. A simple asphyxiant that can silently displace vital oxygen." reagent_state = GAS + gas = GAS_N2 + boiling_point = 77.355 color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 - - -/datum/reagent/nitrogen/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]") - -/datum/reagent/nitrogen/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]") - return + molarity = 2 /datum/reagent/hydrogen name = "Hydrogen" description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas." reagent_state = GAS + gas = GAS_HYDROGEN + boiling_point = 20.271 color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 pH = 0.1//Now I'm stuck in a trap of my own design. Maybe I should make -ve pHes? (not 0 so I don't get div/0 errors) @@ -1015,9 +998,10 @@ name = "Chlorine" description = "A pale yellow gas that's well known as an oxidizer. While it forms many harmless molecules in its elemental form it is far from harmless." reagent_state = GAS - color = "#808080" // rgb: 128, 128, 128 + color = "#c0c0a0" // rgb: 192, 192, 160 taste_description = "chlorine" pH = 7.4 + boiling_point = 239.11 // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial /datum/reagent/chlorine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user) @@ -1291,7 +1275,15 @@ glass_name = "glass of welder fuel" glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption." pH = 4 + boiling_point = 400 +/datum/reagent/fuel/define_gas() + var/datum/gas/G = ..() + G.enthalpy = 227400 + G.fire_burn_rate = 2 / 5 + G.fire_products = list(GAS_CO2 = 2, GAS_H2O = 1) + G.fire_temperature = T0C+300 + return G /datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite! if(method == TOUCH || method == VAPOR) @@ -1309,6 +1301,7 @@ description = "A compound used to clean things. Now with 50% more sodium hypochlorite!" color = "#A5F0EE" // rgb: 165, 240, 238 taste_description = "sourness" + boiling_point = T0C+50 pH = 5.5 /datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume) @@ -1321,6 +1314,7 @@ O.clean_blood() /datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume) + ..() if(reac_volume >= 1) T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) @@ -1488,6 +1482,7 @@ name = "Ammonia" description = "A caustic substance commonly used in fertilizer or household cleaners." reagent_state = GAS + gas = GAS_AMMONIA color = "#404030" // rgb: 64, 64, 48 taste_description = "mordant" pH = 11.6 @@ -1506,8 +1501,17 @@ description = "A secondary amine, mildly corrosive." color = "#604030" // rgb: 96, 64, 48 taste_description = "iron" + boiling_point = 328 pH = 12 +/datum/reagent/diethylamine/define_gas() + var/datum/gas/G = ..() + G.fire_burn_rate = 1 / 6 + G.fire_products = list(GAS_H2O = 4, GAS_AMMONIA = 1, GAS_CO2 = 4) + G.enthalpy = -131000 + G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + return G + // This is more bad ass, and pests get hurt by the corrosive nature of it, not the plant. The new trade off is it culls stability. /datum/reagent/diethylamine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user) . = ..() @@ -1524,40 +1528,23 @@ description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs." color = "#B0B0B0" // rgb : 192, 192, 192 taste_description = "something unknowable" + boiling_point = 195.68 // technically sublimation, not boiling, but same deal + molarity = 5 + gas = GAS_CO2 pH = 6 -/datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]") - -/datum/reagent/carbondioxide/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]") - return - /datum/reagent/nitrous_oxide name = "Nitrous Oxide" description = "A potent oxidizer used as fuel in rockets and as an anaesthetic during surgery." reagent_state = LIQUID metabolization_rate = 1.5 * REAGENTS_METABOLISM color = "#808080" + boiling_point = 184.67 + molarity = 5 + gas = GAS_NITROUS taste_description = "sweetness" pH = 5.8 -/datum/reagent/nitrous_oxide/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]") - -/datum/reagent/nitrous_oxide/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]") - /datum/reagent/nitrous_oxide/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == VAPOR) M.drowsyness += max(round(reac_volume, 1), 2) @@ -1576,9 +1563,11 @@ name = "Stimulum" description = "An unstable experimental gas that greatly increases the energy of those that inhale it" reagent_state = GAS + gas = GAS_STIMULUM metabolization_rate = 1.5 * REAGENTS_METABOLISM chemical_flags = REAGENT_ALL_PROCESS color = "E1A116" + boiling_point = 150 taste_description = "sourness" value = REAGENT_VALUE_EXCEPTIONAL @@ -1602,9 +1591,11 @@ name = "Nitryl" description = "A highly reactive gas that makes you feel faster" reagent_state = GAS + gas = GAS_NITRYL metabolization_rate = REAGENTS_METABOLISM - color = "90560B" + color = "#90560B" taste_description = "burning" + boiling_point = 294.3 pH = 2 value = REAGENT_VALUE_VERY_RARE @@ -1811,6 +1802,8 @@ reagent_state = LIQUID color = "#b37740" taste_description = "chemicals" + gas = GAS_BROMINE + boiling_point = 332 pH = 7.8 /datum/reagent/phenol @@ -2482,6 +2475,7 @@ var/decal_path = /obj/effect/decal/cleanable/semen /datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume) + ..() if(!istype(T)) return if(reac_volume < 10) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index 94b83bdeca..f2157a619e 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -47,6 +47,10 @@ metabolization_rate = 4 chemical_flags = REAGENT_ALL_PROCESS taste_description = "burning" + /* no gaseous CLF3 until i can think of a good way to get it to burn that doesn't destroy matter in mysterious ways + boiling_point = 289.4 + */ + condensation_amount = 2 value = REAGENT_VALUE_COMMON /datum/reagent/clf3/on_mob_life(mob/living/carbon/M) @@ -84,6 +88,12 @@ if(!locate(/obj/effect/hotspot) in M.loc) new /obj/effect/hotspot(M.loc) +/datum/reagent/clf3/define_gas() + var/datum/gas/G = ..() + G.enthalpy = -163200 + G.oxidation_temperature = T0C - 50 + return G + /datum/reagent/sorium name = "Sorium" description = "Sends everything flying from the detonation point." @@ -152,8 +162,17 @@ reagent_state = LIQUID color = "#FA00AF" taste_description = "burning" + boiling_point = T20C-10 value = REAGENT_VALUE_UNCOMMON +/datum/reagent/phlogiston/define_gas() + var/datum/gas/G = ..() + G.enthalpy = FIRE_PLASMA_ENERGY_RELEASED / 100 + G.fire_products = list(GAS_O2 = 0.25, GAS_METHANE = 0.75) // meanwhile this is just magic + G.fire_burn_rate = 1 + G.fire_temperature = T20C+1 + return G + /datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, reac_volume) M.adjust_fire_stacks(1) var/burndmg = max(0.3*M.fire_stacks, 0.3) @@ -288,6 +307,9 @@ taste_description = "the inside of a fire extinguisher" value = REAGENT_VALUE_UNCOMMON +/datum/reagent/firefighting_foam/define_gas() + return null + /datum/reagent/firefighting_foam/reaction_turf(turf/open/T, reac_volume) if (!istype(T)) return diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 2b212bd224..cbb46242c3 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -248,7 +248,7 @@ 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)) + H.reagents.add_reagent(R, breath.get_moles(gas) * initial(R.molarity)) mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - breath.get_moles(gas) : -breath.get_moles(gas) for(var/gas in mole_adjustments) diff --git a/code/modules/unit_tests/reactions.dm b/code/modules/unit_tests/reactions.dm index 66d9b49099..c2b62f6fdc 100644 --- a/code/modules/unit_tests/reactions.dm +++ b/code/modules/unit_tests/reactions.dm @@ -1,6 +1,7 @@ /datum/unit_test/reactions/Run() for(var/datum/gas_reaction/G in SSair.gas_reactions) - var/test_info = G.test() - if(!test_info["success"]) - var/message = test_info["message"] - Fail("Gas reaction [G.name] is failing its unit test with the following message: [message]") + if(!G.exclude) + var/test_info = G.test() + if(!test_info["success"]) + var/message = test_info["message"] + Fail("Gas reaction [G.name] is failing its unit test with the following message: [message]") diff --git a/dependencies.sh b/dependencies.sh index aca82a3a05..4474cc8736 100644 --- a/dependencies.sh +++ b/dependencies.sh @@ -21,7 +21,7 @@ export SPACEMAN_DMM_VERSION=suite-1.7 export PYTHON_VERSION=3.6.8 # Auxmos git tag -export AUXMOS_VERSION=v0.2.3 +export AUXMOS_VERSION=v0.3.0 # Extools git tag export EXTOOLS_VERSION=v0.0.7