diff --git a/code/__DEFINES/misc_defines.dm b/code/__DEFINES/misc_defines.dm
index 4dd7f7922d5..21ee3bde8dd 100644
--- a/code/__DEFINES/misc_defines.dm
+++ b/code/__DEFINES/misc_defines.dm
@@ -578,3 +578,13 @@
/// It will only work for datums mind, for datum reasons
/// : because of the embedded typecheck
#define text_ref(datum) (isdatum(datum) ? (datum:cached_ref ||= "\ref[datum]") : ("\ref[datum]"))
+
+#define ROUND_END_NUCLEAR 1
+#define ROUND_END_CREW_TRANSFER 2
+#define ROUND_END_FORCED 3
+
+#define TS_INFESTATION_GREEN_SPIDER 1
+#define TS_INFESTATION_PRINCE_SPIDER 2
+#define TS_INFESTATION_WHITE_SPIDER 3
+#define TS_INFESTATION_PRINCESS_SPIDER 4
+#define TS_INFESTATION_QUEEN_SPIDER 5
diff --git a/code/controllers/subsystem/SSevents.dm b/code/controllers/subsystem/SSevents.dm
index 05cf11c1c08..bd01160067c 100644
--- a/code/controllers/subsystem/SSevents.dm
+++ b/code/controllers/subsystem/SSevents.dm
@@ -30,6 +30,8 @@ SUBSYSTEM_DEF(events)
var/datum/event_meta/new_event = new
+ var/list/biohazards_this_round = list()
+
/datum/controller/subsystem/events/Initialize()
allEvents = subtypesof(/datum/event)
diff --git a/code/controllers/subsystem/SSticker.dm b/code/controllers/subsystem/SSticker.dm
index a74c694ee28..948f284b69e 100644
--- a/code/controllers/subsystem/SSticker.dm
+++ b/code/controllers/subsystem/SSticker.dm
@@ -128,6 +128,8 @@ SUBSYSTEM_DEF(ticker)
if(game_finished || force_ending)
current_state = GAME_STATE_FINISHED
if(GAME_STATE_FINISHED)
+ if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME && !mode.station_was_nuked)
+ event_blackbox(outcome = ROUND_END_CREW_TRANSFER)
current_state = GAME_STATE_FINISHED
Master.SetRunLevel(RUNLEVEL_POSTGAME) // This shouldnt process more than once, but you never know
auto_toggle_ooc(TRUE) // Turn it on
@@ -774,3 +776,77 @@ SUBSYSTEM_DEF(ticker)
QDEL_LIST_ASSOC_VAL(load_queries)
records.Cut()
flagged_antag_rollers.Cut()
+
+/// This proc is for recording biohazard events, and blackboxing if they lived, died, or ended the round. This currently applies to: Terror spiders, Xenomorphs, and Blob.
+/datum/controller/subsystem/ticker/proc/event_blackbox(outcome = ROUND_END_CREW_TRANSFER)
+ for(var/I in SSevents.biohazards_this_round)
+ switch(I)
+ if(TS_INFESTATION_GREEN_SPIDER, TS_INFESTATION_PRINCE_SPIDER, TS_INFESTATION_WHITE_SPIDER, TS_INFESTATION_PRINCESS_SPIDER, TS_INFESTATION_QUEEN_SPIDER)
+ var/output = "unknown spider type"
+ switch(I)
+ if(TS_INFESTATION_GREEN_SPIDER)
+ output = "Green Terrors"
+ if(TS_INFESTATION_PRINCE_SPIDER)
+ output = "Prince Terror"
+ if(TS_INFESTATION_WHITE_SPIDER)
+ output = "White Terrors"
+ if(TS_INFESTATION_PRINCESS_SPIDER)
+ output = "Princess Terrors"
+ if(TS_INFESTATION_QUEEN_SPIDER)
+ output = "Queen Terrors"
+ var/spiders = 0
+ for(var/mob/living/simple_animal/hostile/poison/terror_spider/S in GLOB.ts_spiderlist)
+ if(S.ckey)
+ spiders++
+ if(spiders >= 5 || (output == "Prince Terror" && spiders == 1)) //If a prince lives, record as win.
+ switch(outcome)
+ if(ROUND_END_NUCLEAR)
+ SSblackbox.record_feedback("tally", "Biohazard nuclear victories", 1, output)
+ if(ROUND_END_CREW_TRANSFER)
+ SSblackbox.record_feedback("tally", "Biohazard survives to normal round end", 1, output)
+ if(ROUND_END_FORCED)
+ SSblackbox.record_feedback("tally", "Biohazard survives to admin round end", 1, output)
+ else
+ switch(outcome)
+ if(ROUND_END_NUCLEAR)
+ SSblackbox.record_feedback("tally", "Biohazard dies station nuked", 1, output)
+ if(ROUND_END_CREW_TRANSFER)
+ SSblackbox.record_feedback("tally", "Biohazard dies normal end", 1, output)
+ if(ROUND_END_FORCED)
+ SSblackbox.record_feedback("tally", "Biohazard dies admin round end", 1, output)
+ if("Xenomorphs")
+ if(length(SSticker.mode.xenos) > 5)
+ switch(outcome)
+ if(ROUND_END_NUCLEAR)
+ SSblackbox.record_feedback("tally", "Biohazard nuclear victories", 1, "Xenomorphs")
+ if(ROUND_END_CREW_TRANSFER)
+ SSblackbox.record_feedback("tally", "Biohazard survives to normal round end", 1, "Xenomorphs")
+ if(ROUND_END_FORCED)
+ SSblackbox.record_feedback("tally", "Biohazard survives to admin round end", 1, "Xenomorphs")
+ else
+ switch(outcome)
+ if(ROUND_END_NUCLEAR)
+ SSblackbox.record_feedback("tally", "Biohazard dies station nuked", 1, "Xenomorphs")
+ if(ROUND_END_CREW_TRANSFER)
+ SSblackbox.record_feedback("tally", "Biohazard dies normal end", 1, "Xenomorphs")
+ if(ROUND_END_FORCED)
+ SSblackbox.record_feedback("tally", "Biohazard dies admin round end", 1, "Xenomorphs")
+
+ if("Blob")
+ if(length(SSticker.mode.blob_overminds))
+ switch(outcome)
+ if(ROUND_END_NUCLEAR)
+ SSblackbox.record_feedback("tally", "Biohazard nuclear victories", 1, "Blob")
+ if(ROUND_END_CREW_TRANSFER)
+ SSblackbox.record_feedback("tally", "Biohazard survives to normal round end", 1, "Blob")
+ if(ROUND_END_FORCED)
+ SSblackbox.record_feedback("tally", "Biohazard survives to admin round end", 1, "Blob")
+ else
+ switch(outcome)
+ if(ROUND_END_NUCLEAR)
+ SSblackbox.record_feedback("tally", "Biohazard dies station nuked", 1, "Blob")
+ if(ROUND_END_CREW_TRANSFER)
+ SSblackbox.record_feedback("tally", "Biohazard dies normal end", 1, "Blob")
+ if(ROUND_END_FORCED)
+ SSblackbox.record_feedback("tally", "Biohazard dies admin round end", 1, "Blob")
+
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 0c7b18507c8..f20e122a817 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -565,6 +565,7 @@ GLOBAL_VAR(bomb_set)
playsound(src,'sound/machines/alarm.ogg',100,0,5)
if(SSticker && SSticker.mode)
SSticker.mode.explosion_in_progress = TRUE
+ SSticker.event_blackbox(outcome = ROUND_END_NUCLEAR)
sleep(100)
GLOB.enter_allowed = 0
diff --git a/code/modules/admin/misc_admin_procs.dm b/code/modules/admin/misc_admin_procs.dm
index a3d9a0e8eeb..17d1788e0b0 100644
--- a/code/modules/admin/misc_admin_procs.dm
+++ b/code/modules/admin/misc_admin_procs.dm
@@ -406,6 +406,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
message_admins("[key_name_admin(usr)] has admin ended the round with message: '[input]'")
log_admin("[key_name(usr)] has admin ended the round with message: '[input]'")
SSticker.force_ending = TRUE
+ SSticker.event_blackbox(outcome = ROUND_END_FORCED)
to_chat(world, "[input]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "End Round") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
SSticker.mode_result = "admin ended"
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 858f8ef45b0..f2e6cc5bcf8 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -41,3 +41,4 @@
spawncount--
successSpawn = TRUE
+ SSevents.biohazards_this_round += "Xenomorphs"
diff --git a/code/modules/events/blob_spawn.dm b/code/modules/events/blob_spawn.dm
index 4220569f120..9061bbbaf08 100644
--- a/code/modules/events/blob_spawn.dm
+++ b/code/modules/events/blob_spawn.dm
@@ -39,3 +39,4 @@
to_chat(B, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Blob)")
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B, action = NOTIFY_FOLLOW)
successSpawn = TRUE
+ SSevents.biohazards_this_round += "Blob"
diff --git a/code/modules/events/spider_terror.dm b/code/modules/events/spider_terror.dm
index 9f0d0a677a5..51f71526d24 100644
--- a/code/modules/events/spider_terror.dm
+++ b/code/modules/events/spider_terror.dm
@@ -1,9 +1,4 @@
#define TS_HIGHPOP_TRIGGER 80
-#define GREEN_SPIDER 1
-#define PRINCE_SPIDER 2
-#define WHITE_SPIDER 3
-#define PRINCESS_SPIDER 4
-#define QUEEN_SPIDER 5
/datum/event/spider_terror
announceWhen = 240
@@ -28,27 +23,27 @@
var/spider_type
var/infestation_type
if((length(GLOB.clients)) < TS_HIGHPOP_TRIGGER)
- infestation_type = pick(GREEN_SPIDER, PRINCE_SPIDER, WHITE_SPIDER, PRINCESS_SPIDER)
+ infestation_type = pick(TS_INFESTATION_GREEN_SPIDER, TS_INFESTATION_PRINCE_SPIDER, TS_INFESTATION_WHITE_SPIDER, TS_INFESTATION_PRINCESS_SPIDER)
else
- infestation_type = pick(PRINCE_SPIDER, WHITE_SPIDER, PRINCESS_SPIDER, QUEEN_SPIDER)
+ infestation_type = pick(TS_INFESTATION_PRINCE_SPIDER, TS_INFESTATION_WHITE_SPIDER, TS_INFESTATION_PRINCESS_SPIDER, TS_INFESTATION_QUEEN_SPIDER)
switch(infestation_type)
- if(GREEN_SPIDER)
+ if(TS_INFESTATION_GREEN_SPIDER)
// Weakest, only used during lowpop.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/green
spawncount = 5
- if(PRINCE_SPIDER)
+ if(TS_INFESTATION_PRINCE_SPIDER)
// Fairly weak. Dangerous in single combat but has little staying power. Always gets whittled down.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/prince
spawncount = 1
- if(WHITE_SPIDER)
+ if(TS_INFESTATION_WHITE_SPIDER)
// Variable. Depends how many they infect.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
spawncount = 2
- if(PRINCESS_SPIDER)
+ if(TS_INFESTATION_PRINCESS_SPIDER)
// Pretty strong.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen/princess
spawncount = 3
- if(QUEEN_SPIDER)
+ if(TS_INFESTATION_QUEEN_SPIDER)
// Strongest, only used during highpop.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
spawncount = 1
@@ -71,10 +66,6 @@
S.give_intro_text()
spawncount--
successSpawn = TRUE
+ SSevents.biohazards_this_round += infestation_type
#undef TS_HIGHPOP_TRIGGER
-#undef GREEN_SPIDER
-#undef PRINCE_SPIDER
-#undef WHITE_SPIDER
-#undef PRINCESS_SPIDER
-#undef QUEEN_SPIDER