diff --git a/code/controllers/subsystem/dynamic/__dynamic_defines.dm b/code/controllers/subsystem/dynamic/__dynamic_defines.dm index f24c772fa24..500666dcd14 100644 --- a/code/controllers/subsystem/dynamic/__dynamic_defines.dm +++ b/code/controllers/subsystem/dynamic/__dynamic_defines.dm @@ -43,6 +43,9 @@ /// Ruleset can be configured by admins (implements /proc/configure_ruleset) /// Only implemented for midrounds currently #define RULESET_ADMIN_CONFIGURABLE (1<<2) +/// Applied to rulesets which intentionally share a pref_flag with another rulesets +/// Denotes multiple rulesets which abide by the same preference, but are each a variation of some base ruleset +#define RULESET_VARIATION (1<<3) /// Href for cancelling midround rulesets before execution #define MIDROUND_CANCEL_HREF(...) "(CANCEL)" diff --git a/code/controllers/subsystem/dynamic/_dynamic_ruleset.dm b/code/controllers/subsystem/dynamic/_dynamic_ruleset.dm index 707c0220ca6..e03f733eb7a 100644 --- a/code/controllers/subsystem/dynamic/_dynamic_ruleset.dm +++ b/code/controllers/subsystem/dynamic/_dynamic_ruleset.dm @@ -10,9 +10,12 @@ /// Don't change this unless you know what you're doing. var/config_tag - /// What flag to check for jobbans? Optional, if unset, uses pref_flag + /// What flag to check for jobbans? + /// Optional, if unset, uses pref_flag for jobbans instead var/jobban_flag - /// What flag to check for prefs? Required if the antag has an associated preference + /// What flag to check for prefs? + /// Required if the antag has an associated preference, and must be unique + /// (unless RULESET_VARIATION is set in ruleset_flags) var/pref_flag /// Flags for this ruleset var/ruleset_flags = NONE diff --git a/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm b/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm index b418f1ade42..6df942b5242 100644 --- a/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm +++ b/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm @@ -658,7 +658,7 @@ candidate_role = "Changeling" pref_flag = ROLE_CHANGELING_MIDROUND jobban_flag = ROLE_CHANGELING - ruleset_flags = RULESET_INVADER + ruleset_flags = RULESET_INVADER|RULESET_VARIATION weight = 5 min_pop = 15 max_antag_cap = 1 @@ -670,6 +670,21 @@ /datum/dynamic_ruleset/midround/from_ghosts/space_changeling/assign_role(datum/mind/candidate) generate_changeling_meteor(candidate) +/datum/dynamic_ruleset/midround/from_ghosts/space_changeling/mass + name = "Mass Space Changelings" + config_tag = "Mass Changelings" + midround_type = HEAVY_MIDROUND + min_pop = 25 + min_antag_cap = 2 + max_antag_cap = 3 + repeatable_weight_decrease = 4 + weight = list( + DYNAMIC_TIER_LOW = 0, + DYNAMIC_TIER_LOWMEDIUM = 3, + DYNAMIC_TIER_MEDIUMHIGH = 4, + DYNAMIC_TIER_HIGH = 5, + ) + /datum/dynamic_ruleset/midround/from_ghosts/paradox_clone name = "Paradox Clone" config_tag = "Paradox Clone" @@ -1064,6 +1079,7 @@ false_alarm_able = TRUE pref_flag = ROLE_SLEEPER_AGENT jobban_flag = ROLE_TRAITOR + ruleset_flags = RULESET_VARIATION weight = 10 min_pop = 3 blacklisted_roles = list( @@ -1079,6 +1095,22 @@ "[command_name()] High-Priority Update", ) +/datum/dynamic_ruleset/midround/from_living/traitor/mass + name = "Mass Traitors" + config_tag = "Mass Traitors" + midround_type = HEAVY_MIDROUND + min_pop = 15 + min_antag_cap = 2 + max_antag_cap = 4 + repeatable_weight_decrease = 8 + blacklisted_roles = list() + weight = list( + DYNAMIC_TIER_LOW = 0, + DYNAMIC_TIER_LOWMEDIUM = 3, + DYNAMIC_TIER_MEDIUMHIGH = 8, + DYNAMIC_TIER_HIGH = 10, + ) + /datum/dynamic_ruleset/midround/from_living/malf_ai name = "Malfunctioning AI" config_tag = "Midround Malfunctioning AI" diff --git a/code/modules/client/preferences/middleware/antags.dm b/code/modules/client/preferences/middleware/antags.dm index dd81ac44760..39948078b11 100644 --- a/code/modules/client/preferences/middleware/antags.dm +++ b/code/modules/client/preferences/middleware/antags.dm @@ -149,11 +149,12 @@ GLOBAL_LIST_INIT(non_ruleset_antagonists, list( for (var/datum/dynamic_ruleset/ruleset as anything in subtypesof(/datum/dynamic_ruleset)) var/datum/antagonist/antagonist_type = initial(ruleset.preview_antag_datum) var/antag_flag = initial(ruleset.pref_flag) - if (isnull(antagonist_type) || isnull(antag_flag)) + if(isnull(antagonist_type) || isnull(antag_flag)) continue - // antag_flag is guaranteed to be unique by unit tests. - antagonists[initial(ruleset.pref_flag)] = antagonist_type + // antag_flag is guaranteed to be unique for all non-RULESET_VARIATION rulesets + // the ||= covers specifically those rulesets - prefer the first one over variations + antagonists[initial(ruleset.pref_flag)] ||= antagonist_type var/list/generated_icons = list() diff --git a/code/modules/unit_tests/dynamic_ruleset_sanity.dm b/code/modules/unit_tests/dynamic_ruleset_sanity.dm index b42b34f99df..a639fb0f837 100644 --- a/code/modules/unit_tests/dynamic_ruleset_sanity.dm +++ b/code/modules/unit_tests/dynamic_ruleset_sanity.dm @@ -30,7 +30,8 @@ continue if (antag_flag in known_antag_flags) - TEST_FAIL("[ruleset] has a non-unique antag_flag [antag_flag] (used by [known_antag_flags[antag_flag]])!") + if(!(initial(ruleset.ruleset_flags) & RULESET_VARIATION)) + TEST_FAIL("[ruleset] has a non-unique antag_flag [antag_flag] (used by [known_antag_flags[antag_flag]])!") continue known_antag_flags[antag_flag] = ruleset diff --git a/config/dynamic.toml b/config/dynamic.toml index 3d8b6d29655..e5b7f92b2f9 100644 --- a/config/dynamic.toml +++ b/config/dynamic.toml @@ -354,6 +354,19 @@ repeatable_weight_decrease = 2 repeatable = 1 minimum_required_age = 0 +["Midround Mass Changelings"] +weight.1 = 0 +weight.2 = 3 +weight.3 = 4 +weight.4 = 5 +min_pop = 25 +blacklisted_roles = [] +repeatable_weight_decrease = 4 +repeatable = 1 +minimum_required_age = 0 +min_antag_cap = 2 +max_antag_cap = 3 + ["Paradox Clone"] weight = 5 min_pop = 10 @@ -414,6 +427,19 @@ repeatable_weight_decrease = 2 repeatable = 1 minimum_required_age = 0 +["Midround Mass Traitors"] +weight.1 = 0 +weight.2 = 3 +weight.3 = 8 +weight.4 = 10 +min_pop = 15 +blacklisted_roles = [] +repeatable_weight_decrease = 7 +repeatable = 1 +minimum_required_age = 0 +min_antag_cap = 2 +max_antag_cap = 4 + ["Midround Malfunctioning AI"] weight.1 = 0 weight.2 = 1