diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 71fc835d25e..44e67226604 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -135,6 +135,11 @@ #define JOB_SOLFED_LIASON "SolFed Liason" // SKYRAT EDIT ADDITION END +#define JOB_GROUP_ENGINEERS list( \ + JOB_STATION_ENGINEER, \ + JOB_ATMOSPHERIC_TECHNICIAN, \ +) + #define JOB_DISPLAY_ORDER_ASSISTANT 1 #define JOB_DISPLAY_ORDER_CAPTAIN 2 diff --git a/code/__DEFINES/supermatter.dm b/code/__DEFINES/supermatter.dm index 4721d755a5c..bac35207fb5 100644 --- a/code/__DEFINES/supermatter.dm +++ b/code/__DEFINES/supermatter.dm @@ -63,6 +63,8 @@ #define SLIGHTLY_CHARGED_ZAP_ICON_STATE "sm_arc_supercharged" #define OVER_9000_ZAP_ICON_STATE "sm_arc_dbz_referance" //Witty I know +#define SUPERMATTER_DEFAULT_BULLET_ENERGY 2 + #define SUPERMATTER_CASCADE_PERCENT 80 /// The divisor scaling value for cubic power loss. diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 1bca2ca531b..fc5d0fe8d4e 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -977,4 +977,27 @@ SUBSYSTEM_DEF(job) return JOB_AVAILABLE +/** + * Check if the station manifest has at least a certain amount of this staff type. + * If a matching head of staff is on the manifest, automatically passes (returns TRUE) + * + * Arguments: + * * crew_threshold - amount of crew to meet the requirement + * * jobs - a list of jobs that qualify the requirement + * * head_jobs - a list of head jobs that qualify the requirement + * +*/ +/datum/controller/subsystem/job/proc/has_minimum_jobs(crew_threshold, list/jobs = list(), list/head_jobs = list()) + var/employees = 0 + for(var/datum/record/crew/target in GLOB.manifest.general) + if(target.trim in head_jobs) + return TRUE + if(target.trim in jobs) + employees++ + + if(employees > crew_threshold) + return TRUE + + return FALSE + #undef VERY_LATE_ARRIVAL_TOAST_PROB diff --git a/code/modules/events/supermatter_surge.dm b/code/modules/events/supermatter_surge.dm new file mode 100644 index 00000000000..f8e1f2698f7 --- /dev/null +++ b/code/modules/events/supermatter_surge.dm @@ -0,0 +1,110 @@ +#define SURGE_DURATION_MIN 240 EVENT_SECONDS +#define SURGE_DURATION_MAX 270 EVENT_SECONDS +#define SURGE_SEVERITY_MIN 1 +#define SURGE_SEVERITY_MAX 4 +/// The amount of bullet energy we add for the duration of the SM surge +#define SURGE_BULLET_ENERGY_ADDITION 5 +/// The amount of powerloss inhibition (energy retention) we add for the duration of the SM surge +#define SURGE_BASE_POWERLOSS_INHIBITION 0.55 +/// The powerloss inhibition scaling based on surge severity +#define SURGE_POWERLOSS_INHIBITION_MODIFIER 0.175 +/// The power generation scaling based on surge severity +#define SURGE_POWER_GENERATION_MODIFIER 0.075 +/// The heat modifier scaling based on surge severity +#define SURGE_HEAT_MODIFIER 0.25 + +/** + * Supermatter Surge + * + * An engineering challenge event where the properties of the SM changes to be in a 'surge' of power. + * For the duration of the event a powerloss inhibition is added to nitrogen, causing the crystal to retain more of its internal energy. + * Heat modifier is lowered to generate some heat but not a high temp burn. + * Bullet energy from emitters is raised slightly to raise meV while turned on. + */ + +/datum/round_event_control/supermatter_surge + name = "Supermatter Surge" + typepath = /datum/round_event/supermatter_surge + category = EVENT_CATEGORY_ENGINEERING + weight = 15 + max_occurrences = 1 + earliest_start = 20 MINUTES + description = "The supermatter will increase in power and heat by a random amount, and announce it." + min_wizard_trigger_potency = 4 + max_wizard_trigger_potency = 7 + admin_setup = list( + /datum/event_admin_setup/input_number/surge_spiciness, + ) + +/datum/round_event_control/supermatter_surge/can_spawn_event(players_amt, allow_magic = FALSE) + . = ..() + + if(!SSjob.has_minimum_jobs(crew_threshold = 3, jobs = JOB_GROUP_ENGINEERS, head_jobs = list(JOB_CHIEF_ENGINEER))) + return FALSE + +/datum/round_event/supermatter_surge + announce_when = 4 + end_when = SURGE_DURATION_MIN + /// How powerful is the supermatter surge going to be? + var/surge_class = SURGE_SEVERITY_MIN + /// Typecasted reference to the supermatter chosen at event start + var/obj/machinery/power/supermatter_crystal/engine + /// Typecasted reference to the nitrogen properies in the SM chamber + var/datum/sm_gas/nitrogen/sm_gas + +/datum/event_admin_setup/input_number/surge_spiciness + input_text = "Set surge intensity. (Higher is more severe.)" + min_value = 1 + max_value = 4 + +/datum/event_admin_setup/input_number/surge_spiciness/prompt_admins() + default_value = rand(1, 4) + return ..() + +/datum/event_admin_setup/input_number/surge_spiciness/apply_to_event(datum/round_event/supermatter_surge/event) + event.surge_class = chosen_value + +/datum/round_event/supermatter_surge/setup() + engine = GLOB.main_supermatter_engine + if(isnull(engine)) + stack_trace("SM surge event failed to find a supermatter engine!") + return + + sm_gas = LAZYACCESS(engine.current_gas_behavior, /datum/gas/nitrogen) + if(isnull(sm_gas)) + stack_trace("SM surge event failed to find gas properties for [engine].") + return + + if(isnull(surge_class)) + surge_class = rand(SURGE_SEVERITY_MIN, SURGE_SEVERITY_MAX) + + end_when = rand(SURGE_DURATION_MIN, SURGE_DURATION_MAX) + +/datum/round_event/supermatter_surge/announce() + priority_announce("The Crystal Integrity Monitoring System has detected unusual atmospheric properties in the supermatter chamber and energy output from the supermatter crystal has increased significantly. Engineering intervention is required to stabilize the engine.", "Class [surge_class] Supermatter Surge Alert", 'sound/machines/engine_alert3.ogg') + +/datum/round_event/supermatter_surge/start() + engine.bullet_energy = surge_class + SURGE_BULLET_ENERGY_ADDITION + sm_gas.powerloss_inhibition = (surge_class * SURGE_POWERLOSS_INHIBITION_MODIFIER) + SURGE_BASE_POWERLOSS_INHIBITION + sm_gas.heat_power_generation = (surge_class * SURGE_POWER_GENERATION_MODIFIER) - 1 + sm_gas.heat_modifier = (surge_class * SURGE_HEAT_MODIFIER) - 1 + + +/datum/round_event/supermatter_surge/end() + engine.bullet_energy = initial(engine.bullet_energy) + sm_gas.powerloss_inhibition = initial(sm_gas.powerloss_inhibition) + sm_gas.heat_power_generation = initial(sm_gas.heat_power_generation) + sm_gas.heat_modifier = initial(sm_gas.heat_modifier) + priority_announce("The supermatter surge has dissipated, crystal output readings have normalized.", "Anomaly Cleared") + engine = null + sm_gas = null + +#undef SURGE_DURATION_MIN +#undef SURGE_DURATION_MAX +#undef SURGE_SEVERITY_MIN +#undef SURGE_SEVERITY_MAX +#undef SURGE_BULLET_ENERGY_ADDITION +#undef SURGE_BASE_POWERLOSS_INHIBITION +#undef SURGE_POWERLOSS_INHIBITION_MODIFIER +#undef SURGE_POWER_GENERATION_MODIFIER +#undef SURGE_HEAT_MODIFIER diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 997a29cc121..654ea805440 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -39,6 +39,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/absorption_ratio = 0.15 /// The gasmix we just recently absorbed. Tile's air multiplied by absorption_ratio var/datum/gas_mixture/absorbed_gasmix + /// The current gas behaviors for this particular crystal + var/list/current_gas_behavior ///Refered to as EER on the monitor. This value effects gas output, damage, and power generation. var/internal_energy = 0 @@ -109,7 +111,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) ///The cutoff for a bolt jumping, grows with heat, lowers with higher mol count, var/zap_cutoff = 1500 ///How much the bullets damage should be multiplied by when it is added to the internal variables - var/bullet_energy = 2 + var/bullet_energy = SUPERMATTER_DEFAULT_BULLET_ENERGY ///How much hallucination should we produce per unit of power? var/hallucination_power = 0.1 @@ -179,6 +181,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/Initialize(mapload) . = ..() + current_gas_behavior = init_sm_gas() gas_percentage = list() absorbed_gasmix = new() uid = gl_uid++ @@ -267,7 +270,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) // Some extra effects like [/datum/sm_gas/carbon_dioxide/extra_effects] // needs more than one gas and rely on a fully parsed gas_percentage. for (var/gas_path in absorbed_gasmix.gases) - var/datum/sm_gas/sm_gas = GLOB.sm_gas_behavior[gas_path] + var/datum/sm_gas/sm_gas = current_gas_behavior[gas_path] sm_gas?.extra_effects(src) // PART 3: POWER PROCESSING @@ -601,7 +604,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(mole_count < MINIMUM_MOLE_COUNT) //save processing power from small amounts like these continue gas_percentage[gas_path] = mole_count / total_moles - var/datum/sm_gas/sm_gas = GLOB.sm_gas_behavior[gas_path] + var/datum/sm_gas/sm_gas = current_gas_behavior[gas_path] if(!sm_gas) continue gas_power_transmission += sm_gas.power_transmission * gas_percentage[gas_path] diff --git a/modular_skyrat/modules/ices_events/code/ICES_event_config.dm b/modular_skyrat/modules/ices_events/code/ICES_event_config.dm index 7f4e2bfde67..bd49fc1de17 100644 --- a/modular_skyrat/modules/ices_events/code/ICES_event_config.dm +++ b/modular_skyrat/modules/ices_events/code/ICES_event_config.dm @@ -576,7 +576,7 @@ * Supermatter Surge */ /datum/round_event_control/supermatter_surge - max_occurrences = 2 + max_occurrences = 1 weight = MED_EVENT_FREQ /** diff --git a/modular_skyrat/modules/supermatter_surge/code/supermatter_surge.dm b/modular_skyrat/modules/supermatter_surge/code/supermatter_surge.dm deleted file mode 100644 index 351903a3e49..00000000000 --- a/modular_skyrat/modules/supermatter_surge/code/supermatter_surge.dm +++ /dev/null @@ -1,70 +0,0 @@ -#define SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_UPPER 300 -#define SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER 100 -#define SUPERMATTER_SURGE_TIME_UPPER 360 * 0.5 -#define SUPERMATTER_SURGE_TIME_LOWER 180 * 0.5 -#define SUPERMATTER_SURGE_ANNOUNCE_THRESHOLD 25 -#define LOWER_SURGE_LIMIT 100 to 150 -#define MIDDLE_SURGE_LIMIT 151 to 200 -#define UPPER_SURGE_LIMIT 201 to 250 -/** - * Supermatter Surge - * - * A very simple event designed to give engineering a challenge. It simply increases the supermatters power by a set amount, and announces it. - * - * This should be entirely fine for a powerful setup, but will require intervention on a lower power setup. - */ - -/datum/round_event_control/supermatter_surge - name = "Supermatter Surge" - typepath = /datum/round_event/supermatter_surge - category = EVENT_CATEGORY_ENGINEERING - max_occurrences = 4 - earliest_start = 30 MINUTES - description = "The supermatter will increase in power by a random amount, and announce it." - -/datum/round_event/supermatter_surge - announce_when = 1 - end_when = SUPERMATTER_SURGE_TIME_LOWER - /// How powerful is the supermatter surge going to be? Set in setup. - var/surge_power = SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER - var/starting_surge_power = 0 - /// Typecasted reference to the supermatter chosen at the events start. Prevents the engine from going AWOL if it changes for some reason. - var/obj/machinery/power/supermatter_crystal/our_main_engine - -/datum/round_event/supermatter_surge/setup() - our_main_engine = GLOB.main_supermatter_engine - surge_power = rand(SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER, SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_UPPER) - starting_surge_power = our_main_engine.bullet_energy - end_when = rand(SUPERMATTER_SURGE_TIME_LOWER, SUPERMATTER_SURGE_TIME_UPPER) - -/datum/round_event/supermatter_surge/announce() - if(surge_power > SUPERMATTER_SURGE_ANNOUNCE_THRESHOLD || prob(round(surge_power))) - priority_announce("Class [get_surge_level()] supermatter surge detected. Intervention may be required.", "Anomaly Alert", ANNOUNCER_KLAXON) - -/datum/round_event/supermatter_surge/proc/get_surge_level() - switch(surge_power) - if(LOWER_SURGE_LIMIT) - return 4 - if(MIDDLE_SURGE_LIMIT) - return 3 - if(UPPER_SURGE_LIMIT) - return 2 - else - return 1 - -/datum/round_event/supermatter_surge/start() - our_main_engine?.bullet_energy *= surge_power - -/datum/round_event/supermatter_surge/end() - our_main_engine?.bullet_energy = starting_surge_power - priority_announce("The supermatter surge has dissipated.", "Anomaly Cleared") - our_main_engine = null - -#undef SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_UPPER -#undef SUPERMATTER_SURGE_BULLET_ENERGY_FACTOR_LOWER -#undef SUPERMATTER_SURGE_TIME_UPPER -#undef SUPERMATTER_SURGE_TIME_LOWER -#undef SUPERMATTER_SURGE_ANNOUNCE_THRESHOLD -#undef LOWER_SURGE_LIMIT -#undef MIDDLE_SURGE_LIMIT -#undef UPPER_SURGE_LIMIT diff --git a/sound/machines/engine_alert3.ogg b/sound/machines/engine_alert3.ogg new file mode 100644 index 00000000000..394bfed2a13 Binary files /dev/null and b/sound/machines/engine_alert3.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 0850981fe74..8a6e71cba1c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3683,6 +3683,7 @@ #include "code\modules\events\shuttle_insurance.dm" #include "code\modules\events\spider_infestation.dm" #include "code\modules\events\stray_cargo.dm" +#include "code\modules\events\supermatter_surge.dm" #include "code\modules\events\tram_malfunction.dm" #include "code\modules\events\vent_clog.dm" #include "code\modules\events\wisdomcow.dm" @@ -7478,7 +7479,6 @@ #include "modular_skyrat\modules\subsystems\code\ticket_ping\adminhelp.dm" #include "modular_skyrat\modules\subsystems\code\ticket_ping\preference.dm" #include "modular_skyrat\modules\subsystems\code\ticket_ping\ticket_ss.dm" -#include "modular_skyrat\modules\supermatter_surge\code\supermatter_surge.dm" #include "modular_skyrat\modules\Syndie_edits\code\area.dm" #include "modular_skyrat\modules\Syndie_edits\code\syndie_edits.dm" #include "modular_skyrat\modules\synths\code\bodyparts\brain.dm"