diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm index d39fcbdd720..da26f72f9ef 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm @@ -50,3 +50,14 @@ #define HYPERTORUS_SUBCRITICAL_MOLES 2000 #define HYPERTORUS_HYPERCRITICAL_MOLES 10000 #define HYPERTORUS_MAX_MOLE_DAMAGE 10 + +#define HYPERTORUS_FLAG_BASE_EXPLOSION (1<<0) +#define HYPERTORUS_FLAG_MEDIUM_EXPLOSION (1<<1) +#define HYPERTORUS_FLAG_DEVASTATING_EXPLOSION (1<<2) +#define HYPERTORUS_FLAG_RADIATION_PULSE (1<<3) +#define HYPERTORUS_FLAG_EMP (1<<4) +#define HYPERTORUS_FLAG_MINIMUM_SPREAD (1<<5) +#define HYPERTORUS_FLAG_MEDIUM_SPREAD (1<<6) +#define HYPERTORUS_FLAG_BIG_SPREAD (1<<7) +#define HYPERTORUS_FLAG_MASSIVE_SPREAD (1<<8) +#define HYPERTORUS_FLAG_CRITICAL_MELTDOWN (1<<9) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm index 2334997574d..1b33ef94a40 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm @@ -34,6 +34,8 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) var/primary_products = list() ///Gases that gets produced in the moderator gasmix or directly ejected (must be 6 gases), the order indicate at what power level the gases are going to be made (from power level 1 to 6) var/secondary_products = list() + ///Flags to decide what behaviour the meltdown will have depending on the fuel mix used + var/meltdown_flags = HYPERTORUS_FLAG_BASE_EXPLOSION /datum/hfr_fuel/hydrogen_tritium_fuel id = "h2_t2_fuel" @@ -47,6 +49,7 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) requirements = list(/datum/gas/hydrogen, /datum/gas/tritium) primary_products = list(/datum/gas/helium) secondary_products = list(/datum/gas/helium, /datum/gas/plasma, /datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/bz, /datum/gas/hypernoblium) + meltdown_flags = HYPERTORUS_FLAG_MEDIUM_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_MEDIUM_SPREAD /datum/hfr_fuel/hydrogen_oxy_fuel id = "h2_o2_fuel" @@ -60,6 +63,7 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) requirements = list(/datum/gas/hydrogen, /datum/gas/oxygen) primary_products = list(/datum/gas/helium, /datum/gas/nitrogen) secondary_products = list(/datum/gas/helium, /datum/gas/plasma, /datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/bz, /datum/gas/hypernoblium) + meltdown_flags = HYPERTORUS_FLAG_BASE_EXPLOSION | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_MEDIUM_SPREAD /datum/hfr_fuel/tritium_oxy_fuel id = "t2_o2_fuel" @@ -73,6 +77,7 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) requirements = list(/datum/gas/tritium, /datum/gas/oxygen) primary_products = list(/datum/gas/helium, /datum/gas/pluoxium) secondary_products = list(/datum/gas/helium, /datum/gas/plasma, /datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/bz, /datum/gas/hypernoblium) + meltdown_flags = HYPERTORUS_FLAG_BASE_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_MEDIUM_SPREAD /datum/hfr_fuel/plasma_oxy_fuel id = "plasma_o2_fuel" @@ -86,6 +91,7 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) requirements = list(/datum/gas/plasma, /datum/gas/oxygen) primary_products = list(/datum/gas/carbon_dioxide, /datum/gas/water_vapor) secondary_products = list(/datum/gas/carbon_dioxide, /datum/gas/water_vapor, /datum/gas/freon, /datum/gas/nitrous_oxide, /datum/gas/pluoxium, /datum/gas/halon) + meltdown_flags = HYPERTORUS_FLAG_BASE_EXPLOSION | HYPERTORUS_FLAG_MINIMUM_SPREAD /datum/hfr_fuel/hypernob_hydrogen_fuel id = "hypernob_hydrogen_fuel" @@ -99,6 +105,7 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) requirements = list(/datum/gas/hypernoblium, /datum/gas/hydrogen) primary_products = list(/datum/gas/antinoblium) secondary_products = list(/datum/gas/antinoblium, /datum/gas/helium, /datum/gas/proto_nitrate, /datum/gas/zauker, /datum/gas/healium, /datum/gas/miasma) + meltdown_flags = HYPERTORUS_FLAG_DEVASTATING_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_BIG_SPREAD /datum/hfr_fuel/hypernob_trit_fuel id = "hypernob_trit_fuel" @@ -112,6 +119,7 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) requirements = list(/datum/gas/hypernoblium, /datum/gas/tritium) primary_products = list(/datum/gas/antinoblium) secondary_products = list(/datum/gas/antinoblium, /datum/gas/helium, /datum/gas/proto_nitrate, /datum/gas/zauker, /datum/gas/healium, /datum/gas/miasma) + meltdown_flags = HYPERTORUS_FLAG_DEVASTATING_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_BIG_SPREAD /datum/hfr_fuel/hypernob_antinob_fuel id = "hypernob_antinob_fuel" @@ -125,3 +133,4 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list()) requirements = list(/datum/gas/hypernoblium, /datum/gas/antinoblium) primary_products = list(/datum/gas/helium) secondary_products = list(/datum/gas/plasma, /datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/proto_nitrate, /datum/gas/stimulum, /datum/gas/miasma) + meltdown_flags = HYPERTORUS_FLAG_DEVASTATING_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_MASSIVE_SPREAD | HYPERTORUS_FLAG_CRITICAL_MELTDOWN diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm index d02e76d305d..06d5014c3ed 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm @@ -294,6 +294,10 @@ return final_countdown = TRUE + var/critical = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_CRITICAL_MELTDOWN + if(critical) + priority_announce("WARNING - The explosion will likely cover a big part of the station and the coming EMP will wipe out most of the electronics. \ + Get as far away as possible from the reactor or find a way to shut it down.", "Alert") var/speaking = "[emergency_alert] The Hypertorus fusion reactor has reached critical integrity failure. Emergency magnetic dampeners online." radio.talk_into(src, speaking, common_channel, language = get_selected_language()) for(var/i in HYPERTORUS_COUNTDOWN_TIME to 0 step -10) @@ -305,6 +309,8 @@ sleep(10) continue else if(i > 50) + if(i == 10 SECONDS && critical) + sound_to_playing_players('sound/machines/hypertorus/HFR_critical_explosion.ogg') speaking = "[DisplayTimeText(i, TRUE)] remain before total integrity failure." else speaking = "[i*0.1]..." @@ -318,10 +324,76 @@ * Create the explosion + the gas emission before deleting the machine core. */ /obj/machinery/atmospherics/components/unary/hypertorus/core/proc/meltdown() - explosion(src, light_impact_range = power_level * 5, flash_range = power_level * 6, adminlog = TRUE, ignorecap = TRUE) - radiation_pulse(loc, power_level * 7000, (1 / (power_level + 5)), TRUE) - empulse(loc, power_level * 5, power_level * 7, TRUE) - var/list/around_turfs = circlerangeturfs(src, power_level * 5) + var/flash_explosion = 0 + var/light_impact_explosion = 0 + var/heavy_impact_explosion = 0 + var/devastating_explosion = 0 + var/em_pulse = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_EMP + var/rad_pulse = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_RADIATION_PULSE + var/emp_light_size = 0 + var/emp_heavy_size = 0 + var/rad_pulse_size = 0 + var/rad_pulse_strength = 0 + var/gas_spread = 0 + var/gas_pockets = 0 + var/critical = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_CRITICAL_MELTDOWN + + if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_BASE_EXPLOSION) + flash_explosion = power_level * 3 + light_impact_explosion = power_level * 2 + + if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MEDIUM_EXPLOSION) + flash_explosion = power_level * 6 + light_impact_explosion = power_level * 5 + heavy_impact_explosion = power_level * 0.5 + + if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_DEVASTATING_EXPLOSION) + flash_explosion = power_level * 8 + light_impact_explosion = power_level * 7 + heavy_impact_explosion = power_level * 2 + devastating_explosion = power_level + + if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MINIMUM_SPREAD) + if(em_pulse) + emp_light_size = power_level * 3 + emp_heavy_size = power_level * 1 + if(rad_pulse) + rad_pulse_size = (1 / (power_level + 1)) + rad_pulse_strength = power_level * 3000 + gas_pockets = 5 + gas_spread = power_level * 2 + + if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MEDIUM_SPREAD) + if(em_pulse) + emp_light_size = power_level * 5 + emp_heavy_size = power_level * 3 + if(rad_pulse) + rad_pulse_size = (1 / (power_level + 3)) + rad_pulse_strength = power_level * 5000 + gas_pockets = 7 + gas_spread = power_level * 4 + + if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_BIG_SPREAD) + if(em_pulse) + emp_light_size = power_level * 7 + emp_heavy_size = power_level * 5 + if(rad_pulse) + rad_pulse_size = (1 / (power_level + 5)) + rad_pulse_strength = power_level * 7000 + gas_pockets = 10 + gas_spread = power_level * 6 + + if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MASSIVE_SPREAD) + if(em_pulse) + emp_light_size = power_level * 9 + emp_heavy_size = power_level * 7 + if(rad_pulse) + rad_pulse_size = (1 / (power_level + 7)) + rad_pulse_strength = power_level * 9000 + gas_pockets = 15 + gas_spread = power_level * 8 + + var/list/around_turfs = circlerangeturfs(src, gas_spread) for(var/turf/turf as anything in around_turfs) if(isclosedturf(turf) || isspaceturf(turf)) around_turfs -= turf @@ -330,8 +402,8 @@ if(internal_fusion.total_moles() > 0) remove_fusion = internal_fusion.remove_ratio(0.2) var/datum/gas_mixture/remove - for(var/i in 1 to 10) - remove = remove_fusion.remove_ratio(0.1) + for(var/i in 1 to gas_pockets) + remove = remove_fusion.remove_ratio(1/gas_pockets) var/turf/local = pick(around_turfs) local.assume_air(remove) loc.assume_air(internal_fusion) @@ -339,11 +411,39 @@ if(moderator_internal.total_moles() > 0) remove_moderator = moderator_internal.remove_ratio(0.2) var/datum/gas_mixture/remove - for(var/i in 1 to 10) - remove = remove_moderator.remove_ratio(0.1) + for(var/i in 1 to gas_pockets) + remove = remove_moderator.remove_ratio(1/gas_pockets) var/turf/local = pick(around_turfs) local.assume_air(remove) loc.assume_air(moderator_internal) + + //Max explosion ranges: devastation = 12, heavy = 24, light = 42 + explosion( + origin = src, + devastation_range = critical ? devastating_explosion * 2 : devastating_explosion, + heavy_impact_range = critical ? heavy_impact_explosion * 2 : heavy_impact_explosion, + light_impact_range = light_impact_explosion, + flash_range = flash_explosion, + adminlog = TRUE, + ignorecap = TRUE + ) + + if(rad_pulse) + radiation_pulse( + source = loc, + intensity = rad_pulse_strength, + range_modifier = rad_pulse_size, + log = TRUE + ) + + if(em_pulse) + empulse( + epicenter = loc, + heavy_range = critical ? emp_heavy_size * 2 : emp_heavy_size, + light_range = critical ? emp_light_size * 2 : emp_heavy_size, + log = TRUE + ) + qdel(src) /obj/machinery/atmospherics/components/unary/hypertorus/core/proc/check_cracked_parts() diff --git a/sound/machines/hypertorus/HFR_critical_explosion.ogg b/sound/machines/hypertorus/HFR_critical_explosion.ogg new file mode 100644 index 00000000000..5db3cd611f0 Binary files /dev/null and b/sound/machines/hypertorus/HFR_critical_explosion.ogg differ