diff --git a/code/__DEFINES/atmospherics/atmos_core.dm b/code/__DEFINES/atmospherics/atmos_core.dm index c0ca6bb78c8..8105920ecd7 100644 --- a/code/__DEFINES/atmospherics/atmos_core.dm +++ b/code/__DEFINES/atmospherics/atmos_core.dm @@ -138,6 +138,9 @@ ///Helper for small fires to grow #define FIRE_GROWTH_RATE 40000 +///Multiplier for the temperature shared to other turfs +#define COLD_FIRE_SPREAD_RADIOSITY_SCALE 0.95 + ///moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC (103 or so) #define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) ///compared against for superconductivity diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index 8772ce6fdf4..f5559e795a7 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -96,8 +96,10 @@ // - Freon: /// The maximum temperature freon can combust at. #define FREON_MAXIMUM_BURN_TEMPERATURE 283 -/// The minimum temperature freon can combust at. +///Minimum temperature allowed for the burn to go at max speed, we would have negative pressure otherwise #define FREON_LOWER_TEMPERATURE 60 +///Terminal temperature after wich we stop the reaction +#define FREON_TERMINAL_TEMPERATURE 20 /// Multiplier for freonfire with O2 moles * FREON_OXYGEN_FULLBURN for the maximum fuel consumption #define FREON_OXYGEN_FULLBURN 10 /// The maximum fraction of the freon in a mix that can combust each reaction tick. diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm index 1294ce9da63..c36f4bbb26c 100644 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ b/code/modules/atmospherics/environmental/LINDA_fire.dm @@ -41,6 +41,8 @@ var/trit = . ? .[MOLES] : 0 . = air_gases[/datum/gas/hydrogen] var/h2 = . ? .[MOLES] : 0 + . = air_gases[/datum/gas/freon] + var/freon = . ? .[MOLES] : 0 if(active_hotspot) if(soh) if(plas > 0.5 || trit > 0.5 || h2 > 0.5) @@ -48,9 +50,15 @@ active_hotspot.temperature = exposed_temperature if(active_hotspot.volume < exposed_volume) active_hotspot.volume = exposed_volume + else if(freon > 0.5) + if(active_hotspot.temperature > exposed_temperature) + active_hotspot.temperature = exposed_temperature + if(active_hotspot.volume < exposed_volume) + active_hotspot.volume = exposed_volume return - if((exposed_temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) && (plas > 0.5 || trit > 0.5 || h2 > 0.5)) + if(((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (plas > 0.5 || trit > 0.5 || h2 > 0.5)) || \ + ((exposed_temperature < FREON_MAXIMUM_BURN_TEMPERATURE) && (freon > 0.5))) active_hotspot = new /obj/effect/hotspot(src, exposed_volume*25, exposed_temperature) @@ -58,7 +66,6 @@ //remove just_spawned protection if no longer processing this cell SSair.add_to_active(src) - /** * Hotspot objects interfaces with the temperature of turf gasmixtures while also providing visual effects. * One important thing to note about hotspots are that they can roughly be divided into two categories based on the bypassing variable. @@ -89,6 +96,8 @@ /// Whether the hotspot becomes passive and follows the gasmix temp instead of changing it. var/bypassing = FALSE var/visual_update_tick = 0 + ///Are we burning freon? + var/cold_fire = FALSE /obj/effect/hotspot/Initialize(mapload, starting_volume, starting_temperature) @@ -130,7 +139,7 @@ bypassing = !just_spawned && (volume > CELL_VOLUME*0.95) //Passive mode - if(bypassing) + if(bypassing || cold_fire) reference = location.air // Our color and volume will depend on the turf's gasmix //Active mode else @@ -150,6 +159,8 @@ temperature = reference.temperature // Handles the burning of atoms. + if(cold_fire) + return for(var/A in location) var/atom/AT = A if(!QDELETED(AT) && AT != src) @@ -171,7 +182,12 @@ var/heat_a = 255 var/greyscale_fire = 1 //This determines how greyscaled the fire is. - if(temperature < 5000) //This is where fire is very orange, we turn it into the normal fire texture here. + if(cold_fire) + heat_r = 0 + heat_g = LERP(255, temperature, 1.2) + heat_b = LERP(255, temperature, 0.9) + heat_a = 100 + else if(temperature < 5000) //This is where fire is very orange, we turn it into the normal fire texture here. var/normal_amt = gauss_lerp(temperature, 1000, 3000) heat_r = LERP(heat_r,255,normal_amt) heat_g = LERP(heat_g,255,normal_amt) @@ -237,12 +253,16 @@ if(location.excited_group) location.excited_group.reset_cooldowns() - if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1)) + cold_fire = FALSE + if(temperature <= FREON_MAXIMUM_BURN_TEMPERATURE) + cold_fire = TRUE + + if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST && !cold_fire) || (volume <= 1)) qdel(src) return //Not enough / nothing to burn - if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium) && INSUFFICIENT(/datum/gas/hydrogen)) || INSUFFICIENT(/datum/gas/oxygen)) + if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium) && INSUFFICIENT(/datum/gas/hydrogen) && INSUFFICIENT(/datum/gas/freon)) || INSUFFICIENT(/datum/gas/oxygen)) qdel(src) return @@ -250,11 +270,14 @@ if(bypassing) icon_state = "3" - location.burn_tile() + if(!cold_fire) + location.burn_tile() //Possible spread due to radiated heat. - if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD) + if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD || cold_fire) var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE + if(cold_fire) + radiated_temperature = location.air.temperature * COLD_FIRE_SPREAD_RADIOSITY_SCALE for(var/t in location.atmos_adjacent_turfs) var/turf/open/T = t if(!T.active_hotspot) @@ -280,7 +303,7 @@ /obj/effect/hotspot/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER - if(isliving(arrived)) + if(isliving(arrived) && !cold_fire) var/mob/living/immolated = arrived immolated.fire_act(temperature, volume) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 7f07541b3f6..1d12ae6a732 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -58,12 +58,12 @@ /// A short string describing this reaction. var/desc /** REACTION FACTORS - * + * * Describe (to a human) factors influencing this reaction in an assoc list format. * Also include gases formed by the reaction * Implement various interaction for different keys under subsystem/air/proc/atmos_handbook_init() - * - * E.G. + * + * E.G. * factor["Temperature"] = "Minimum temperature of 20 kelvins, maximum temperature of 100 kelvins" * factor["o2"] = "Minimum oxygen amount of 20 moles, more oxygen increases reaction rate up to 150 moles" */ @@ -379,13 +379,14 @@ priority_group = PRIORITY_FIRE name = "Freon Combustion" id = "freonfire" + expands_hotspot = TRUE desc = "Reaction between oxygen and freon that consumes a huge amount of energy and can cool things significantly. Also able to produce hot ice." /datum/gas_reaction/freonfire/init_reqs() requirements = list( /datum/gas/oxygen = MINIMUM_MOLE_COUNT, /datum/gas/freon = MINIMUM_MOLE_COUNT, - "MIN_TEMP" = FREON_LOWER_TEMPERATURE, + "MIN_TEMP" = FREON_TERMINAL_TEMPERATURE, "MAX_TEMP" = FREON_MAXIMUM_BURN_TEMPERATURE, ) @@ -395,10 +396,12 @@ var/temperature = air.temperature var/temperature_scale - if(temperature < FREON_LOWER_TEMPERATURE) //stop the reaction when too cold + if(temperature < FREON_TERMINAL_TEMPERATURE) //stop the reaction when too cold temperature_scale = 0 + else if(temperature < FREON_LOWER_TEMPERATURE) + temperature_scale = 0.5 else - temperature_scale = (FREON_MAXIMUM_BURN_TEMPERATURE - temperature) / (FREON_MAXIMUM_BURN_TEMPERATURE - FREON_LOWER_TEMPERATURE) //calculate the scale based on the temperature + temperature_scale = (FREON_MAXIMUM_BURN_TEMPERATURE - temperature) / (FREON_MAXIMUM_BURN_TEMPERATURE - FREON_TERMINAL_TEMPERATURE) //calculate the scale based on the temperature if (temperature_scale <= 0) return NO_REACTION @@ -427,7 +430,13 @@ var/energy_consumed = FIRE_FREON_ENERGY_CONSUMED * freon_burn_rate var/new_heat_capacity = air.heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) - air.temperature = (temperature * old_heat_capacity - energy_consumed) / new_heat_capacity + air.temperature = max((temperature * old_heat_capacity - energy_consumed) / new_heat_capacity, TCMB) + + var/turf/open/location = holder + if(istype(location)) + temperature = air.temperature + if(temperature < FREON_MAXIMUM_BURN_TEMPERATURE) + location.hotspot_expose(temperature, CELL_VOLUME) return REACTING @@ -544,7 +553,7 @@ var/list/cached_gases = air.gases var/pressure = air.return_pressure() // This slows down in relation to pressure, very quickly. Please don't expect it to be anything more then a snail - + // Bigger is better for these two values. var/pressure_efficiency = (0.1 * ONE_ATMOSPHERE) / pressure // More pressure = more bad var/ratio_efficiency = min(cached_gases[/datum/gas/nitrous_oxide][MOLES] / cached_gases[/datum/gas/plasma][MOLES], 1) // Malus to production if more plasma than n2o.