diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm
index b8226704cd..95ebbf71d2 100644
--- a/code/modules/events/_event.dm
+++ b/code/modules/events/_event.dm
@@ -29,6 +29,9 @@
var/triggering //admin cancellation
+ /// Whether or not dynamic should hijack this event
+ var/dynamic_should_hijack = FALSE
+
/datum/round_event_control/New()
if(config && !wizardevent) // Magic is unaffected by configs
earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1)
@@ -55,6 +58,11 @@
return FALSE
if(holidayID && (!SSevents.holidays || !SSevents.holidays[holidayID]))
return FALSE
+
+ var/datum/game_mode/dynamic/dynamic = SSticker.mode
+ if (istype(dynamic) && dynamic_should_hijack && dynamic.random_event_hijacked != HIJACKED_NOTHING)
+ return FALSE
+
return TRUE
/datum/round_event_control/wizard/canSpawnEvent(var/players_amt, var/gamemode)
@@ -64,14 +72,19 @@
return can_be_midround_wizard && ..()
return ..()
+
+
/datum/round_event_control/proc/preRunEvent()
if(!ispath(typepath, /datum/round_event))
return EVENT_CANT_RUN
+ if (SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PRE_RANDOM_EVENT, src) & CANCEL_PRE_RANDOM_EVENT)
+ return EVENT_INTERRUPTED
+
triggering = TRUE
if (alert_observers)
- message_admins("Random Event triggering in 30 seconds: [name] (CANCEL)")
- sleep(300)
+ message_admins("Random Event triggering in [RANDOM_EVENT_ADMIN_INTERVENTION_TIME] seconds: [name] (CANCEL)")
+ sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME SECONDS)
var/gamemode = SSticker.mode.config_tag
var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)
if(!canSpawnEvent(players_amt, gamemode))
diff --git a/code/modules/unit_tests/dynamic_ruleset_sanity.dm b/code/modules/unit_tests/dynamic_ruleset_sanity.dm
index 9fff5daf9b..837e0b235c 100644
--- a/code/modules/unit_tests/dynamic_ruleset_sanity.dm
+++ b/code/modules/unit_tests/dynamic_ruleset_sanity.dm
@@ -12,3 +12,25 @@
Fail("[ruleset] has a scaling_cost, but is also a lone/highlander ruleset.")
else if (!has_scaling_cost && !is_lone)
Fail("[ruleset] has no scaling cost, but is also not a lone/highlander ruleset.")
+
+/// Verifies that dynamic rulesets have unique antag_flag.
+/datum/unit_test/dynamic_unique_antag_flags
+
+/datum/unit_test/dynamic_unique_antag_flags/Run()
+ var/list/known_antag_flags = list()
+
+ for (var/datum/dynamic_ruleset/ruleset as anything in subtypesof(/datum/dynamic_ruleset))
+ if (isnull(initial(ruleset.antag_datum)))
+ continue
+
+ var/antag_flag = initial(ruleset.antag_flag)
+
+ if (isnull(antag_flag))
+ Fail("[ruleset] has a null antag_flag!")
+ continue
+
+ if (antag_flag in known_antag_flags)
+ 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/tgstation.dme b/tgstation.dme
index 80cfab4735..b8f852aa53 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -812,13 +812,14 @@
#include "code\game\gamemodes\devil\objectives.dm"
#include "code\game\gamemodes\devil\devil agent\devil_agent.dm"
#include "code\game\gamemodes\dynamic\dynamic.dm"
+#include "code\game\gamemodes\dynamic\dynamic_hijacking.dm"
#include "code\game\gamemodes\dynamic\dynamic_logging.dm"
#include "code\game\gamemodes\dynamic\dynamic_rulesets.dm"
#include "code\game\gamemodes\dynamic\dynamic_rulesets_latejoin.dm"
#include "code\game\gamemodes\dynamic\dynamic_rulesets_midround.dm"
-#include "code\game\gamemodes\dynamic\dynamic_rulesets_minor.dm"
#include "code\game\gamemodes\dynamic\dynamic_rulesets_roundstart.dm"
#include "code\game\gamemodes\dynamic\dynamic_simulations.dm"
+#include "code\game\gamemodes\dynamic\ruleset_picking.dm"
#include "code\game\gamemodes\eldritch_cult\eldritch_cult.dm"
#include "code\game\gamemodes\extended\extended.dm"
#include "code\game\gamemodes\gangs\dominator.dm"