diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm
index db4cd6fbec0..bf934dc242c 100644
--- a/code/controllers/subsystem/shuttles.dm
+++ b/code/controllers/subsystem/shuttles.dm
@@ -43,6 +43,8 @@ var/datum/subsystem/shuttle/SSshuttle
var/shuttle_purchased = FALSE //If the station has purchased a replacement escape shuttle this round
var/list/shuttle_purchase_requirements_met = list() //For keeping track of ingame events that would unlock new shuttles, such as defeating a boss or discovering a secret item
+ var/lockdown = FALSE //disallow transit after nuke goes off
+
/datum/subsystem/shuttle/New()
NEW_SS_GLOBAL(SSshuttle)
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index b1b00b3d51d..29560785e08 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -218,32 +218,36 @@ var/datum/subsystem/ticker/ticker
if(!adm["present"])
send2irc("Server", "Round just started with no active admins online!")
+/datum/subsystem/ticker/proc/station_explosion_detonation(atom/bomb)
+ if(bomb) //BOOM
+ var/turf/epi = bomb.loc
+ qdel(bomb)
+ if(epi)
+ explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE)
+
//Plus it provides an easy way to make cinematics for other events. Just use this as a template
-/datum/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null)
+/datum/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null, atom/bomb = null)
if( cinematic )
return //already a cinematic in progress!
for (var/datum/html_interface/hi in html_interfaces)
hi.closeAll()
+ SStgui.close_all_uis()
+
+ //Turn off the shuttles, there's no escape now
+ if(!station_missed && bomb)
+ SSshuttle.registerHostileEnvironment(src)
+ SSshuttle.lockdown = TRUE
+
//initialise our cinematic screen object
cinematic = new /obj/screen{icon='icons/effects/station_explosion.dmi';icon_state="station_intact";layer=21;mouse_opacity=0;screen_loc="1,0";}(src)
- if(station_missed)
- for(var/mob/M in mob_list)
- M.notransform = TRUE //stop everything moving
- if(M.client)
- M.client.screen += cinematic //show every client the cinematic
- else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived"
- for(var/mob/M in mob_list)
- if(M.client)
- M.client.screen += cinematic
- if(M.stat != DEAD)
- var/turf/T = get_turf(M)
- if(T && T.z==1)
- M.death(0) //no mercy
- else
- M.notransform=TRUE //no moving for you
+ for(var/mob/M in mob_list)
+ M.notransform = TRUE //stop everything moving
+ if(M.client)
+ M.client.screen += cinematic //show every client the cinematic
+ var/actually_blew_up = TRUE
//Now animate the cinematic
switch(station_missed)
if(NUKE_NEAR_MISS) //nuke was nearby but (mostly) missed
@@ -254,27 +258,32 @@ var/datum/subsystem/ticker/ticker
flick("intro_nuke",cinematic)
sleep(35)
world << sound('sound/effects/explosionfar.ogg')
+ station_explosion_detonation(bomb)
flick("station_intact_fade_red",cinematic)
cinematic.icon_state = "summary_nukefail"
if("gang war") //Gang Domination (just show the override screen)
cinematic.icon_state = "intro_malf_still"
flick("intro_malf",cinematic)
+ actually_blew_up = FALSE
sleep(70)
if("fake") //The round isn't over, we're just freaking people out for fun
flick("intro_nuke",cinematic)
sleep(35)
world << sound('sound/items/bikehorn.ogg')
flick("summary_selfdes",cinematic)
+ actually_blew_up = FALSE
else
flick("intro_nuke",cinematic)
sleep(35)
world << sound('sound/effects/explosionfar.ogg')
- //flick("end",cinematic)
+ station_explosion_detonation(bomb)
if(NUKE_MISS_STATION || NUKE_SYNDICATE_BASE) //nuke was nowhere nearby //TODO: a really distant explosion animation
sleep(50)
world << sound('sound/effects/explosionfar.ogg')
+ station_explosion_detonation(bomb)
+ actually_blew_up = station_missed == NUKE_SYNDICATE_BASE //don't kill everyone on station if it detonated off station
else //station was destroyed
if( mode && !override )
override = mode.name
@@ -284,18 +293,21 @@ var/datum/subsystem/ticker/ticker
sleep(35)
flick("station_explode_fade_red",cinematic)
world << sound('sound/effects/explosionfar.ogg')
+ station_explosion_detonation(bomb)
cinematic.icon_state = "summary_nukewin"
if("AI malfunction") //Malf (screen,explosion,summary)
flick("intro_malf",cinematic)
sleep(76)
flick("station_explode_fade_red",cinematic)
world << sound('sound/effects/explosionfar.ogg')
+ station_explosion_detonation(bomb) //TODO: If we ever decide to actually detonate the vault bomb
cinematic.icon_state = "summary_malf"
if("blob") //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
world << sound('sound/effects/explosionfar.ogg')
+ station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_selfdes"
if("no_core") //Nuke failed to detonate as it had no core
flick("intro_nuke",cinematic)
@@ -314,16 +326,32 @@ var/datum/subsystem/ticker/ticker
sleep(35)
flick("station_explode_fade_red", cinematic)
world << sound('sound/effects/explosionfar.ogg')
+ station_explosion_detonation(bomb)
cinematic.icon_state = "summary_selfdes"
//If its actually the end of the round, wait for it to end.
//Otherwise if its a verb it will continue on afterwards.
- addtimer(CALLBACK(src, .proc/finish_cinematic), 300)
-/datum/subsystem/ticker/proc/finish_cinematic()
+ if(mode)
+ mode.explosion_in_progress = 0
+ world << "The station was destoyed by the nuclear blast!"
+ mode.station_was_nuked = (station_missed<2) //station_missed==1 is a draw. the station becomes irradiated and needs to be evacuated.
+ //kinda shit but I couldn't get permission to do what I wanted to do.
+ var/bombloc = null
+ if(actually_blew_up)
+ if(bomb && bomb.loc)
+ bombloc = bomb.z
+ else if(!station_missed)
+ bombloc = ZLEVEL_STATION
+
+ addtimer(CALLBACK(src, .proc/finish_cinematic, bombloc), 300)
+
+/datum/subsystem/ticker/proc/finish_cinematic(killz)
if(cinematic)
qdel(cinematic) //end the cinematic
for(var/mob/M in mob_list)
- M.notransform = FALSE //gratz you survived
+ M.notransform = FALSE
+ if(!isnull(killz) && M.stat != DEAD && M.z == killz)
+ M.gib()
/datum/subsystem/ticker/proc/create_characters()
for(var/mob/new_player/player in player_list)
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index ec3972a7d96..1199b72c374 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -424,7 +424,7 @@ var/bomb_set
sleep(100)
if(!core)
- ticker.station_explosion_cinematic(3,"no_core")
+ ticker.station_explosion_cinematic(3,"no_core",src)
ticker.mode.explosion_in_progress = 0
return
@@ -443,19 +443,17 @@ var/bomb_set
else
off_station = NUKE_NEAR_MISS
- if(ticker.mode && ticker.mode.name == "nuclear emergency")
+ if(istype(ticker.mode, /datum/game_mode/nuclear))
var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate")
- ticker.mode:syndies_didnt_escape = (Shuttle && Shuttle.z == ZLEVEL_CENTCOM) ? 0 : 1
- ticker.mode:nuke_off_station = off_station
- ticker.station_explosion_cinematic(off_station,null)
+ var/datum/game_mode/nuclear/NM = ticker.mode
+ NM.syndies_didnt_escape = (Shuttle && Shuttle.z == ZLEVEL_CENTCOM) ? 0 : 1
+ NM.nuke_off_station = off_station
+
+ ticker.station_explosion_cinematic(off_station,null,src)
if(ticker.mode)
- ticker.mode.explosion_in_progress = 0
- if(ticker.mode.name == "nuclear emergency")
- ticker.mode:nukes_left --
- else
- world << "The station was destoyed by the nuclear blast!"
- ticker.mode.station_was_nuked = (off_station<2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated.
- //kinda shit but I couldn't get permission to do what I wanted to do.
+ if(istype(ticker.mode, /datum/game_mode/nuclear))
+ var/datum/game_mode/nuclear/NM = ticker.mode
+ NM.nukes_left --
if(!ticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
spawn()
world.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
diff --git a/code/modules/events/wizard/fakeexplosion.dm b/code/modules/events/wizard/fakeexplosion.dm
index 770f876e688..e8e8352c79a 100644
--- a/code/modules/events/wizard/fakeexplosion.dm
+++ b/code/modules/events/wizard/fakeexplosion.dm
@@ -8,5 +8,4 @@
/datum/round_event/wizard/fake_explosion/start()
for(var/mob/M in player_list)
M << 'sound/machines/Alarm.ogg'
- spawn(100)
- ticker.station_explosion_cinematic(1,"fake") //:o)
\ No newline at end of file
+ addtimer(CALLBACK(ticker, /datum/subsystem/ticker/.proc/station_explosion_cinematic, 1, "fake"), 100) //:o)
\ No newline at end of file
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 28fe9de5e47..184f4b7bbb6 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -144,4 +144,4 @@
var/resize = 1 //Badminnery resize
- var/list/observers = null //The list of people observing this mob.
+ var/list/observers = null //The list of people observing this mob.
\ No newline at end of file
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 4e43edea999..153a5badd36 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -345,6 +345,8 @@
mode = SHUTTLE_RECALL
/obj/docking_port/mobile/proc/enterTransit()
+ if(SSshuttle.lockdown && z == ZLEVEL_STATION) //emp went off, no escape
+ return
previous = null
// if(!destination)
// return