diff --git a/code/__DEFINES/dynamic.dm b/code/__DEFINES/dynamic.dm index 07c833cdc49..0162ef755e3 100644 --- a/code/__DEFINES/dynamic.dm +++ b/code/__DEFINES/dynamic.dm @@ -38,3 +38,9 @@ #define RULESET_FORCE_ENABLED "force enabled" /// Ruleset should not run regardless of population and threat available #define RULESET_FORCE_DISABLED "force disabled" + +// Flavor ruletypes, used by station traits +/// Rulesets selected by dynamic at default +#define RULESET_CATEGORY_DEFAULT (1 << 0) +/// Rulesets not including crew antagonists, non-witting referring to antags like obsessed which aren't really enemies of the station +#define RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS (1 << 1) diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index f64816db5b0..9540fef7b47 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -19,6 +19,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) GLOBAL_LIST_EMPTY(dynamic_station_traits) /// Rulesets which have been forcibly enabled or disabled GLOBAL_LIST_EMPTY(dynamic_forced_rulesets) +/// Bitflags used during init by Dynamic to determine which rulesets we're allowed to use, used by station traits for gamemode-esque experiences +GLOBAL_VAR_INIT(dynamic_ruleset_categories, RULESET_CATEGORY_DEFAULT) SUBSYSTEM_DEF(dynamic) name = "Dynamic" @@ -646,7 +648,6 @@ SUBSYSTEM_DEF(dynamic) log_admin(concatenated_message) to_chat(GLOB.admins, concatenated_message) - /// Initializes the internal ruleset variables /datum/controller/subsystem/dynamic/proc/setup_rulesets() midround_rules = init_rulesets(/datum/dynamic_ruleset/midround) @@ -664,6 +665,9 @@ SUBSYSTEM_DEF(dynamic) if (initial(ruleset_type.weight) == 0) continue + if(!(initial(ruleset_type.ruleset_category) & GLOB.dynamic_ruleset_categories)) + continue + var/ruleset = new ruleset_type configure_ruleset(ruleset) rulesets += ruleset diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets.dm index 0ca3c84bb68..8460307009e 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets.dm @@ -83,6 +83,8 @@ /// A list, or null, of templates that the ruleset depends on to function correctly var/list/ruleset_lazy_templates + /// In what categories is this ruleset allowed to run? Used by station traits + var/ruleset_category = RULESET_CATEGORY_DEFAULT /datum/dynamic_ruleset/New() // Rulesets can be instantiated more than once, such as when an admin clicks diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm index fecc1f09ca4..c8cdddf0fe7 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm @@ -349,6 +349,7 @@ antag_datum = /datum/antagonist/wizard antag_flag = ROLE_WIZARD_MIDROUND antag_flag_override = ROLE_WIZARD + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 weight = 1 @@ -377,6 +378,7 @@ antag_flag = ROLE_OPERATIVE_MIDROUND antag_flag_override = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS enemy_roles = list( JOB_AI, JOB_CYBORG, @@ -431,6 +433,7 @@ midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY antag_datum = /datum/antagonist/blob antag_flag = ROLE_BLOB + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 minimum_round_time = 35 MINUTES @@ -450,6 +453,7 @@ antag_datum = /datum/antagonist/blob/infection antag_flag = ROLE_BLOB_INFECTION antag_flag_override = ROLE_BLOB + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS protected_roles = list( JOB_CAPTAIN, JOB_DETECTIVE, @@ -502,6 +506,7 @@ midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY antag_datum = /datum/antagonist/xeno antag_flag = ROLE_ALIEN + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 minimum_round_time = 40 MINUTES @@ -550,6 +555,7 @@ antag_datum = /datum/antagonist/nightmare antag_flag = ROLE_NIGHTMARE antag_flag_override = ROLE_ALIEN + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 weight = 3 @@ -585,7 +591,7 @@ midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY antag_datum = /datum/antagonist/space_dragon antag_flag = ROLE_SPACE_DRAGON - antag_flag_override = ROLE_SPACE_DRAGON + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 weight = 4 @@ -625,6 +631,7 @@ midround_ruleset_style = MIDROUND_RULESET_STYLE_LIGHT antag_datum = /datum/antagonist/abductor antag_flag = ROLE_ABDUCTOR + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 2 required_applicants = 2 @@ -662,6 +669,7 @@ midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY antag_datum = /datum/antagonist/ninja antag_flag = ROLE_NINJA + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 weight = 4 @@ -701,6 +709,7 @@ name = "Spiders" midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY antag_flag = ROLE_SPIDER + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_type = /mob/dead/observer required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 0 @@ -718,6 +727,7 @@ /datum/dynamic_ruleset/midround/from_ghosts/revenant name = "Revenant" midround_ruleset_style = MIDROUND_RULESET_STYLE_LIGHT + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS antag_datum = /datum/antagonist/revenant antag_flag = ROLE_REVENANT required_enemies = list(2,2,1,1,1,1,1,0,0,0) @@ -768,6 +778,7 @@ /datum/dynamic_ruleset/midround/pirates name = "Space Pirates" midround_ruleset_style = MIDROUND_RULESET_STYLE_LIGHT + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS antag_flag = "Space Pirates" required_type = /mob/dead/observer required_enemies = list(2,2,1,1,1,1,1,0,0,0) @@ -790,6 +801,7 @@ /datum/dynamic_ruleset/midround/dangerous_pirates name = "Dangerous Space Pirates" midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS antag_flag = "Space Pirates" required_type = /mob/dead/observer required_enemies = list(2,2,1,1,1,1,1,0,0,0) @@ -814,6 +826,7 @@ midround_ruleset_style = MIDROUND_RULESET_STYLE_LIGHT antag_datum = /datum/antagonist/obsessed antag_flag = ROLE_OBSESSED + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS restricted_roles = list( JOB_AI, JOB_CYBORG, @@ -857,6 +870,7 @@ antag_datum = /datum/antagonist/changeling/space antag_flag = ROLE_CHANGELING_MIDROUND antag_flag_override = ROLE_CHANGELING + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS required_type = /mob/dead/observer required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 @@ -877,6 +891,7 @@ midround_ruleset_style = MIDROUND_RULESET_STYLE_LIGHT antag_datum = /datum/antagonist/paradox_clone antag_flag = ROLE_PARADOX_CLONE + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS enemy_roles = list( JOB_CAPTAIN, JOB_DETECTIVE, diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm index 12ec28c7072..72554a108e3 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm @@ -254,6 +254,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) name = "Wizard" antag_flag = ROLE_WIZARD antag_datum = /datum/antagonist/wizard + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS flags = HIGH_IMPACT_RULESET minimum_required_age = 14 restricted_roles = list( @@ -395,6 +396,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) /datum/dynamic_ruleset/roundstart/nuclear name = "Nuclear Emergency" antag_flag = ROLE_OPERATIVE + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS antag_datum = /datum/antagonist/nukeop var/datum/antagonist/antag_leader_datum = /datum/antagonist/nukeop/leader minimum_required_age = 14 @@ -618,6 +620,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) antag_datum = /datum/antagonist/nukeop/clownop antag_flag = ROLE_CLOWN_OPERATIVE antag_flag_override = ROLE_OPERATIVE + ruleset_category = parent_type::ruleset_category | RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS antag_leader_datum = /datum/antagonist/nukeop/leader/clownop requirements = list(101,101,101,101,101,101,101,101,101,101) required_role = ROLE_CLOWN_OPERATIVE diff --git a/code/datums/station_traits/_station_trait.dm b/code/datums/station_traits/_station_trait.dm index 4c8b19a1358..493f036e191 100644 --- a/code/datums/station_traits/_station_trait.dm +++ b/code/datums/station_traits/_station_trait.dm @@ -35,6 +35,8 @@ GLOBAL_LIST_EMPTY(lobby_station_traits) var/dynamic_threat_id /// If ran during dynamic, do we reduce the total threat? Will be overriden by config if set var/threat_reduction = 0 + /// Which ruleset flags to allow dynamic to use. null to disregard + var/dynamic_category = null /// Trait should not be instantiated in a round if its type matches this type var/abstract_type = /datum/station_trait @@ -45,6 +47,8 @@ GLOBAL_LIST_EMPTY(lobby_station_traits) if(threat_reduction) GLOB.dynamic_station_traits[src] = threat_reduction + if(dynamic_category) + GLOB.dynamic_ruleset_categories = dynamic_category if(sign_up_button) GLOB.lobby_station_traits += src if(trait_processes) diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index 9df85756c21..67b24dc744d 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -562,3 +562,15 @@ #undef SKUB_IDFC #undef RANDOM_SKUB +/// Crew don't ever spawn as enemies of the station. Obsesseds, blob infection, space changelings etc can still happen though +/datum/station_trait/background_checks + name = "Station-Wide Background Checks" + report_message = "We replaced the intern doing your crew's background checks with a trained screener for this shift! That said, our enemies may just find another way to infiltrate the station, so be careful." + trait_type = STATION_TRAIT_NEUTRAL + weight = 1 + show_in_report = TRUE + can_revert = FALSE + + dynamic_category = RULESET_CATEGORY_NO_WITTING_CREW_ANTAGONISTS + threat_reduction = 15 + dynamic_threat_id = "Background Checks" diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm index f93ce4989d4..88a5aed2d83 100644 --- a/code/datums/station_traits/positive_traits.dm +++ b/code/datums/station_traits/positive_traits.dm @@ -1,7 +1,6 @@ #define PARTY_COOLDOWN_LENGTH_MIN (6 MINUTES) #define PARTY_COOLDOWN_LENGTH_MAX (12 MINUTES) - /datum/station_trait/lucky_winner name = "Lucky winner" trait_type = STATION_TRAIT_POSITIVE @@ -31,6 +30,9 @@ new /obj/item/reagent_containers/cup/glass/bottle/beer(toLaunch) new /obj/effect/pod_landingzone(T, toLaunch) +#undef PARTY_COOLDOWN_LENGTH_MIN +#undef PARTY_COOLDOWN_LENGTH_MAX + /datum/station_trait/galactic_grant name = "Galactic grant" trait_type = STATION_TRAIT_POSITIVE @@ -369,6 +371,3 @@ trait_to_give = STATION_TRAIT_ASSISTANT_GIMMICKS show_in_report = TRUE blacklist = list(/datum/station_trait/colored_assistants) - -#undef PARTY_COOLDOWN_LENGTH_MIN -#undef PARTY_COOLDOWN_LENGTH_MAX diff --git a/config/dynamic.json b/config/dynamic.json index bf0c287e504..ca2e52f04d1 100644 --- a/config/dynamic.json +++ b/config/dynamic.json @@ -162,6 +162,8 @@ "Station": { "Radioactive Nebula": { + }, + "Background Checks": { } } }