From 917c230ae2c547f09f3b5ef8164e3ca8ec6868c7 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 14 Dec 2020 18:14:03 -0800 Subject: [PATCH 01/16] Makes grab bag ONLY make station antags. --- .../gamemodes/dynamic/dynamic_storytellers.dm | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index d5766b287e..b6e5377add 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -365,6 +365,33 @@ Property weights are added to the config weight of the ruleset. They are: /datum/dynamic_storyteller/grabbag/minor_start_chance() return 100 +/datum/dynamic_storyteller/grabbag/minor_draft() + var/list/original_rules = ..() + var/list/drafted_rules = list() + for(var/R in original_rules) + var/datum/dynamic_ruleset/rule = R + if(rule.flags & MINOR_RULESET) + drafted_rules += R + return drafted_rules + +/datum/dynamic_storyteller/grabbag/midround_draft() + var/list/original_rules = ..() + var/list/drafted_rules = list() + for(var/R in original_rules) + var/datum/dynamic_ruleset/rule = R + if(rule.flags & MINOR_RULESET) + drafted_rules += R + return drafted_rules + +/datum/dynamic_storyteller/grabbag/latejoin_draft() + var/list/original_rules = ..() + var/list/drafted_rules = list() + for(var/R in original_rules) + var/datum/dynamic_ruleset/rule = R + if(rule.flags & MINOR_RULESET) + drafted_rules += R + return drafted_rules + /datum/dynamic_storyteller/liteextended name = "Calm" config_tag = "calm" From f4d15f189b049a52c66c452954e3f997f0b640ec Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 14 Dec 2020 18:38:11 -0800 Subject: [PATCH 02/16] Also made alien threat WAY higher. --- code/modules/antagonists/xeno/xeno.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/antagonists/xeno/xeno.dm b/code/modules/antagonists/xeno/xeno.dm index f10506a0d9..1468a5a97b 100644 --- a/code/modules/antagonists/xeno/xeno.dm +++ b/code/modules/antagonists/xeno/xeno.dm @@ -17,16 +17,16 @@ threat = 3 /datum/antagonist/xeno/threat() - . = 1 + . = 3 if(isalienhunter(owner)) - . = 2 + . = 6 else if(isaliensentinel(owner)) - . = 4 + . = 12 else if(isalienroyal(owner)) if(isalienqueen(owner)) - . = 8 + . = 24 else - . = 6 + . = 18 /datum/antagonist/xeno/create_team(datum/team/xeno/new_team) if(!new_team) From 7adc97027aaafed5377f846234d05b63ff538eb3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 14 Dec 2020 22:18:27 -0800 Subject: [PATCH 03/16] oop --- code/game/gamemodes/dynamic/dynamic_storytellers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index b6e5377add..84407ecce8 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -365,7 +365,7 @@ Property weights are added to the config weight of the ruleset. They are: /datum/dynamic_storyteller/grabbag/minor_start_chance() return 100 -/datum/dynamic_storyteller/grabbag/minor_draft() +/datum/dynamic_storyteller/grabbag/minor_rule_draft() var/list/original_rules = ..() var/list/drafted_rules = list() for(var/R in original_rules) From e0d7699e273bef0fc6e970c06e1484de0d44b2f1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 15 Dec 2020 18:48:59 -0800 Subject: [PATCH 04/16] Made vote only use runnable storytellers. --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 06b76718c1..880802fd5c 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -492,7 +492,7 @@ SUBSYSTEM_DEF(vote) if("dynamic") GLOB.master_mode = "dynamic" var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight) - for(var/T in config.storyteller_cache) + for(var/T in config.get_runnable_storytellers()) var/datum/dynamic_storyteller/S = T var/probability = ((initial(S.config_tag) in probabilities) ? probabilities[initial(S.config_tag)] : initial(S.weight)) if(probability > 0) From bdd5fc777f1fff94ea0c7a8c475095c6b720e989 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 15 Dec 2020 19:14:15 -0800 Subject: [PATCH 05/16] Added an indicator of how many iterations were done. --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 836b00250f..78821a881e 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -439,7 +439,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) potential_minor_rulesets -= rule update_playercounts() iterations++ - message_admins("Minor antag roundstart rolls completed, with [num_rulesets_executed] antags or antag teams made.") + message_admins("Minor antag roundstart rolls completed, with [iterations] rolls done and [num_rulesets_executed] antags or antag teams made.") log_game("DYNAMIC: Minor antag roundstart made [num_rulesets_executed] antags or antag teams.") From 6f0075e60655ee21dd6585b1def1fefd0a719b60 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 17 Dec 2020 22:44:35 -0800 Subject: [PATCH 06/16] Made minor roundstarts actually work. --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- .../dynamic/dynamic_rulesets_minor.dm | 43 +++++++++++++++++++ .../gamemodes/dynamic/dynamic_storytellers.dm | 1 - 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 78821a881e..f57dda877c 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -415,7 +415,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) /datum/game_mode/dynamic/post_setup(report) update_playercounts() if(minor_ruleset_start) - addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/minor_roundstart),rand(1 MINUTES,5 MINUTES)) + addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/minor_roundstart),rand(1 MINUTES,3 MINUTES)) else for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules) addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_roundstart_rule, rule), rule.delay) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm index 618befbaa7..74a61bd3ff 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm @@ -1,3 +1,46 @@ +/datum/dynamic_ruleset/minor/proc/trim_list(list/L = list()) + var/list/trimmed_list = L.Copy() + for(var/mob/M in trimmed_list) + if (!ishuman(M)) + trimmed_list.Remove(M) + continue + if (HAS_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG)) + trimmed_list.Remove(M) + continue + if (!M.client) // Are they connected? + trimmed_list.Remove(M) + continue + if(!mode.check_age(M.client, minimum_required_age)) + trimmed_list.Remove(M) + continue + if(antag_flag_override) + if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override)) + trimmed_list.Remove(M) + continue + else + if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag)) + trimmed_list.Remove(M) + continue + if (M.mind) + if ((M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])) // Are they playing a ghost role? + trimmed_list.Remove(M) + continue + if (M.mind.assigned_role in restricted_roles) // Does their job allow it? + trimmed_list.Remove(M) + continue + if ((exclusive_roles.len > 0) && !(M.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job? + trimmed_list.Remove(M) + continue + return trimmed_list + +/datum/dynamic_ruleset/minor/trim_candidates() + // + // All you need to know is that here, the candidates list contains 4 lists itself, indexed with the following defines: + // Candidates = list(CURRENT_LIVING_PLAYERS, CURRENT_LIVING_ANTAGS, CURRENT_DEAD_PLAYERS, CURRENT_OBSERVERS) + // So for example you can get the list of all current dead players with var/list/dead_players = candidates[CURRENT_DEAD_PLAYERS] + // Make sure to properly typecheck the mobs in those lists, as the dead_players list could contain ghosts, or dead players still in their bodies. + // We're still gonna trim the obvious (mobs without clients, jobbanned players, etc) + candidates = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) ////////////////////////////////////////////// // // diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index 84407ecce8..1ebbfdacc3 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -128,7 +128,6 @@ Property weights are added to the config weight of the ruleset. They are: var/list/drafted_rules = list() for (var/datum/dynamic_ruleset/minor/rule in mode.minor_rules) if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level)) - rule.candidates = mode.candidates.Copy() rule.trim_candidates() if (rule.ready() && rule.candidates.len > 0) var/property_weight = 0 From dd61efbc60dd9eb174a7b01b01cf539ee0f6a3f6 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 17 Dec 2020 23:29:25 -0800 Subject: [PATCH 07/16] Made dynamic respect midround antag setting (HOW) --- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 416721702b..7ce6e74cc1 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -48,6 +48,9 @@ if (!M.client) // Are they connected? trimmed_list.Remove(M) continue + if(M.client.prefs && M.client.prefs.toggles & MIDROUND_ANTAG) + trimmed_list.Remove(M) + continue if(!mode.check_age(M.client, minimum_required_age)) trimmed_list.Remove(M) continue From 5c7ddaeeddcc1dbaac9d6b80bb30cfe47b18b8af Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 17 Dec 2020 23:43:17 -0800 Subject: [PATCH 08/16] Makes nightmare dynamic-controlled --- code/modules/events/nightmare.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/events/nightmare.dm b/code/modules/events/nightmare.dm index 698f5130f1..97a10c930a 100644 --- a/code/modules/events/nightmare.dm +++ b/code/modules/events/nightmare.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/ghost_role/nightmare max_occurrences = 1 min_players = 20 + gamemode_blacklist = list("dynamic") /datum/round_event/ghost_role/nightmare minimum_required = 1 From 5e8f76792ee65ec5168366ce6382c90027a07ade Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 18 Dec 2020 20:24:30 -0800 Subject: [PATCH 09/16] Readjusted weight; added min/max config options --- .../configuration/configuration.dm | 9 ++++++ .../configuration/entries/dynamic.dm | 12 +++++++- .../gamemodes/dynamic/dynamic_storytellers.dm | 28 ++++++++++++------- config/dynamic_config.txt | 9 ++++-- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 0fd09d297d..9d5110daf5 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -388,6 +388,8 @@ Example config: var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight) var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players) + var/list/storyteller_min_chaos = Get(/datum/config_entry/keyed_list/storyteller_min_chaos) + var/list/storyteller_max_chaos = Get(/datum/config_entry/keyed_list/storyteller_max_chaos) for(var/T in storyteller_cache) var/datum/dynamic_storyteller/S = T var/config_tag = initial(S.config_tag) @@ -399,6 +401,13 @@ Example config: continue if(length(GLOB.player_list) < min_players) continue + if(!Get(/datum/config_entry/flag/no_storyteller_threat_removal)) + var/min_chaos = (probabilities in storyteller_min_chaos) ? storyteller_min_chaos[config_tag] : initial(S.min_chaos) + var/max_chaos = (probabilities in storyteller_max_chaos) ? storyteller_max_chaos[config_tag] : initial(S.max_chaos) + if(SSpersistence.average_dynamic_threat < min_chaos) + continue + if(SSpersistence.average_dynamic_threat > max_chaos) + continue if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len) var/name = initial(S.name) var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 44d9a041a6..1f16c1db2d 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -1,5 +1,7 @@ /datum/config_entry/flag/dynamic_voting +/datum/config_entry/flag/no_storyteller_threat_removal + /datum/config_entry/number/dynamic_high_pop_limit config_entry_value = 55 min_val = 1 @@ -74,7 +76,7 @@ /datum/config_entry/number/dynamic_hijack_cost config_entry_value = 5 - + /datum/config_entry/number/dynamic_glorious_death_cost config_entry_value = 5 @@ -96,3 +98,11 @@ /datum/config_entry/keyed_list/storyteller_min_players key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM + +/datum/config_entry/keyed_list/storyteller_min_chaos + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + +/datum/config_entry/keyed_list/storyteller_max_chaos + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index 1ebbfdacc3..56a80c6e72 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -15,7 +15,9 @@ */ var/flags = 0 var/dead_player_weight = 1 // How much dead players matter for threat calculation - var/weight = 3 // Weights for randomly picking storyteller. Multiplied by score after voting. + var/weight = 0 // Weights for randomly picking storyteller. Multiplied by score after voting. + var/min_chaos = -1000 // Won't show up if recent rounds have been below this chaotic on average + var/max_chaos = 1000 // Won't show up if recent rounds have been above this chaotic on average var/event_frequency_lower = 6 MINUTES // How rare events will be, at least. var/event_frequency_upper = 20 MINUTES // How rare events will be, at most. var/min_players = -1 // How many players are required for this one to start. @@ -212,6 +214,7 @@ Property weights are added to the config weight of the ruleset. They are: weight = 1 event_frequency_lower = 2 MINUTES event_frequency_upper = 10 MINUTES + max_chaos = 50 flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON min_players = 30 var/refund_cooldown = 0 @@ -234,12 +237,13 @@ Property weights are added to the config weight of the ruleset. They are: desc = "Modes where the crew must band together. Nukies, xenos, blob. Only one antag threat at once." curve_centre = 2 curve_width = 1.5 - weight = 2 + weight = 4 + max_chaos = 75 min_players = 20 flags = WAROPS_ALWAYS_ALLOWED | USE_PREV_ROUND_WEIGHTS property_weights = list("valid" = 3, "trust" = 5) -/datum/dynamic_storyteller/chaotic/minor_start_chance() +/datum/dynamic_storyteller/team/minor_start_chance() return 0 /datum/dynamic_storyteller/team/should_inject_antag(dry_run = FALSE) @@ -255,13 +259,14 @@ Property weights are added to the config weight of the ruleset. They are: flags = WAROPS_ALWAYS_ALLOWED property_weights = list("valid" = 1, "conversion" = 20) -/datum/dynamic_storyteller/chaotic/minor_start_chance() +/datum/dynamic_storyteller/conversion/minor_start_chance() return 0 /datum/dynamic_storyteller/random name = "Random" config_tag = "random" weight = 1 + max_chaos = 60 desc = "No weighting at all; every ruleset has the same chance of happening. Cooldowns vary wildly. As random as it gets." /datum/dynamic_storyteller/random/on_start() @@ -274,7 +279,7 @@ Property weights are added to the config weight of the ruleset. They are: /datum/dynamic_storyteller/random/should_inject_antag() return prob(50) -/datum/dynamic_storyteller/chaotic/minor_start_chance() +/datum/dynamic_storyteller/random/minor_start_chance() return 20 /datum/dynamic_storyteller/random/roundstart_draft() @@ -330,7 +335,7 @@ Property weights are added to the config weight of the ruleset. They are: name = "Story" config_tag = "story" desc = "Antags with options for loadouts and gimmicks. Traitor, wizard, nukies." - weight = 2 + weight = 4 curve_width = 2 flags = USE_PREV_ROUND_WEIGHTS property_weights = list("story_potential" = 2) @@ -338,6 +343,7 @@ Property weights are added to the config weight of the ruleset. They are: /datum/dynamic_storyteller/classic name = "Classic" config_tag = "classic" + weight = 8 desc = "No special antagonist weights. Good variety, but not like random. Uses your chaos preference to weight." flags = USE_PREF_WEIGHTS | USE_PREV_ROUND_WEIGHTS @@ -345,7 +351,7 @@ Property weights are added to the config weight of the ruleset. They are: name = "Intrigue" config_tag = "intrigue" desc = "Antags that instill distrust in the crew. Traitors, bloodsuckers." - weight = 2 + weight = 4 curve_width = 2 dead_player_weight = 2 flags = USE_PREV_ROUND_WEIGHTS @@ -358,7 +364,7 @@ Property weights are added to the config weight of the ruleset. They are: name = "Grab Bag" config_tag = "grabbag" desc = "Crew antags (e.g. traitor, changeling, bloodsucker, heretic) only, all mixed together." - weight = 2 + weight = 4 flags = USE_PREF_WEIGHTS | USE_PREV_ROUND_WEIGHTS /datum/dynamic_storyteller/grabbag/minor_start_chance() @@ -398,12 +404,13 @@ Property weights are added to the config weight of the ruleset. They are: curve_centre = -3 curve_width = 0.5 flags = NO_ASSASSIN - weight = 1 + min_chaos = 30 + weight = 3 dead_player_weight = 5 property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "conversion" = -10) /datum/dynamic_storyteller/liteextended/minor_start_chance() - return 100 + return 90 /datum/dynamic_storyteller/no_antag name = "Extended" @@ -411,6 +418,7 @@ Property weights are added to the config weight of the ruleset. They are: desc = "No standard antags." curve_centre = -5 curve_width = 0.5 + min_chaos = 40 flags = NO_ASSASSIN | FORCE_IF_WON weight = 1 property_weights = list("extended" = 2) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index c08b316e2e..480f6d8ed8 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -13,6 +13,9 @@ STORYTELLER_WEIGHT EXTENDED 0 STORYTELLER_MIN_PLAYERS CHAOTIC 30 STORYTELLER_MIN_PLAYERS TEAMWORK 30 +## If this is uncommented, Dynamic won't disable certain storytellers based on recent round threats +#NO_STORYTELLER_THREAT_REMOVAL + ## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected. DYNAMIC_MIDROUND_DELAY_MIN 5 DYNAMIC_MIDROUND_DELAY_MAX 15 @@ -171,8 +174,8 @@ DYNAMIC_COST LATEJOIN_REVOLUTION 20 DYNAMIC_COST LATEJOIN_BLOODSUCKER 10 DYNAMIC_COST LATEJOIN_COLLECTOR 1 -## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. -## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. +## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. +## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. ## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. DYNAMIC_REQUIREMENTS TRAITOR 50 50 50 50 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS TRAITORBRO 101 101 101 101 101 101 101 101 101 101 @@ -301,6 +304,6 @@ DYNAMIC_GLORIOUS_DEATH_COST 5 DYNAMIC_ASSASSINATE_COST 2 ## This requirement uses threat level, rather than current threat, which is why it's higher. -DYNAMIC_WAROPS_REQUIREMENT 60 +DYNAMIC_WAROPS_REQUIREMENT 60 DYNAMIC_WAROPS_COST 10 From f209fec1ee4e81dc74c43ae142ff3bdaacd29276 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 18 Dec 2020 22:19:40 -0800 Subject: [PATCH 10/16] oh, that's why extended is there --- code/controllers/configuration/configuration.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 9d5110daf5..9b04e985f3 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -421,7 +421,7 @@ Example config: /datum/controller/configuration/proc/get_runnable_modes() var/list/datum/game_mode/runnable_modes = new - var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) + var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight) var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop) var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop) var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) From fb31117a8d100673bb3d648013d03c67e534d2c1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 18 Dec 2020 22:36:41 -0800 Subject: [PATCH 11/16] nah nah none of that. --- .../gamemodes/dynamic/dynamic_storytellers.dm | 33 ++----------------- 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index 56a80c6e72..4edfc39a74 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -128,10 +128,10 @@ Property weights are added to the config weight of the ruleset. They are: /datum/dynamic_storyteller/proc/minor_rule_draft() var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/minor/rule in mode.minor_rules) + for (var/datum/dynamic_ruleset/rule in mode.minor_rules) if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level)) rule.trim_candidates() - if (rule.ready() && rule.candidates.len > 0) + if (rule.ready()) var/property_weight = 0 for(var/property in property_weights) if(property in rule.property_weights) // just treat it as 0 if it's not in there @@ -363,40 +363,13 @@ Property weights are added to the config weight of the ruleset. They are: /datum/dynamic_storyteller/grabbag name = "Grab Bag" config_tag = "grabbag" - desc = "Crew antags (e.g. traitor, changeling, bloodsucker, heretic) only, all mixed together." + desc = "Crew antags (e.g. traitor, changeling, bloodsucker, heretic) only at round start, all mixed together." weight = 4 flags = USE_PREF_WEIGHTS | USE_PREV_ROUND_WEIGHTS /datum/dynamic_storyteller/grabbag/minor_start_chance() return 100 -/datum/dynamic_storyteller/grabbag/minor_rule_draft() - var/list/original_rules = ..() - var/list/drafted_rules = list() - for(var/R in original_rules) - var/datum/dynamic_ruleset/rule = R - if(rule.flags & MINOR_RULESET) - drafted_rules += R - return drafted_rules - -/datum/dynamic_storyteller/grabbag/midround_draft() - var/list/original_rules = ..() - var/list/drafted_rules = list() - for(var/R in original_rules) - var/datum/dynamic_ruleset/rule = R - if(rule.flags & MINOR_RULESET) - drafted_rules += R - return drafted_rules - -/datum/dynamic_storyteller/grabbag/latejoin_draft() - var/list/original_rules = ..() - var/list/drafted_rules = list() - for(var/R in original_rules) - var/datum/dynamic_ruleset/rule = R - if(rule.flags & MINOR_RULESET) - drafted_rules += R - return drafted_rules - /datum/dynamic_storyteller/liteextended name = "Calm" config_tag = "calm" From f8409657631c70d3f84040082238f90ccb18e57a Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 19 Dec 2020 18:04:22 -0800 Subject: [PATCH 12/16] no autotraitor, better logging --- code/game/gamemodes/dynamic/dynamic.dm | 2 ++ .../gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 10 ---------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index f57dda877c..724417ec07 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -612,6 +612,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) latejoin_rules = remove_from_list(latejoin_rules, rule.type) else if(rule.ruletype == "Midround") midround_rules = remove_from_list(midround_rules, rule.type) + message_admins("DYNAMIC: Picked [rule]; executing soon...") addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay) return TRUE @@ -663,6 +664,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) /datum/game_mode/dynamic/proc/execute_midround_latejoin_rule(sent_rule) var/datum/dynamic_ruleset/rule = sent_rule if (rule.execute()) + message_admins("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") log_threat("[rule.ruletype] [rule.name] added [rule.cost]", verbose = TRUE) if(rule.flags & HIGHLANDER_RULESET) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index c5e0857461..1be5cb3c57 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -8,7 +8,6 @@ /datum/dynamic_ruleset/roundstart/traitor name = "Traitors" config_tag = "traitor" - persistent = TRUE antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor/ minimum_required_age = 0 @@ -34,15 +33,6 @@ M.mind.restricted_roles = restricted_roles return TRUE -/datum/dynamic_ruleset/roundstart/traitor/rule_process() - if (autotraitor_cooldown > 0) - autotraitor_cooldown-- - else - autotraitor_cooldown = 450 // 15 minutes - message_admins("Checking if we can turn someone into a traitor.") - log_game("DYNAMIC: Checking if we can turn someone into a traitor.") - mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor) - ////////////////////////////////////////// // // // BLOOD BROTHERS // From c47761fa582f9ab5b6fffa647c3339aa1bd0bf43 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 19 Dec 2020 19:30:16 -0800 Subject: [PATCH 13/16] Added a DYNAMIC_THREAT_BASELINE config option. why didn't i do this sooner --- code/controllers/configuration/entries/dynamic.dm | 3 +++ code/game/gamemodes/dynamic/dynamic.dm | 1 + 2 files changed, 4 insertions(+) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 1f16c1db2d..935164352e 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -69,6 +69,9 @@ /datum/config_entry/number/dynamic_third_rule_high_pop_requirement config_entry_value = 70 +/datum/config_entry/number/dynamic_threat_baseline + config_entry_value = 50 + /datum/config_entry/number_list/dynamic_hijack_requirements /datum/config_entry/number/dynamic_hijack_high_population_requirement diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 724417ec07..de85e2b5c5 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -145,6 +145,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) third_rule_req = list(101, 101, 101, 101, 101, 100, 90, 80, 70, 60) high_pop_second_rule_req = CONFIG_GET(number/dynamic_second_rule_high_pop_requirement) high_pop_third_rule_req = CONFIG_GET(number/dynamic_third_rule_high_pop_requirement) + added_threat = CONFIG_GET(number/dynamic_threat_baseline) GLOB.dynamic_high_pop_limit = CONFIG_GET(number/dynamic_high_pop_limit) GLOB.dynamic_latejoin_delay_min = CONFIG_GET(number/dynamic_latejoin_delay_min)*600 GLOB.dynamic_latejoin_delay_max = CONFIG_GET(number/dynamic_latejoin_delay_max)*600 From a3f2ae3333af919a7b9c2ea9799d0698cf1563b3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 19 Dec 2020 20:27:07 -0800 Subject: [PATCH 14/16] i'm such an idiot. --- code/game/gamemodes/dynamic/dynamic_storytellers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index 4edfc39a74..98bc922564 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -103,7 +103,7 @@ Property weights are added to the config weight of the ruleset. They are: /datum/dynamic_storyteller/proc/should_inject_antag(dry_run = FALSE) if(mode.forced_injection) - mode.forced_injection = !dry_run + mode.forced_injection = dry_run return TRUE return mode.threat < mode.threat_level From f9edd8e8ac71e79d75cf06bfb7f797f3ca3ee297 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 19 Dec 2020 20:34:28 -0800 Subject: [PATCH 15/16] Made the previous-round weight-adjust based on max instead of average. --- code/controllers/subsystem/persistence.dm | 2 +- code/game/gamemodes/dynamic/dynamic.dm | 3 +++ code/game/gamemodes/dynamic/dynamic_storytellers.dm | 6 ++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index e1b6e6f6e2..e39242aac3 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -422,7 +422,7 @@ SUBSYSTEM_DEF(persistence) saved_storytellers[3] = saved_storytellers[2] saved_storytellers[2] = saved_storytellers[1] saved_storytellers[1] = mode.storyteller.name - average_dynamic_threat = (mode.threat_average + average_dynamic_threat) / 2 + average_dynamic_threat = (mode.max_threat + average_dynamic_threat) / 2 var/json_file = file("data/RecentStorytellers.json") var/list/file_data = list() file_data["data"] = saved_storytellers + average_dynamic_threat diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index de85e2b5c5..6a16b62643 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -64,6 +64,8 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) var/threat_average_weight = 0 /// Last time a threat average sample was taken. Used for weighting the rolling average. var/last_threat_sample_time = 0 + /// Maximum threat recorded so far, for cross-round chaos adjustment. + var/max_threat = 0 /// Things that cause a rolling threat adjustment to be displayed at roundend. var/list/threat_tallies = list() /// Running information about the threat. Can store text or datum entries. @@ -744,6 +746,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) if(!M.voluntary_ghosted) current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow) threat = storyteller.calculate_threat() + added_threat + max_threat = max(max_threat,threat) if(threat_average_weight) var/cur_sample_weight = world.time - last_threat_sample_time threat_average = ((threat_average * threat_average_weight) + (threat * cur_sample_weight)) / (threat_average_weight + cur_sample_weight) diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index 98bc922564..03aa9d174a 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -21,6 +21,7 @@ var/event_frequency_lower = 6 MINUTES // How rare events will be, at least. var/event_frequency_upper = 20 MINUTES // How rare events will be, at most. var/min_players = -1 // How many players are required for this one to start. + var/soft_antag_ratio_cap = 4 // how many players-per-antag there should be var/datum/game_mode/dynamic/mode = null // Cached as soon as it's made, by dynamic. /** @@ -105,6 +106,8 @@ Property weights are added to the config weight of the ruleset. They are: if(mode.forced_injection) mode.forced_injection = dry_run return TRUE + if(mode.current_players[CURRENT_LIVING_PLAYERS].len < (mode.current_players[CURRENT_LIVING_ANTAGS].len * soft_antag_ratio_cap)) + return FALSE return mode.threat < mode.threat_level /datum/dynamic_storyteller/proc/roundstart_draft() @@ -215,6 +218,7 @@ Property weights are added to the config weight of the ruleset. They are: event_frequency_lower = 2 MINUTES event_frequency_upper = 10 MINUTES max_chaos = 50 + soft_antag_ratio_cap = 1 flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON min_players = 30 var/refund_cooldown = 0 @@ -267,6 +271,7 @@ Property weights are added to the config weight of the ruleset. They are: config_tag = "random" weight = 1 max_chaos = 60 + soft_antag_ratio_cap = 1 desc = "No weighting at all; every ruleset has the same chance of happening. Cooldowns vary wildly. As random as it gets." /datum/dynamic_storyteller/random/on_start() @@ -380,6 +385,7 @@ Property weights are added to the config weight of the ruleset. They are: min_chaos = 30 weight = 3 dead_player_weight = 5 + soft_antag_ratio_cap = 8 property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "conversion" = -10) /datum/dynamic_storyteller/liteextended/minor_start_chance() From 4e6abdec7446fd1e80f1dc1966e2f805a0aa2ff3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 19 Dec 2020 20:51:58 -0800 Subject: [PATCH 16/16] i wish we both die --- code/controllers/configuration/configuration.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 9b04e985f3..9d5110daf5 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -421,7 +421,7 @@ Example config: /datum/controller/configuration/proc/get_runnable_modes() var/list/datum/game_mode/runnable_modes = new - var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight) + var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop) var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop) var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)