diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index a8c111c5164..1989ca0eaa3 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -261,3 +261,8 @@ #define PN_BZASE_NUCLEAR_PARTICLE_MAXIMUM 6 /// How much radiation in consumed amount does a nuclear particle take from radiation when proto-nitrate breaks down BZ. #define PN_BZASE_NUCLEAR_PARTICLE_RADIATION_ENERGY_CONVERSION 2.5 + +// Electrolysis: +// Electrolysis arguments: +/// Supermatter power argument. +#define ELECTROLYSIS_ARGUMENT_SUPERMATTER_POWER "electrolyzer_supermatter_power" diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index f329b98bec0..cddd5c24125 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -726,3 +726,20 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) output_air.merge(removed) return TRUE + +/** + * Calls for electrolyzer_reaction reactions on the gas_mixture. + * Arguments: + * * working_power - working_power to use for the electrolyzer_reaction reactions. + * * electrolyzer_args - electrolysis arguments to use for the electrolyzer_reaction reactions. + */ +/datum/gas_mixture/proc/electrolyze(working_power = 0, electrolyzer_args = list()) + for(var/reaction in GLOB.electrolyzer_reactions) + var/datum/electrolyzer_reaction/current_reaction = GLOB.electrolyzer_reactions[reaction] + + if(!current_reaction.reaction_check(air_mixture = src, electrolyzer_args = electrolyzer_args)) + continue + + current_reaction.react(air_mixture = src, working_power = working_power, electrolyzer_args = electrolyzer_args) + + garbage_collect() diff --git a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm index f20ee606cb2..d8105c1b344 100644 --- a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm +++ b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm @@ -130,15 +130,7 @@ cell.use(power_to_use) /obj/machinery/electrolyzer/proc/call_reactions(datum/gas_mixture/env) - for(var/reaction in GLOB.electrolyzer_reactions) - var/datum/electrolyzer_reaction/current_reaction = GLOB.electrolyzer_reactions[reaction] - - if(!current_reaction.reaction_check(env)) - continue - - current_reaction.react(loc, env, working_power) - - env.garbage_collect() + env.electrolyze(working_power = working_power) /obj/machinery/electrolyzer/RefreshParts() . = ..() diff --git a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm index 35dbf7cdbb3..21fd7eb018a 100644 --- a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm +++ b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm @@ -19,10 +19,23 @@ GLOBAL_LIST_INIT(electrolyzer_reactions, electrolyzer_reactions_list()) var/desc = "" var/list/factor -/datum/electrolyzer_reaction/proc/react(turf/location, datum/gas_mixture/air_mixture, working_power) +/** + * Electrolyzer reaction. + * Args: + * * air_mixture: The gas_mixture receiving the electrolysis. + * * working_power: How much energy to put into the electrolysis, in electrolyzer units. A value of 1 is what a tier 1 electrolyzer would put in. + * * electrolyzer_args: Additional arguments for alternative methods of electrolysis. + */ +/datum/electrolyzer_reaction/proc/react(datum/gas_mixture/air_mixture, working_power, list/electrolyzer_args = list()) return -/datum/electrolyzer_reaction/proc/reaction_check(datum/gas_mixture/air_mixture) +/** + * Checks whether the requirements are met for a reaction. + * Args: + * * air_mixture: The air mixture to check the requirements for. + * * electrolyzer_args: Additional arguments for alternative methods of electrolysis. + */ +/datum/electrolyzer_reaction/proc/reaction_check(datum/gas_mixture/air_mixture, list/electrolyzer_args = list()) var/temp = air_mixture.temperature var/list/cached_gases = air_mixture.gases if((requirements["MIN_TEMP"] && temp < requirements["MIN_TEMP"]) || (requirements["MAX_TEMP"] && temp > requirements["MAX_TEMP"])) @@ -48,7 +61,7 @@ GLOBAL_LIST_INIT(electrolyzer_reactions, electrolyzer_reactions_list()) "Location" = "Can only happen on turfs with an active Electrolyzer.", ) -/datum/electrolyzer_reaction/h2o_conversion/react(turf/location, datum/gas_mixture/air_mixture, working_power) +/datum/electrolyzer_reaction/h2o_conversion/react(datum/gas_mixture/air_mixture, working_power, list/electrolyzer_args = list()) var/old_heat_capacity = air_mixture.heat_capacity() air_mixture.assert_gases(/datum/gas/water_vapor, /datum/gas/oxygen, /datum/gas/hydrogen) @@ -66,23 +79,30 @@ GLOBAL_LIST_INIT(electrolyzer_reactions, electrolyzer_reactions_list()) desc = "Conversion of Hypernoblium into Antinoblium" requirements = list( /datum/gas/hypernoblium = MINIMUM_MOLE_COUNT, - "MAX_TEMP" = 150 ) factor = list( /datum/gas/hypernoblium = "1 mole of Hypernoblium gets consumed", - /datum/gas/antinoblium = "0.5 moles of Antinoblium get produced", - "Temperature" = "Can only occur under 150 kelvin.", - "Location" = "Can only happen on turfs with an active Electrolyzer.", + /datum/gas/antinoblium = "1 mole of Antinoblium get produced", + "Location" = "Can only happen on turfs that are being struck by supermatter zaps with a power level above 5 GeV.", ) -/datum/electrolyzer_reaction/nob_conversion/react(turf/location, datum/gas_mixture/air_mixture, working_power) +/datum/electrolyzer_reaction/nob_conversion/reaction_check(datum/gas_mixture/air_mixture, list/electrolyzer_args = list()) + if(!electrolyzer_args[ELECTROLYSIS_ARGUMENT_SUPERMATTER_POWER] || electrolyzer_args[ELECTROLYSIS_ARGUMENT_SUPERMATTER_POWER] <= POWER_PENALTY_THRESHOLD) + return FALSE + . = ..() +/datum/electrolyzer_reaction/nob_conversion/react(datum/gas_mixture/air_mixture, working_power, list/electrolyzer_args = list()) + /// The supermatter zap power_level. + var/supermatter_power = electrolyzer_args[ELECTROLYSIS_ARGUMENT_SUPERMATTER_POWER] + var/list/cached_gases = air_mixture.gases var/old_heat_capacity = air_mixture.heat_capacity() air_mixture.assert_gases(/datum/gas/hypernoblium, /datum/gas/antinoblium) - var/proportion = min(air_mixture.gases[/datum/gas/hypernoblium][MOLES], (1.5 * (working_power ** 2))) - air_mixture.gases[/datum/gas/hypernoblium][MOLES] -= proportion - air_mixture.gases[/datum/gas/antinoblium][MOLES] += proportion * 0.5 - var/new_heat_capacity = air_mixture.heat_capacity() + var/list/hypernoblium = cached_gases[/datum/gas/hypernoblium] + var/list/antinoblium = cached_gases[/datum/gas/antinoblium] + var/electrolysed = hypernoblium[MOLES] * clamp(supermatter_power - POWER_PENALTY_THRESHOLD, 0, CRITICAL_POWER_PENALTY_THRESHOLD - POWER_PENALTY_THRESHOLD) / (CRITICAL_POWER_PENALTY_THRESHOLD - POWER_PENALTY_THRESHOLD) + hypernoblium[MOLES] -= electrolysed + antinoblium[MOLES] += electrolysed + var/new_heat_capacity = old_heat_capacity + electrolysed * (antinoblium[GAS_META][META_GAS_SPECIFIC_HEAT] - hypernoblium[GAS_META][META_GAS_SPECIFIC_HEAT]) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) air_mixture.temperature = max(air_mixture.temperature * old_heat_capacity / new_heat_capacity, TCMB) @@ -102,7 +122,7 @@ GLOBAL_LIST_INIT(electrolyzer_reactions, electrolyzer_reactions_list()) "Location" = "Can only happen on turfs with an active Electrolyzer.", ) -/datum/electrolyzer_reaction/halon_generation/react(turf/location, datum/gas_mixture/air_mixture, working_power) +/datum/electrolyzer_reaction/halon_generation/react(datum/gas_mixture/air_mixture, working_power, list/electrolyzer_args = list()) var/old_heat_capacity = air_mixture.heat_capacity() air_mixture.assert_gases(/datum/gas/bz, /datum/gas/oxygen, /datum/gas/halon) var/reaction_efficency = min(air_mixture.gases[/datum/gas/bz][MOLES] * (1 - NUM_E ** (-0.5 * air_mixture.temperature * working_power / FIRE_MINIMUM_TEMPERATURE_TO_EXIST)), air_mixture.gases[/datum/gas/bz][MOLES]) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index a728033f967..f523dc27a22 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -1050,8 +1050,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) //This gotdamn variable is a boomer and keeps giving me problems var/turf/target_turf = get_turf(target) var/pressure = 1 + // Calculate pressure and do electrolysis. if(target_turf?.return_air()) - pressure = max(1,target_turf.return_air().return_pressure()) + var/datum/gas_mixture/air_mixture = target_turf.return_air() + pressure = max(1, air_mixture.return_pressure()) + air_mixture.electrolyze(working_power = zap_str / 200, electrolyzer_args = list(ELECTROLYSIS_ARGUMENT_SUPERMATTER_POWER = power_level)) + target_turf.air_update_turf() //We get our range with the strength of the zap and the pressure, the higher the former and the lower the latter the better var/new_range = clamp(zap_str / pressure * 10, 2, 7) var/zap_count = 1 diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index ab210fe1986..c41be13d086 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -348,6 +348,13 @@ else power = closest_atom.zap_act(power, zap_flags) + // Electrolysis. + var/turf/target_turf = get_turf(closest_atom) + if(target_turf?.return_air()) + var/datum/gas_mixture/air_mixture = target_turf.return_air() + air_mixture.electrolyze(working_power = power / 200) + target_turf.air_update_turf() + if(prob(20))//I know I know var/list/shocked_copy = shocked_targets.Copy() tesla_zap(source = closest_atom, zap_range = next_range, power = power * 0.5, cutoff = cutoff, zap_flags = zap_flags, shocked_targets = shocked_copy)