diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 95efebbc629..d3b9a58168a 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -30,7 +30,6 @@ var/list/modes = list() // allowed modes var/list/votable_modes = list() // votable modes var/list/probabilities = list() // relative probability of each mode - var/allow_random_events = 0 // enables random events mid-round when set to 1 var/respawn = 0 var/guest_jobban = 1 var/panic_bunker_threshold = 150 // above this player count threshold, never-before-seen players are blocked from connecting @@ -120,19 +119,6 @@ var/default_laws = 0 //Controls what laws the AI spawns with. - var/const/minutes_to_ticks = 60 * 10 - // Event settings - var/expected_round_length = 60 * 2 * minutes_to_ticks // 2 hours - // If the first delay has a custom start time - // No custom time, no custom time, between 80 to 100 minutes respectively. - var/list/event_first_run = list(EVENT_LEVEL_MUNDANE = null, EVENT_LEVEL_MODERATE = null, EVENT_LEVEL_MAJOR = list("lower" = 48000, "upper" = 60000)) - // The lowest delay until next event - // 10, 30, 50 minutes respectively - var/list/event_delay_lower = list(EVENT_LEVEL_MUNDANE = 6000, EVENT_LEVEL_MODERATE = 18000, EVENT_LEVEL_MAJOR = 30000) - // The upper delay until next event - // 15, 45, 70 minutes respectively - var/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 9000, EVENT_LEVEL_MODERATE = 27000, EVENT_LEVEL_MAJOR = 42000) - var/starlight = 0 // Whether space turfs have ambient light or not var/allow_holidays = 0 @@ -372,10 +358,6 @@ else log_config("Incorrect probability configuration definition: [prob_name] [prob_value].") - if("allow_random_events") - config.allow_random_events = 1 - - if("forbid_singulo_possession") forbid_singulo_possession = 1 @@ -427,33 +409,6 @@ if("max_maint_drones") config.max_maint_drones = text2num(value) - if("expected_round_length") - config.expected_round_length = text2num(value) MINUTES - - if("event_custom_start_mundane") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES) - - if("event_custom_start_moderate") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES) - - if("event_custom_start_major") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES) - - if("event_delay_lower") - var/values = text2numlist(value, ";") - config.event_delay_lower[EVENT_LEVEL_MUNDANE] = values[1] MINUTES - config.event_delay_lower[EVENT_LEVEL_MODERATE] = values[2] MINUTES - config.event_delay_lower[EVENT_LEVEL_MAJOR] = values[3] MINUTES - - if("event_delay_upper") - var/values = text2numlist(value, ";") - config.event_delay_upper[EVENT_LEVEL_MUNDANE] = values[1] MINUTES - config.event_delay_upper[EVENT_LEVEL_MODERATE] = values[2] MINUTES - config.event_delay_upper[EVENT_LEVEL_MAJOR] = values[3] MINUTES - if("starlight") config.starlight = 1 diff --git a/code/controllers/configuration/__config_defines.dm b/code/controllers/configuration/__config_defines.dm index 9f34b875a2d..03d7622edd1 100644 --- a/code/controllers/configuration/__config_defines.dm +++ b/code/controllers/configuration/__config_defines.dm @@ -14,6 +14,12 @@ target = text2num(input)\ } +/// Wrapper to not overwrite a variable if a list key doesnt exist. Auto casts to number, and accepts a macro argument for number maths (ds to min for example) +#define CONFIG_LOAD_NUM_MULT(target, input, multiplier) \ + if(!isnull(input)) {\ + target = text2num(input) multiplier\ + } + /// Wrapper to not overwrite a variable if a list key doesnt exist. Auto casts to string. #define CONFIG_LOAD_STR(target, input) \ if(!isnull(input)) {\ diff --git a/code/controllers/configuration/configuration_core.dm b/code/controllers/configuration/configuration_core.dm index 9d7eaaa1fce..9f2d60d74f5 100644 --- a/code/controllers/configuration/configuration_core.dm +++ b/code/controllers/configuration/configuration_core.dm @@ -15,6 +15,8 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new()) var/datum/configuration_section/database_configuration/database /// Holder for the Discord configuration datum var/datum/configuration_section/discord_configuration/discord + /// Holder for the Event configuration datum + var/datum/configuration_section/event_configuration/event /// Holder for the gateway configuration datum var/datum/configuration_section/gateway_configuration/gateway /// Holder for the job configuration datum @@ -45,6 +47,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new()) custom_sprites = new() database = new() discord = new() + event = new() gateway = new() jobs = new() logging = new() @@ -65,6 +68,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new()) custom_sprites.load_data(raw_config_data["custom_sprites_configuration"]) database.load_data(raw_config_data["database_configuration"]) discord.load_data(raw_config_data["discord_configuration"]) + event.load_data(raw_config_data["event_configuration"]) gateway.load_data(raw_config_data["gateway_configuration"]) jobs.load_data(raw_config_data["job_configuration"]) logging.load_data(raw_config_data["logging_configuration"]) diff --git a/code/controllers/configuration/sections/event_configuration.dm b/code/controllers/configuration/sections/event_configuration.dm new file mode 100644 index 00000000000..d169a92406d --- /dev/null +++ b/code/controllers/configuration/sections/event_configuration.dm @@ -0,0 +1,61 @@ +/// Config holder for all stuff relating to ingame random events +/datum/configuration_section/event_configuration + /// Do we want to enable random events at all + var/enable_random_events = TRUE + /// Assoc list of when the first event in a group can run. key: severity | value: assoc list with upper and low bounds (key: "upper"/"lower" | value: time in deciseconds) + var/list/first_run_times = list( + EVENT_LEVEL_MUNDANE = null, + EVENT_LEVEL_MODERATE = null, + EVENT_LEVEL_MAJOR = list("lower" = 40 MINUTES, "upper" = 50 MINUTES) + ) // <---- Whoever designed this needs to be shot + + /// Assoc list of lower bounds of event delays. key: severity | value: delay (deciseconds) + var/list/delay_lower_bound = list( + EVENT_LEVEL_MUNDANE = 5 MINUTES, + EVENT_LEVEL_MODERATE = 15 MINUTES, + EVENT_LEVEL_MAJOR = 25 MINUTES + ) + /// Assoc list of lower bounds of event delays. key: severity | value: delay (deciseconds) + var/list/delay_upper_bound = list( + EVENT_LEVEL_MUNDANE = 7.5 MINUTES, + EVENT_LEVEL_MODERATE = 22.5 MINUTES, + EVENT_LEVEL_MAJOR = 35 MINUTES + ) + /// Expected time of a round in deciseconds + var/expected_round_length = 120 MINUTES // This macro is equivilent to 72,000 deciseconds + +/datum/configuration_section/event_configuration/load_data(list/data) + // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line + CONFIG_LOAD_BOOL(enable_random_events, data["allow_random_events"]) + + // Wrapper cant be used here due to it being multiplied + if(isnum(data["expected_round_length"])) + expected_round_length = data["expected_round_length"] MINUTES // Convert from minutes to deciseconds + + // Load event severities. This is quite awful but needs to be done so we can account for config mistakes. This event system is awful + if(islist(data["event_delay_lower_bounds"])) + CONFIG_LOAD_NUM_MULT(delay_lower_bound[EVENT_LEVEL_MUNDANE], data["event_delay_lower_bounds"]["mundane"], MINUTES) + CONFIG_LOAD_NUM_MULT(delay_lower_bound[EVENT_LEVEL_MODERATE], data["event_delay_lower_bounds"]["moderate"], MINUTES) + CONFIG_LOAD_NUM_MULT(delay_lower_bound[EVENT_LEVEL_MAJOR], data["event_delay_lower_bounds"]["major"], MINUTES) + + // Same here. I hate this. + if(islist(data["event_delay_upper_bounds"])) + CONFIG_LOAD_NUM_MULT(delay_upper_bound[EVENT_LEVEL_MUNDANE], data["event_delay_upper_bounds"]["mundane"], MINUTES) + CONFIG_LOAD_NUM_MULT(delay_upper_bound[EVENT_LEVEL_MODERATE], data["event_delay_upper_bounds"]["moderate"], MINUTES) + CONFIG_LOAD_NUM_MULT(delay_upper_bound[EVENT_LEVEL_MAJOR], data["event_delay_upper_bounds"]["major"], MINUTES) + + // And for the worst, the first run delays. I hate this so much -aa07 + if(islist(data["event_initial_delays"])) + for(var/list/assoclist in data["event_initial_delays"]) + var/target = null + switch(assoclist["severity"]) + if("mundane") + target = EVENT_LEVEL_MUNDANE + if("moderate") + target = EVENT_LEVEL_MODERATE + if("major") + target = EVENT_LEVEL_MAJOR + ASSERT(target in list(EVENT_LEVEL_MUNDANE, EVENT_LEVEL_MODERATE, EVENT_LEVEL_MAJOR)) + first_run_times[target] = list("lower" = assoclist["lower_bound"] MINUTES, "upper" = assoclist["upper_bound"] MINUTES) + + diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 484bd321bf1..507a5da0cb9 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -939,14 +939,14 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!check_rights(R_SERVER|R_EVENT)) return - if(!config.allow_random_events) - config.allow_random_events = 1 + if(!GLOB.configuration.event.enable_random_events) + GLOB.configuration.event.enable_random_events = TRUE to_chat(usr, "Random events enabled") - message_admins("Admin [key_name_admin(usr)] has enabled random events.", 1) + message_admins("Admin [key_name_admin(usr)] has enabled random events.") else - config.allow_random_events = 0 + GLOB.configuration.event.enable_random_events = FALSE to_chat(usr, "Random events disabled") - message_admins("Admin [key_name_admin(usr)] has disabled random events.", 1) + message_admins("Admin [key_name_admin(usr)] has disabled random events.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Random Events") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/reset_all_tcs() diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 11c63f0a257..dc29fb203cc 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -29,7 +29,8 @@ GLOBAL_LIST_EMPTY(event_last_fired) if(delayed) next_event_time += (world.time - last_world_time) else if(world.time > next_event_time) - start_event() + if(GLOB.configuration.event.enable_random_events) + start_event() last_world_time = world.time @@ -66,7 +67,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) for(var/event_meta in last_event_time) if(possible_events[event_meta]) var/time_passed = world.time - GLOB.event_last_fired[event_meta] - var/weight_modifier = max(0, (config.expected_round_length - time_passed) / 300) + var/weight_modifier = max(0, (GLOB.configuration.event.expected_round_length - time_passed) / 300) var/new_weight = max(possible_events[event_meta] - weight_modifier, 0) if(new_weight) @@ -84,9 +85,9 @@ GLOBAL_LIST_EMPTY(event_last_fired) /datum/event_container/proc/set_event_delay() // If the next event time has not yet been set and we have a custom first time start - if(next_event_time == 0 && config.event_first_run[severity]) - var/lower = config.event_first_run[severity]["lower"] - var/upper = config.event_first_run[severity]["upper"] + if(next_event_time == 0 && GLOB.configuration.event.first_run_times[severity]) + var/lower = GLOB.configuration.event.first_run_times[severity]["lower"] + var/upper = GLOB.configuration.event.first_run_times[severity]["upper"] var/event_delay = rand(lower, upper) next_event_time = world.time + event_delay // Otherwise, follow the standard setup process @@ -110,7 +111,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) playercount_modifier = playercount_modifier * delay_modifier - var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier + var/event_delay = rand(GLOB.configuration.event.delay_lower_bound[severity], GLOB.configuration.event.delay_upper_bound[severity]) * playercount_modifier next_event_time = world.time + event_delay log_debug("Next event of severity [GLOB.severity_to_string[severity]] in [(next_event_time - world.time)/600] minutes.") diff --git a/config/example/config.toml b/config/example/config.toml index 2c6533ce1bf..4cdecd20903 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -203,7 +203,8 @@ event_delay_lower_bounds = {mundane = 10, moderate = 30, major = 50} event_delay_upper_bounds = {mundane = 15, moderate = 45, major = 70} # Expected round length in minutes. Changes event weights expected_round_length = 120 -# Initial delays for the first events firing off. If any of these are commented, a random value based on above thresholds is used +# Initial delays for the first events firing off. If any of these are commented, a random value based on above thresholds is used. +# You must specify an upper and lower bound, or the code cries a lot. The events system is so bad good god. event_initial_delays = [ #{severity = "mundane", lower_bound = 10, upper_bound = 15}, {severity = "moderate", lower_bound = 25, upper_bound = 40}, diff --git a/paradise.dme b/paradise.dme index c3b0cb582b4..f42a6bff02b 100644 --- a/paradise.dme +++ b/paradise.dme @@ -190,6 +190,7 @@ #include "code\controllers\configuration\sections\custom_sprites_configuration.dm" #include "code\controllers\configuration\sections\database_configuration.dm" #include "code\controllers\configuration\sections\discord_configuration.dm" +#include "code\controllers\configuration\sections\event_configuration.dm" #include "code\controllers\configuration\sections\gateway_configuration.dm" #include "code\controllers\configuration\sections\job_configuration.dm" #include "code\controllers\configuration\sections\logging_configuration.dm"