diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 6a1e0b1d851..f3db9bb3159 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -378,3 +378,5 @@ /datum/config_entry/number/monkeycap config_entry_value = 64 min_val = 0 + +/datum/config_entry/flag/dynamic_config_enabled diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index cb7250f8109..ee23ba9464e 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -107,6 +107,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/highlander_executed = FALSE /// If a only ruleset has been executed. var/only_ruleset_executed = FALSE + /// Dynamic configuration, loaded on pre_setup + var/list/configuration = null /datum/game_mode/dynamic/admin_panel() var/list/dat = list("Game Mode Panel

Game Mode Panel

") @@ -287,6 +289,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) return TRUE /datum/game_mode/dynamic/pre_setup() + if(CONFIG_GET(flag/dynamic_config_enabled)) + var/json_file = file("config/dynamic.json") + if(fexists(json_file)) + configuration = json_decode(file2text(json_file)) for (var/rule in subtypesof(/datum/dynamic_ruleset)) var/datum/dynamic_ruleset/ruleset = new rule() // Simple check if the ruleset should be added to the lists. @@ -300,6 +306,17 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if ("Midround") if (ruleset.weight) midround_rules += ruleset + if(configuration) + if(!configuration[ruleset.ruletype]) + continue + if(!configuration[ruleset.ruletype][ruleset.name]) + continue + var/rule_conf = configuration[ruleset.ruletype][ruleset.name] + for(var/variable in rule_conf) + if(!ruleset.vars[variable]) + stack_trace("Invalid dynamic configuration variable [variable] in [ruleset.ruletype] [ruleset.name]") + ruleset.vars[variable] = rule_conf[variable] + for(var/mob/dead/new_player/player in GLOB.player_list) if(player.ready == PLAYER_READY_TO_PLAY && player.mind) roundstart_pop_ready++ diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 2e0a25f09dc..fe4aa64304c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -92,7 +92,7 @@ return (threat_level >= high_population_requirement) else pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement - var/indice_pop = min(10,round(population/pop_per_requirement)+1) + var/indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) return (threat_level >= requirements[indice_pop]) /// This is called if persistent variable is true everytime SSTicker ticks. diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 9e4a82a1a8f..e2c4f5ca8cd 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -313,14 +313,14 @@ cost = 35 requirements = list(90,90,90,80,60,40,30,20,10,10) high_population_requirement = 10 - var/operative_cap = list(2,2,3,3,4,5,5,5,5,5) + var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5) var/datum/team/nuclear/nuke_team flags = HIGHLANDER_RULESET /datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) return FALSE // Unavailable if nuke ops were already sent at roundstart - var/indice_pop = min(10,round(living_players.len/5)+1) + var/indice_pop = min(operative_cap.len, round(living_players.len/5)+1) required_candidates = operative_cap[indice_pop] return ..() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 56532ef5146..cd839214057 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -200,16 +200,16 @@ requirements = list(100,90,80,60,40,30,10,10,10,10) high_population_requirement = 10 flags = HIGHLANDER_RULESET - var/cultist_cap = list(2,2,2,3,3,4,4,4,4,4) + var/list/cultist_cap = list(2,2,2,3,3,4,4,4,4,4) var/datum/team/cult/main_cult /datum/dynamic_ruleset/roundstart/bloodcult/ready(forced = FALSE) - var/indice_pop = min(10,round(mode.roundstart_pop_ready/pop_per_requirement)+1) + var/indice_pop = min(cultist_cap.len, round(mode.roundstart_pop_ready/pop_per_requirement)+1) required_candidates = cultist_cap[indice_pop] . = ..() /datum/dynamic_ruleset/roundstart/bloodcult/pre_execute() - var/indice_pop = min(10,round(mode.roundstart_pop_ready/pop_per_requirement)+1) + var/indice_pop = min(cultist_cap.len, round(mode.roundstart_pop_ready/pop_per_requirement)+1) var/cultists = cultist_cap[indice_pop] for(var/cultists_number = 1 to cultists) if(candidates.len <= 0) @@ -258,18 +258,18 @@ requirements = list(90,90,90,80,60,40,30,20,10,10) high_population_requirement = 10 flags = HIGHLANDER_RULESET - var/operative_cap = list(2,2,2,3,3,3,4,4,5,5) + var/list/operative_cap = list(2,2,2,3,3,3,4,4,5,5) var/datum/team/nuclear/nuke_team /datum/dynamic_ruleset/roundstart/nuclear/ready(forced = FALSE) - var/indice_pop = min(10,round(mode.roundstart_pop_ready/pop_per_requirement)+1) + var/indice_pop = min(operative_cap.len,round(mode.roundstart_pop_ready/pop_per_requirement)+1) required_candidates = operative_cap[indice_pop] . = ..() /datum/dynamic_ruleset/roundstart/nuclear/pre_execute() // If ready() did its job, candidates should have 5 or more members in it - var/indice_pop = min(10,round(mode.roundstart_pop_ready/5)+1) + var/indice_pop = min(operative_cap.len, round(mode.roundstart_pop_ready/5)+1) var/operatives = operative_cap[indice_pop] for(var/operatives_number = 1 to operatives) if(candidates.len <= 0) diff --git a/config/dynamic.json b/config/dynamic.json new file mode 100644 index 00000000000..f396d16403b --- /dev/null +++ b/config/dynamic.json @@ -0,0 +1,36 @@ +{ + "Roundstart": { + "Traitors": { + "cost": 10, + "weight": 5, + "required_candidates": 1, + "high_population_requirement": 10, + "minimum_required_aged": 0, + "requirements": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "protected_roles": [ + "Security Officer", + "Warden", + "Detective", + "Head of Security", + "Captain" + ], + "restricted_roles": [ + "Cyborg" + ], + "autotraitor_cooldown": 450 + } + }, + "Midround": {}, + "Latejoin": {} +} diff --git a/config/game_options.txt b/config/game_options.txt index 409f3599da6..82d6781708c 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -254,6 +254,9 @@ MAX_TICKETS_PER_ROLL 100 ## Uncomment to allow players to see the set odds of different rounds in secret/random in the get server revision screen. This will NOT tell the current roundtype. #SHOW_GAME_TYPE_ODDS +## Uncomment to enable dynamic ruleset config file. +DYNAMIC_CONFIG_ENABLED + ## RANDOM EVENTS ### ## Comment this out to disable random events during the round. ALLOW_RANDOM_EVENTS