From 10fbd233f31eca3095b23735071efbcd54ea3cc9 Mon Sep 17 00:00:00 2001 From: Pickle-Coding <58013024+Pickle-Coding@users.noreply.github.com> Date: Sat, 17 May 2025 05:34:05 +0100 Subject: [PATCH] Tesla and supermatter zaps can trigger electrolysis reactions. Hypernoblium to antinoblium conversion requires supermatter zaps. (#91048) ## About The Pull Request Supermatter and tesla zaps can trigger electrolysis reactions. Hypernoblium to antinoblium conversion requires supermatter zaps above 5 GeV, with 100% efficiency at 9GeV. Antinoblium is generated at 1:1 from hypernoblium consumed. The requirement for hypernoblium conversion is also included in the reaction console. ## Why It's Good For The Game Ordinary electrolysis is a rather boring way to obtain antinoblium, especially with fire extinguisher cheese. This limits the creation of antinoblium to more extreme and loud methods. This is mainly intended for balancing #91016, but seems out of scope to include in that PR. This also gives room for antinoblium to be balanced as one of the more exotic gases, and is much more obvious when antinoblium is being created. ## Changelog :cl: add: Supermatter and tesla zaps can trigger electrolyzer reactions. balance: Hypernoblium to antinoblium electrolysis requires supermatter zaps above 5 GeV. balance: Hypernoblium is converted to antinoblium 1:1 during electrolysis. /:cl: --- code/__DEFINES/reactions.dm | 5 ++ .../atmospherics/gasmixtures/gas_mixture.dm | 17 +++++++ .../components/electrolyzer/electrolyzer.dm | 10 +--- .../electrolyzer/electrolyzer_reactions.dm | 46 +++++++++++++------ code/modules/power/supermatter/supermatter.dm | 6 ++- code/modules/power/tesla/energy_ball.dm | 7 +++ 6 files changed, 68 insertions(+), 23 deletions(-) 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)