Merge pull request #6822 from Citadel-Station-13/upstream-merge-37600

[MIRROR] Refactors hydrocarbon combustion + other general atmos code changes
This commit is contained in:
LetterJay
2018-05-21 08:29:16 -05:00
committed by GitHub
4 changed files with 106 additions and 66 deletions
+2 -1
View File
@@ -29,7 +29,8 @@ SUBSYSTEM_DEF(air)
var/list/obj/machinery/atmos_machinery = list() var/list/obj/machinery/atmos_machinery = list()
var/list/pipe_init_dirs_cache = list() var/list/pipe_init_dirs_cache = list()
//atmos singletons
var/list/gas_reactions = list()
//Special functions lists //Special functions lists
var/list/turf/active_super_conductivity = list() var/list/turf/active_super_conductivity = list()
@@ -4,11 +4,11 @@ What are the archived variables for?
This prevents race conditions that arise based on the order of tile processing. This prevents race conditions that arise based on the order of tile processing.
*/ */
#define MINIMUM_HEAT_CAPACITY 0.0003 #define MINIMUM_HEAT_CAPACITY 0.0003
#define MINIMUM_MOLE_COUNT 0.01
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that #define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide))) // These gasses cannot react amongst themselves
/proc/init_gaslist_cache() /proc/init_gaslist_cache()
. = list() . = list()
@@ -1,4 +1,5 @@
GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded
GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/pluoxium, /datum/gas/stimulum, /datum/gas/nitryl))) //unable to react amongst themselves
/proc/meta_gas_list() /proc/meta_gas_list()
. = subtypesof(/datum/gas) . = subtypesof(/datum/gas)
@@ -124,6 +125,7 @@ GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /
specific_heat = 80 specific_heat = 80
name = "Pluoxium" name = "Pluoxium"
fusion_power = 10 fusion_power = 10
/obj/effect/overlay/gas /obj/effect/overlay/gas
icon = 'icons/effects/tile_effects.dmi' icon = 'icons/effects/tile_effects.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT mouse_opacity = MOUSE_OPACITY_TRANSPARENT
@@ -30,7 +30,6 @@
#define FUSION_PURITY_THRESHOLD 0.95 #define FUSION_PURITY_THRESHOLD 0.95
#define FUSION_HEAT_DROPOFF (20000+T0C) #define FUSION_HEAT_DROPOFF (20000+T0C)
#define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense. #define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense.
/datum/controller/subsystem/air/var/list/gas_reactions //this is our singleton of all reactions
/proc/init_gas_reactions() /proc/init_gas_reactions()
var/list/reaction_types = list() var/list/reaction_types = list()
@@ -49,7 +48,7 @@
/datum/gas_reaction /datum/gas_reaction
//regarding the requirements lists: the minimum or maximum requirements must be non-zero. //regarding the requirements lists: the minimum or maximum requirements must be non-zero.
//when in doubt, use MINIMUM_HEAT_CAPACITY. //when in doubt, use MINIMUM_MOLE_COUNT.
var/list/min_requirements var/list/min_requirements
var/list/max_requirements var/list/max_requirements
var/exclude = FALSE //do it this way to allow for addition/removal of reactions midmatch in the future var/exclude = FALSE //do it this way to allow for addition/removal of reactions midmatch in the future
@@ -61,6 +60,7 @@
init_reqs() init_reqs()
/datum/gas_reaction/proc/init_reqs() /datum/gas_reaction/proc/init_reqs()
/datum/gas_reaction/proc/react(datum/gas_mixture/air, atom/location) /datum/gas_reaction/proc/react(datum/gas_mixture/air, atom/location)
return NO_REACTION return NO_REACTION
@@ -94,16 +94,20 @@
air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_GAS_VISIBLE air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_GAS_VISIBLE
. = REACTING . = REACTING
//fire: combustion of plasma and volatile fuel (treated as hydrocarbons). creates hotspots. exothermic //tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
/datum/gas_reaction/fire /datum/gas_reaction/tritfire
priority = -1 //fire should ALWAYS be last priority = -1 //fire should ALWAYS be last, but tritium fires happen before plasma fires
name = "Hydrocarbon Combustion" name = "Tritium Combustion"
id = "fire" id = "tritfire"
/datum/gas_reaction/fire/init_reqs() /datum/gas_reaction/tritfire/init_reqs()
min_requirements = list("TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST) //doesn't include plasma reqs b/c of other, rarer, burning gases. min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
/datum/gas/tritium = MINIMUM_MOLE_COUNT,
/datum/gas/oxygen = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/fire/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0 var/energy_released = 0
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow
@@ -112,65 +116,99 @@
cached_results[id] = 0 cached_results[id] = 0
var/turf/open/location = isturf(holder) ? holder : null var/turf/open/location = isturf(holder) ? holder : null
//General volatile gas burn var/burned_fuel = 0
if(cached_gases[/datum/gas/tritium] && cached_gases[/datum/gas/tritium][MOLES]) if(cached_gases[/datum/gas/oxygen][MOLES] < cached_gases[/datum/gas/tritium][MOLES])
var/burned_fuel burned_fuel = cached_gases[/datum/gas/oxygen][MOLES]/TRITIUM_BURN_OXY_FACTOR
if(!cached_gases[/datum/gas/oxygen]) cached_gases[/datum/gas/tritium][MOLES] -= burned_fuel
burned_fuel = 0 else
else if(cached_gases[/datum/gas/oxygen][MOLES] < cached_gases[/datum/gas/tritium][MOLES]) burned_fuel = cached_gases[/datum/gas/tritium][MOLES]*TRITIUM_BURN_TRIT_FACTOR
burned_fuel = cached_gases[/datum/gas/oxygen][MOLES]/TRITIUM_BURN_OXY_FACTOR cached_gases[/datum/gas/tritium][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]/TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/tritium][MOLES] -= burned_fuel cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]
else
burned_fuel = cached_gases[/datum/gas/tritium][MOLES]*TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/tritium][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]/TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]
if(burned_fuel) if(burned_fuel)
energy_released += FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel energy_released += FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR) radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
ASSERT_GAS(/datum/gas/water_vapor, air) //oxygen+more-or-less hydrogen=H2O ASSERT_GAS(/datum/gas/water_vapor, air) //oxygen+more-or-less hydrogen=H2O
cached_gases[/datum/gas/water_vapor][MOLES] += burned_fuel/TRITIUM_BURN_OXY_FACTOR cached_gases[/datum/gas/water_vapor][MOLES] += burned_fuel/TRITIUM_BURN_OXY_FACTOR
cached_results[id] += burned_fuel cached_results[id] += burned_fuel
if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
//let the floor know a fire is happening
if(istype(location))
temperature = air.temperature
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location)
var/atom/movable/item = I
item.temperature_expose(air, temperature, CELL_VOLUME)
location.temperature_expose(air, temperature, CELL_VOLUME)
return cached_results[id] ? REACTING : NO_REACTION
//plasma combustion: combustion of oxygen and plasma (treated as hydrocarbons). creates hotspots. exothermic
/datum/gas_reaction/plasmafire
priority = -2 //fire should ALWAYS be last, but plasma fires happen after tritium fires
name = "Plasma Combustion"
id = "plasmafire"
/datum/gas_reaction/plasmafire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
/datum/gas/plasma = MINIMUM_MOLE_COUNT,
/datum/gas/oxygen = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
var/old_heat_capacity = air.heat_capacity()
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow
var/temperature = air.temperature
var/list/cached_results = air.reaction_results
cached_results[id] = 0
var/turf/open/location = isturf(holder) ? holder : null
//Handle plasma burning //Handle plasma burning
if(cached_gases[/datum/gas/plasma] && cached_gases[/datum/gas/plasma][MOLES] > MINIMUM_HEAT_CAPACITY) var/plasma_burn_rate = 0
var/plasma_burn_rate = 0 var/oxygen_burn_rate = 0
var/oxygen_burn_rate = 0 //more plasma released at higher temperatures
//more plasma released at higher temperatures var/temperature_scale = 0
var/temperature_scale //to make tritium
var/super_saturation var/super_saturation = FALSE
if(temperature > PLASMA_UPPER_TEMPERATURE)
temperature_scale = 1 if(temperature > PLASMA_UPPER_TEMPERATURE)
temperature_scale = 1
else
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(cached_gases[/datum/gas/oxygen][MOLES] / cached_gases[/datum/gas/plasma][MOLES] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
super_saturation = TRUE
if(cached_gases[/datum/gas/oxygen][MOLES] > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
else else
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(temperature_scale > 0)
var/o2 = cached_gases[/datum/gas/oxygen] ? cached_gases[/datum/gas/oxygen][MOLES] : 0 if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/oxygen][MOLES]/oxygen_burn_rate) //Ensures matter is conserved properly
if(o2 / cached_gases[/datum/gas/plasma][MOLES] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium. cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate)
super_saturation = TRUE cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
if(o2 > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN) if (super_saturation)
plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA ASSERT_GAS(/datum/gas/tritium,air)
cached_gases[/datum/gas/tritium][MOLES] += plasma_burn_rate
else else
plasma_burn_rate = (temperature_scale*(o2/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA ASSERT_GAS(/datum/gas/carbon_dioxide,air)
cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
ASSERT_GAS(/datum/gas/carbon_dioxide, air) //don't need to assert o2, since if it isn't present we'll never reach this point anyway
plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/oxygen][MOLES]/oxygen_burn_rate) //Ensures matter is conserved properly
cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate)
cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
if (super_saturation)
ASSERT_GAS(/datum/gas/tritium,air)
cached_gases[/datum/gas/tritium][MOLES] += plasma_burn_rate
else
ASSERT_GAS(/datum/gas/carbon_dioxide,air)
cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) cached_results[id] += (plasma_burn_rate)*(1+oxygen_burn_rate)
cached_results[id] += (plasma_burn_rate)*(1+oxygen_burn_rate)
if(energy_released > 0) if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
@@ -196,7 +234,6 @@
name = "Plasmic Fusion" name = "Plasmic Fusion"
id = "fusion" id = "fusion"
/datum/gas_reaction/fusion/init_reqs() /datum/gas_reaction/fusion/init_reqs()
min_requirements = list( min_requirements = list(
"ENER" = PLASMA_BINDING_ENERGY * 1000, "ENER" = PLASMA_BINDING_ENERGY * 1000,
@@ -361,7 +398,7 @@
air.temperature = max(((air.temperature*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB) air.temperature = max(((air.temperature*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB)
return REACTING return REACTING
/datum/gas_reaction/nobliumformation //Hyper-Nobelium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic. /datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic.
priority = 6 priority = 6
name = "Hyper-Noblium condensation" name = "Hyper-Noblium condensation"
id = "nobformation" id = "nobformation"
@@ -380,8 +417,8 @@
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz][MOLES],1))) var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz][MOLES],1)))
if ((cached_gases[/datum/gas/tritium][MOLES] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen][MOLES] - 20*nob_formed < 0)) if ((cached_gases[/datum/gas/tritium][MOLES] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen][MOLES] - 20*nob_formed < 0))
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/tritium][MOLES] = max(cached_gases[/datum/gas/tritium][MOLES]- 10*nob_formed,0) cached_gases[/datum/gas/tritium][MOLES] -= 10*nob_formed
cached_gases[/datum/gas/nitrogen][MOLES] = max(cached_gases[/datum/gas/nitrogen][MOLES]- 20*nob_formed,0) cached_gases[/datum/gas/nitrogen][MOLES] -= 20*nob_formed
cached_gases[/datum/gas/hypernoblium][MOLES]+= nob_formed cached_gases[/datum/gas/hypernoblium][MOLES]+= nob_formed