diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 7e35e74a5c..a2fb71ee04 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -14,8 +14,12 @@
GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (10 MINUTES))
GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (30 MINUTES))
-GLOBAL_VAR_INIT(dynamic_midround_delay_min, (5 MINUTES))
-GLOBAL_VAR_INIT(dynamic_midround_delay_max, (15 MINUTES))
+GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES))
+GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES))
+
+GLOBAL_VAR_INIT(dynamic_event_delay_min, (5 MINUTES))
+GLOBAL_VAR_INIT(dynamic_event_delay_max, (20 MINUTES)) // this is on top of regular events, so can't be quite as often
+
// -- Roundstart injection delays
GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (2 MINUTES))
@@ -76,6 +80,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
var/list/latejoin_rules = list()
/// List of midround rules used for selecting the rules.
var/list/midround_rules = list()
+ /// List of events used for reducing threat without causing antag injection (necessarily).
+ var/list/events = list()
/** # Pop range per requirement.
* If the value is five the range is:
* 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+
@@ -113,6 +119,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
var/latejoin_injection_cooldown = 0
/// When world.time is over this number the mode tries to inject a midround ruleset.
var/midround_injection_cooldown = 0
+ /// When wor.dtime is over this number the mode tries to do an event.
+ var/event_injection_cooldown = 0
/// When TRUE GetInjectionChance returns 100.
var/forced_injection = FALSE
/// Forced ruleset to be executed for the next latejoin.
@@ -173,6 +181,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
dat += "
Injection Timers: ([get_injection_chance(TRUE)]% chance)
"
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)] seconds"] \[Now!\]
"
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)] seconds"] \[Now!\]
"
+ dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)] seconds"] \[Now!\]
"
usr << browse(dat.Join(), "window=gamemode_panel;size=500x500")
/datum/game_mode/dynamic/Topic(href, href_list)
@@ -204,6 +213,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
midround_injection_cooldown = 0
forced_injection = TRUE
message_admins("[key_name(usr)] forced a midround injection.", 1)
+ else if (href_list["forceevent"])
+ event_injection_cooldown = 0
+ // events always happen anyway
+ message_admins("[key_name(usr)] forced an event.", 1)
else if (href_list["threatlog"])
show_threatlog(usr)
else if (href_list["stacking_limit"])
@@ -348,6 +361,9 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
if ("Midround")
if (ruleset.weight)
midround_rules += ruleset
+ if("Event")
+ if(ruleset.weight)
+ events += ruleset
for(var/mob/dead/new_player/player in GLOB.player_list)
if(player.ready == PLAYER_READY_TO_PLAY && player.mind)
roundstart_pop_ready++
@@ -548,6 +564,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
latejoin_rules = remove_from_list(latejoin_rules, rule.type)
else if(rule.type == "Midround")
midround_rules = remove_from_list(midround_rules, rule.type)
+ else if(rule.type == "Event")
+ events = remove_from_list(events,rule.type)
addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay)
return TRUE
@@ -641,7 +659,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
// Time to inject some threat into the round
if(EMERGENCY_ESCAPED_OR_ENDGAMED) // Unless the shuttle is gone
return
-
message_admins("DYNAMIC: Checking for midround injection.")
log_game("DYNAMIC: Checking for midround injection.")
@@ -651,9 +668,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
var/list/drafted_rules = list()
var/antag_num = current_players[CURRENT_LIVING_ANTAGS].len
for (var/datum/dynamic_ruleset/midround/rule in midround_rules)
- var/antag_acceptable = (antag_num || !isnull(rule.antag_flag))
// if there are antags OR the rule is an antag rule, antag_acceptable will be true.
- if (antag_acceptable && rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost)
+ if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost)
// Classic secret : only autotraitor/minor roles
if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)))
continue
@@ -667,7 +683,21 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
picking_midround_latejoin_rule(drafted_rules)
else
midround_injection_cooldown = (midround_injection_cooldown + world.time)/2
-
+
+ if(event_injection_cooldown < world.time)
+ var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
+ event_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time)
+ message_admins("DYNAMIC: Doing event injection.")
+ log_game("DYNAMIC: Doing event injection.")
+ update_playercounts()
+ var/list/drafted_rules = list()
+ for(var/datum/dynamic_ruleset/event/rule in events)
+ if(rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost)
+ if(rule.ready())
+ drafted_rules[rule] = rule.get_weight()
+ if(drafted_rules.len > 0)
+ picking_midround_latejoin_rule(drafted_rules)
+
/// Updates current_players.
/datum/game_mode/dynamic/proc/update_playercounts()
current_players[CURRENT_LIVING_PLAYERS] = list()
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm
new file mode 100644
index 0000000000..707b0b6b5b
--- /dev/null
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm
@@ -0,0 +1,345 @@
+/datum/dynamic_ruleset/event
+ ruletype = "Event"
+ var/typepath // typepath of the event
+ var/triggering
+
+/datum/dynamic_ruleset/event/execute()
+ var/datum/round_event/E = new typepath()
+ E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
+ // E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always
+
+ testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
+ deadchat_broadcast("[name] has just been triggered by dynamic!")
+ log_game("Random Event triggering: [name] ([typepath])")
+
+ return E
+
+/datum/dynamic_ruleset/event/ready(forced = FALSE) // same as midround cause we're still using enemy system
+ if (!forced)
+ var/job_check = 0
+ if (enemy_roles.len > 0)
+ for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS])
+ if (M.stat == DEAD)
+ continue // Dead players cannot count as opponents
+ if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles))
+ job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it
+
+ var/threat = round(mode.threat_level/10)
+ if (job_check < required_enemies[threat])
+ return FALSE
+ return TRUE
+
+//////////////////////////////////////////////
+// //
+// PIRATES //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/event/pirates
+ name = "Space Pirates"
+ config_tag = "pirates"
+ typepath = /datum/round_event/pirates
+ antag_flag = ROLE_TRAITOR
+ enemy_roles = list("AI","Security Officer","Head of Security","Captain")
+ required_enemies = list(2,2,1,1,0,0,0,0,0,0)
+ weight = 5
+ cost = 10
+ requirements = list(70,60,50,50,40,40,40,30,20,15)
+ high_population_requirement = 15
+
+/datum/dynamic_ruleset/event/pirates/ready(forced = FALSE)
+ if (!SSmapping.empty_space)
+ return FALSE
+ return ..()
+
+//////////////////////////////////////////////
+// //
+// SPIDERS //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/event/spiders
+ name = "Spider Infestation"
+ config_tag = "spiders"
+ typepath = /datum/round_event/spider_infestation
+ enemy_roles = list("AI","Security Officer","Head of Security","Captain")
+ required_enemies = list(2,2,1,1,0,0,0,0,0,0)
+ weight = 5
+ cost = 10
+ requirements = list(70,60,50,50,40,40,40,30,20,15)
+ high_population_requirement = 15
+
+//////////////////////////////////////////////
+// //
+// CLOGGED VENTS //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/event/ventclog
+ name = "Clogged Vents"
+ config_tag = "ventclog"
+ typepath = /datum/round_event/vent_clog
+ enemy_roles = list("Chemist","Medical Doctor","Chief Medical Officer")
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ cost = 2
+ weight = 4
+ repeatable_weight_decrease = 3
+ requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/ventclog/ready()
+ if(mode.threat_level > 30 && mode.threat >= 5 && prob(20))
+ name = "Clogged Vents: Threatening"
+ cost = 5
+ required_enemies = list(3,3,3,2,2,2,1,1,1,1)
+ typepath = /datum/round_event/vent_clog/threatening
+ else if(mode.threat_level > 15 && mode.threat > 15 && prob(30))
+ name = "Clogged Vents: Catastrophic"
+ cost = 15
+ required_enemies = list(2,2,1,1,1,1,0,0,0,0)
+ typepath = /datum/round_event/vent_clog/catastrophic
+ else
+ cost = 2
+ name = "Clogged Vents: Normal"
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ typepath = /datum/round_event/vent_clog
+ return ..()
+
+//////////////////////////////////////////////
+// //
+// ION STORM //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/event/ion_storm
+ name = "Ion Storm"
+ config_tag = "ion_storm"
+ typepath = /datum/round_event/ion_storm
+ enemy_roles = list("Research Director","Captain","Chief Engineer")
+ required_enemies = list(1,1,0,0,0,0,0,0,0,0)
+ weight = 4
+ // no repeatable weight decrease. too variable to be unfun multiple times in one round
+ cost = 3
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+//////////////////////////////////////////////
+// //
+// METEORS //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/event/meteor_wave
+ name = "Meteor Wave"
+ config_tag = "meteor_wave"
+ typepath = /datum/round_event/meteor_wave
+ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg")
+ required_enemies = list(3,3,3,3,3,3,3,3,3,3)
+ cost = 15
+ weight = 3
+ repeatable_weight_decrease = 2
+ requirements = list(60,50,40,30,30,30,30,30,30,30)
+ high_population_requirement = 30
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/meteor_wave/ready()
+ if(mode.threat_level > 40 && mode.threat >= 25 && prob(20))
+ cost = 25
+ typepath = /datum/round_event/meteor_wave/threatening
+ else if(mode.threat_level > 50 && mode.threat >= 40 && prob(30))
+ cost = 40
+ typepath = /datum/round_event/meteor_wave/catastrophic
+ else
+ cost = 15
+ typepath = /datum/round_event/meteor_wave
+ return ..()
+
+//////////////////////////////////////////////
+// //
+// ANOMALIES //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/event/anomaly_bluespace
+ name = "Anomaly: Bluespace"
+ config_tag = "anomaly_bluespace"
+ typepath = /datum/round_event/anomaly/anomaly_bluespace
+ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ weight = 2
+ repeatable_weight_decrease = 1
+ cost = 3
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/anomaly_flux
+ name = "Anomaly: Hyper-Energetic Flux"
+ config_tag = "anomaly_flux"
+ typepath = /datum/round_event/anomaly/anomaly_flux
+ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ weight = 2
+ repeatable_weight_decrease = 1
+ cost = 5
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 10
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/anomaly_gravitational
+ name = "Anomaly: Gravitational"
+ config_tag = "anomaly_gravitational"
+ typepath = /datum/round_event/anomaly/anomaly_grav
+ weight = 2
+ repeatable_weight_decrease = 1
+ cost = 3
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/anomaly_pyroclastic
+ name = "Anomaly: Pyroclastic"
+ config_tag = "anomaly_pyroclastic"
+ typepath = /datum/round_event/anomaly/anomaly_pyro
+ weight = 2
+ repeatable_weight_decrease = 1
+ cost = 5
+ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
+ required_enemies = list(1,1,1,1,1,1,1,1,1,1)
+ requirements = list(10,10,10,10,10,10,10,10,10,10)
+ high_population_requirement = 10
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/anomaly_vortex
+ name = "Anomaly: Vortex"
+ config_tag = "anomaly_vortex"
+ typepath = /datum/round_event/anomaly/anomaly_vortex
+ weight = 2
+ repeatable_weight_decrease = 1
+ cost = 5
+ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
+ required_enemies = list(1,1,1,1,1,1,1,1,1,1)
+ requirements = list(10,10,10,10,10,10,10,10,10,10)
+ high_population_requirement = 10
+ repeatable = TRUE
+
+//////////////////////////////////////////////
+// //
+// WOW THAT'S A LOT OF EVENTS //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/event/brand_intelligence
+ name = "Brand Intelligence"
+ config_tag = "brand_intelligence"
+ typepath = /datum/round_event/brand_intelligence
+ weight = 1
+ repeatable_weight_decrease = 1
+ cost = 2
+ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
+ required_enemies = list(1,1,1,1,0,0,0,0,0,0)
+ requirements = list(10,10,10,10,10,10,10,10,10,10)
+ high_population_requirement = 10
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/carp_migration
+ name = "Carp Migration"
+ config_tag = "carp_migration"
+ typepath = /datum/round_event/carp_migration
+ weight = 7
+ repeatable_weight_decrease = 3
+ cost = 4
+ requirements = list(10,10,10,10,10,10,10,10,10,10)
+ high_population_requirement = 10
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/communications_blackout
+ name = "Communications Blackout"
+ config_tag = "communications_blackout"
+ typepath = /datum/round_event/communications_blackout
+ cost = 4
+ weight = 2
+ repeatable_weight_decrease = 3
+ enemy_roles = list("Chief Engineer","Station Engineer")
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/processor_overload
+ name = "Processer Overload"
+ config_tag = "processor_overload"
+ typepath = /datum/round_event/processor_overload
+ cost = 4
+ weight = 2
+ repeatable_weight_decrease = 3
+ enemy_roles = list("Chief Engineer","Station Engineer")
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/space_dust
+ name = "Minor Space Dust"
+ config_tag = "space_dust"
+ typepath = /datum/round_event/space_dust
+ cost = 2
+ weight = 2
+ repeatable_weight_decrease = 1
+ enemy_roles = list("Chief Engineer","Station Engineer")
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/major_dust
+ name = "Major Space Dust"
+ config_tag = "major_dust"
+ typepath = /datum/round_event/meteor_wave/major_dust
+ cost = 4
+ weight = 2
+ repeatable_weight_decrease = 1
+ enemy_roles = list("Chief Engineer","Station Engineer")
+ required_enemies = list(2,2,2,2,2,2,2,2,2,2)
+ requirements = list(10,10,10,10,10,10,10,10,10,10)
+ high_population_requirement = 10
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/electrical_storm
+ name = "Electrical Storm"
+ config_tag = "electrical_storm"
+ typepath = /datum/round_event/electrical_storm
+ cost = 1
+ weight = 2
+ repeatable_weight_decrease = 1
+ enemy_roles = list("Chief Engineer","Station Engineer")
+ required_enemies = list(1,1,1,0,0,0,0,0,0,0)
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/heart_attack
+ name = "Random Heart Attack"
+ config_tag = "heart_attack"
+ typepath = /datum/round_event/heart_attack
+ cost = 3
+ weight = 2
+ repeatable_weight_decrease = 1
+ enemy_roles = list("Medical Doctor","Chief Medical Officer")
+ required_enemies = list(2,2,2,2,2,2,2,2,2,2)
+ requirements = list(101,101,101,5,5,5,5,5,5,5)
+ high_population_requirement = 5
+ repeatable = TRUE
+
+/datum/dynamic_ruleset/event/radiation_storm
+ name = "Radiation Storm"
+ config_tag = "radiation_storm"
+ typepath = /datum/round_event/radiation_storm
+ cost = 3
+ weight = 1
+ enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain")
+ required_enemies = list(1,1,1,1,1,1,1,1,1,1)
+ requirements = list(5,5,5,5,5,5,5,5,5,5)
+ high_population_requirement = 5
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 826bc6b593..c6f85a40b3 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -24,11 +24,6 @@
/// Whether the ruleset should call generate_ruleset_body or not.
var/makeBody = TRUE
-/datum/dynamic_ruleset/midround/event // Doesn't assume an antag
- required_type = /mob
- var/typepath // typepath of the event
- var/triggering
-
/datum/dynamic_ruleset/midround/trim_candidates()
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
@@ -76,7 +71,7 @@
if (!forced)
var/job_check = 0
if (enemy_roles.len > 0)
- for (var/mob/M in living_players)
+ for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS])
if (M.stat == DEAD)
continue // Dead players cannot count as opponents
if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles)))
@@ -166,23 +161,6 @@
/datum/dynamic_ruleset/midround/from_ghosts/proc/setup_role(datum/antagonist/new_role)
return
-/datum/dynamic_ruleset/midround/event/trim_list(list/L = list())
- return L.Copy() // we're not drafting ghosts here
-
-/datum/dynamic_ruleset/midround/event/ready(forced = FALSE)
- return TRUE
-
-/datum/dynamic_ruleset/midround/event/execute()
- var/datum/round_event/E = new typepath()
- E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
- // E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always
-
- testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
- deadchat_broadcast("[name] has just been triggered by dynamic!")
- log_game("Random Event triggering: [name] ([typepath])")
-
- return E
-
//////////////////////////////////////////////
// //
// SYNDICATE TRAITORS //
@@ -743,330 +721,5 @@
log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.")
return Ninja
-/datum/dynamic_ruleset/midround/event/pirates
- name = "Space Pirates"
- config_tag = "pirates"
- typepath = /datum/round_event/pirates
- antag_flag = ROLE_TRAITOR
- enemy_roles = list("AI","Security Officer","Head of Security","Captain")
- required_enemies = list(2,2,1,1,0,0,0,0,0,0)
- weight = 5
- cost = 10
- requirements = list(70,60,50,50,40,40,40,30,20,15)
- high_population_requirement = 15
-
-/datum/dynamic_ruleset/midround/event/pirates/ready(forced = FALSE)
- if (!SSmapping.empty_space)
- return FALSE
- return ..()
-
-//////////////////////////////////////////////
-// //
-// SPIDERS //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/midround/event/spiders
- name = "Spider Infestation"
- config_tag = "spiders"
- typepath = /datum/round_event/spider_infestation
- enemy_roles = list("AI","Security Officer","Head of Security","Captain")
- required_enemies = list(2,2,1,1,0,0,0,0,0,0)
- weight = 5
- cost = 10
- requirements = list(70,60,50,50,40,40,40,30,20,15)
- high_population_requirement = 15
-
-//////////////////////////////////////////////
-// //
-// CLOGGED VENTS //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/midround/event/ventclog
- name = "Clogged Vents: Normal"
- config_tag = "ventclog_normal"
- typepath = /datum/round_event/vent_clog
- enemy_roles = list("Chemist","Medical Doctor","Chief Medical Officer")
- required_enemies = list(1,1,1,0,0,0,0,0,0,0)
- cost = 2
- weight = 4
- repeatable_weight_decrease = 2
- requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/ventclog/threatening
- name = "Clogged Vents: Threatening"
- config_tag = "ventclog_threatening"
- typepath = /datum/round_event/vent_clog/threatening
- required_enemies = list(2,2,1,1,1,1,0,0,0,0)
- cost = 5
- weight = 4
- repeatable_weight_decrease = 2
- requirements = list(15,15,15,15,15,15,15,15,15,15) // doesn't really scale with pop, so
- high_population_requirement = 15
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/ventclog/catastrophic
- name = "Clogged Vents: Catastrophic"
- config_tag = "ventclog_catostrophic"
- typepath = /datum/round_event/vent_clog/catastrophic
- required_enemies = list(3,3,3,2,2,2,1,1,1,1)
- cost = 15
- weight = 4
- repeatable_weight_decrease = 2
- requirements = list(30,30,30,30,30,30,30,30,30,30)
- high_population_requirement = 30
- repeatable = TRUE
-
-//////////////////////////////////////////////
-// //
-// ION STORM //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/midround/event/ion_storm
- name = "Ion Storm"
- config_tag = "ion_storm"
- typepath = /datum/round_event/ion_storm
- enemy_roles = list("Research Director","Captain","Chief Engineer")
- required_enemies = list(1,1,0,0,0,0,0,0,0,0)
- weight = 4
- // no repeatable weight decrease. too variable to be unfun multiple times in one round
- cost = 3
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-//////////////////////////////////////////////
-// //
-// METEORS //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/midround/event/meteor_wave
- name = "Meteor Wave: Normal"
- config_tag = "meteor_wave_normal"
- typepath = /datum/round_event/meteor_wave
- enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg")
- required_enemies = list(2,2,2,2,2,2,2,2,2,2)
- cost = 15
- weight = 3
- repeatable_weight_decrease = 2
- requirements = list(60,50,40,30,30,30,30,30,30,30)
- high_population_requirement = 30
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/meteor_wave/threatening
- name = "Meteor Wave: Threatening"
- config_tag = "meteor_wave_threatening"
- typepath = /datum/round_event/meteor_wave/threatening
- cost = 25
- weight = 3
- repeatable_weight_decrease = 2
- requirements = list(80,70,60,50,40,40,40,40,40,40)
- high_population_requirement = 40
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/meteor_wave/catastrophic
- name = "Meteor Wave: Catastrophic"
- config_tag = "meteor_wave_catastrophic"
- typepath = /datum/round_event/meteor_wave/catastrophic
- cost = 40
- weight = 3
- repeatable_weight_decrease = 2
- requirements = list(101,100,90,80,70,60,50,50,50,50)
- high_population_requirement = 50
- repeatable = TRUE
-
-//////////////////////////////////////////////
-// //
-// ANOMALIES //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/midround/event/anomaly_bluespace
- name = "Anomaly: Bluespace"
- config_tag = "anomaly_bluespace"
- typepath = /datum/round_event/anomaly/anomaly_bluespace
- enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
- required_enemies = list(1,1,1,0,0,0,0,0,0,0)
- weight = 2
- repeatable_weight_decrease = 1
- cost = 3
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/anomaly_flux
- name = "Anomaly: Hyper-Energetic Flux"
- config_tag = "anomaly_flux"
- typepath = /datum/round_event/anomaly/anomaly_flux
- enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
- required_enemies = list(1,1,1,0,0,0,0,0,0,0)
- weight = 2
- repeatable_weight_decrease = 1
- cost = 5
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 10
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/anomaly_gravitational
- name = "Anomaly: Gravitational"
- config_tag = "anomaly_gravitational"
- typepath = /datum/round_event/anomaly/anomaly_grav
- weight = 2
- repeatable_weight_decrease = 1
- cost = 3
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/anomaly_pyroclastic
- name = "Anomaly: Pyroclastic"
- config_tag = "anomaly_pyroclastic"
- typepath = /datum/round_event/anomaly/anomaly_pyro
- weight = 2
- repeatable_weight_decrease = 1
- cost = 5
- enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
- required_enemies = list(1,1,1,1,1,1,1,1,1,1)
- requirements = list(10,10,10,10,10,10,10,10,10,10)
- high_population_requirement = 10
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/anomaly_vortex
- name = "Anomaly: Vortex"
- config_tag = "anomaly_vortex"
- typepath = /datum/round_event/anomaly/anomaly_vortex
- weight = 2
- repeatable_weight_decrease = 1
- cost = 5
- enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
- required_enemies = list(1,1,1,1,1,1,1,1,1,1)
- requirements = list(10,10,10,10,10,10,10,10,10,10)
- high_population_requirement = 10
- repeatable = TRUE
-
-//////////////////////////////////////////////
-// //
-// WOW THAT'S A LOT OF EVENTS //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/midround/event/brand_intelligence
- name = "Brand Intelligence"
- config_tag = "brand_intelligence"
- typepath = /datum/round_event/brand_intelligence
- weight = 1
- repeatable_weight_decrease = 1
- cost = 2
- enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
- required_enemies = list(1,1,1,1,0,0,0,0,0,0)
- requirements = list(10,10,10,10,10,10,10,10,10,10)
- high_population_requirement = 10
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/carp_migration
- name = "Carp Migration"
- config_tag = "carp_migration"
- typepath = /datum/round_event/carp_migration
- weight = 7
- repeatable_weight_decrease = 3
- cost = 4
- requirements = list(10,10,10,10,10,10,10,10,10,10)
- high_population_requirement = 10
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/communications_blackout
- name = "Communications Blackout"
- config_tag = "communications_blackout"
- typepath = /datum/round_event/communications_blackout
- cost = 4
- weight = 2
- repeatable_weight_decrease = 3
- enemy_roles = list("Chief Engineer","Station Engineer")
- required_enemies = list(1,1,1,0,0,0,0,0,0,0)
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/processor_overload
- name = "Processer Overload"
- config_tag = "processor_overload"
- typepath = /datum/round_event/processor_overload
- cost = 4
- weight = 2
- repeatable_weight_decrease = 3
- enemy_roles = list("Chief Engineer","Station Engineer")
- required_enemies = list(1,1,1,0,0,0,0,0,0,0)
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/space_dust
- name = "Minor Space Dust"
- config_tag = "space_dust"
- typepath = /datum/round_event/space_dust
- cost = 2
- weight = 2
- repeatable_weight_decrease = 1
- enemy_roles = list("Chief Engineer","Station Engineer")
- required_enemies = list(1,1,1,0,0,0,0,0,0,0)
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/major_dust
- name = "Major Space Dust"
- config_tag = "major_dust"
- typepath = /datum/round_event/meteor_wave/major_dust
- cost = 4
- weight = 2
- repeatable_weight_decrease = 1
- enemy_roles = list("Chief Engineer","Station Engineer")
- required_enemies = list(2,2,2,2,2,2,2,2,2,2)
- requirements = list(10,10,10,10,10,10,10,10,10,10)
- high_population_requirement = 10
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/electrical_storm
- name = "Electrical Storm"
- config_tag = "electrical_storm"
- typepath = /datum/round_event/electrical_storm
- cost = 1
- weight = 2
- repeatable_weight_decrease = 1
- enemy_roles = list("Chief Engineer","Station Engineer")
- required_enemies = list(1,1,1,0,0,0,0,0,0,0)
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/heart_attack
- name = "Random Heart Attack"
- config_tag = "heart_attack"
- typepath = /datum/round_event/heart_attack
- cost = 3
- weight = 2
- repeatable_weight_decrease = 1
- enemy_roles = list("Medical Doctor","Chief Medical Officer")
- required_enemies = list(2,2,2,2,2,2,2,2,2,2)
- requirements = list(101,101,101,5,5,5,5,5,5,5)
- high_population_requirement = 5
- repeatable = TRUE
-
-/datum/dynamic_ruleset/midround/event/radiation_storm
- name = "Radiation Storm"
- config_tag = "radiation_storm"
- typepath = /datum/round_event/radiation_storm
- cost = 3
- weight = 1
- enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain")
- required_enemies = list(1,1,1,1,1,1,1,1,1,1)
- requirements = list(5,5,5,5,5,5,5,5,5,5)
- high_population_requirement = 5
-
#undef ABDUCTOR_MAX_TEAMS
#undef REVENANT_SPAWN_THRESHOLD
diff --git a/tgstation.dme b/tgstation.dme
index 4fd1b6c4f3..f9d5eb8823 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -565,6 +565,7 @@
#include "code\game\gamemodes\devil\devil agent\devil_agent.dm"
#include "code\game\gamemodes\dynamic\dynamic.dm"
#include "code\game\gamemodes\dynamic\dynamic_rulesets.dm"
+#include "code\game\gamemodes\dynamic\dynamic_rulesets_events.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_roundstart.dm"