diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index 8e743d44521..7fa94f8c8ec 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -5,6 +5,7 @@ #define SHUTTLE_CALL "called" #define SHUTTLE_DOCKED "docked" #define SHUTTLE_STRANDED "stranded" +#define SHUTTLE_DISABLED "disabled" #define SHUTTLE_ESCAPE "escape" #define SHUTTLE_ENDGAME "endgame: game over" #define SHUTTLE_RECHARGING "recharging" diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 41d3b87598a..87354c3bd11 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -26,6 +26,9 @@ SUBSYSTEM_DEF(shuttle) var/emergencyCallAmount = 0 //how many times the escape shuttle was called var/emergencyNoEscape var/emergencyNoRecall = FALSE + var/adminEmergencyNoRecall = FALSE + var/lastMode = SHUTTLE_IDLE + var/lastCallTime = 6000 var/list/hostileEnvironments = list() //Things blocking escape shuttle from leaving var/list/tradeBlockade = list() //Things blocking cargo from leaving. var/supplyBlocked = FALSE @@ -126,7 +129,7 @@ SUBSYSTEM_DEF(shuttle) break /datum/controller/subsystem/shuttle/proc/CheckAutoEvac() - if(emergencyNoEscape || emergencyNoRecall || !emergency || !SSticker.HasRoundStarted()) + if(emergencyNoEscape || adminEmergencyNoRecall || emergencyNoRecall || !emergency || !SSticker.HasRoundStarted()) return var/threshold = CONFIG_GET(number/emergency_shuttle_autocall_threshold) @@ -153,10 +156,17 @@ SUBSYSTEM_DEF(shuttle) emergency.request(null, set_coefficient = 0.4) /datum/controller/subsystem/shuttle/proc/block_recall(lockout_timer) + if(adminEmergencyNoRecall) + priority_announce("Error!", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg') + addtimer(CALLBACK(src, .proc/unblock_recall), lockout_timer) + return emergencyNoRecall = TRUE addtimer(CALLBACK(src, .proc/unblock_recall), lockout_timer) /datum/controller/subsystem/shuttle/proc/unblock_recall() + if(adminEmergencyNoRecall) + priority_announce("Error!", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg') + return emergencyNoRecall = FALSE /datum/controller/subsystem/shuttle/proc/getShuttle(id) @@ -193,7 +203,7 @@ SUBSYSTEM_DEF(shuttle) if(SHUTTLE_ESCAPE) to_chat(user, "The emergency shuttle is moving away to a safe distance.") return FALSE - if(SHUTTLE_STRANDED) + if(SHUTTLE_STRANDED, SHUTTLE_DISABLED) to_chat(user, "The emergency shuttle has been disabled by CentCom.") return FALSE @@ -284,7 +294,7 @@ SUBSYSTEM_DEF(shuttle) return 1 /datum/controller/subsystem/shuttle/proc/canRecall() - if(!emergency || emergency.mode != SHUTTLE_CALL || emergencyNoRecall || SSticker.mode.name == "meteor") + if(!emergency || emergency.mode != SHUTTLE_CALL || adminEmergencyNoRecall || emergencyNoRecall || SSticker.mode.name == "meteor") return var/security_num = seclevel2num(get_security_level()) switch(security_num) @@ -891,4 +901,3 @@ SUBSYSTEM_DEF(shuttle) message_admins("[key_name_admin(usr)] loaded [mdp] with the shuttle manipulator.") log_admin("[key_name(usr)] loaded [mdp] with the shuttle manipulator.") SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]") - diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index df2a1e99538..2b9f67be872 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -158,7 +158,7 @@ replacementmode = pickweight(usable_modes) switch(SSshuttle.emergency.mode) //Rounds on the verge of ending don't get new antags, they just run out - if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE) + if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE, SHUTTLE_DISABLED) return TRUE if(SHUTTLE_CALL) if(SSshuttle.emergency.timeLeft(1) < initial(SSshuttle.emergencyCallTime)*0.5) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 818c61b7737..a108d21e6ee 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -59,6 +59,8 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/jumptoturf, /*allows us to jump to a specific turf*/ /client/proc/admin_call_shuttle, /*allows us to call the emergency shuttle*/ /client/proc/admin_cancel_shuttle, /*allows us to cancel the emergency shuttle, sending it back to centcom*/ + /client/proc/admin_disable_shuttle, /*allows us to disable the emergency shuttle admin-wise so that it cannot be called*/ + /client/proc/admin_enable_shuttle, /*undoes the above*/ /client/proc/cmd_admin_direct_narrate, /*send text directly to a player with no padding. Useful for narratives and fluff-text*/ /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ /client/proc/cmd_admin_local_narrate, /*sends text to all mobs within view of atom*/ diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index e5bf8ed3739..787003c8892 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -726,7 +726,6 @@ Traitors and the like can also be revived with the previous role mostly intact. SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Change View Range", "[view]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/admin_call_shuttle() - set category = "Admin - Events" set name = "Call Shuttle" @@ -736,14 +735,18 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!check_rights(R_ADMIN)) return - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") - if(confirm != "Yes") - return + var/confirm = alert(src, "You sure?", "Confirm", "Yes", "Yes (No Recall)", "No") + switch(confirm) + if(null, "No") + return + if("Yes (No Recall)") + SSshuttle.adminEmergencyNoRecall = TRUE + SSshuttle.emergency.mode = SHUTTLE_IDLE SSshuttle.emergency.request() SSblackbox.record_feedback("tally", "admin_verb", 1, "Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! log_admin("[key_name(usr)] admin-called the emergency shuttle.") - message_admins("[key_name_admin(usr)] admin-called the emergency shuttle.") + message_admins("[key_name_admin(usr)] admin-called the emergency shuttle[confirm == "Yes (No Recall)" ? " (non-recallable)" : ""].") return /client/proc/admin_cancel_shuttle() @@ -754,6 +757,9 @@ Traitors and the like can also be revived with the previous role mostly intact. if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return + if(SSshuttle.adminEmergencyNoRecall) + SSshuttle.adminEmergencyNoRecall = FALSE + if(EMERGENCY_AT_LEAST_DOCKED) return @@ -764,6 +770,55 @@ Traitors and the like can also be revived with the previous role mostly intact. return +/client/proc/admin_disable_shuttle() + set category = "Admin - Events" + set name = "Disable Shuttle" + + if(!check_rights(R_ADMIN)) + return + + if(SSshuttle.emergency.mode == SHUTTLE_DISABLED) + to_chat(usr, "Error, shuttle is already disabled.") + return + + if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") + return + + message_admins("[key_name_admin(usr)] disabled the shuttle.") + + SSshuttle.lastMode = SSshuttle.emergency.mode + SSshuttle.lastCallTime = SSshuttle.emergency.timeLeft(1) + SSshuttle.adminEmergencyNoRecall = TRUE + SSshuttle.emergency.setTimer(0) + SSshuttle.emergency.mode = SHUTTLE_DISABLED + priority_announce("Warning: Emergency Shuttle uplink failure, shuttle disabled until further notice.", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg') + +/client/proc/admin_enable_shuttle() + set category = "Admin - Events" + set name = "Enable Shuttle" + + if(!check_rights(R_ADMIN)) + return + + if(SSshuttle.emergency.mode != SHUTTLE_DISABLED) + to_chat(usr, "Error, shuttle not disabled.") + return + + if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") + return + + message_admins("[key_name_admin(usr)] enabled the emergency shuttle.") + SSshuttle.adminEmergencyNoRecall = FALSE + SSshuttle.emergencyNoRecall = FALSE + if(SSshuttle.lastMode == SHUTTLE_DISABLED) //If everything goes to shit, fix it. + SSshuttle.lastMode = SHUTTLE_IDLE + + SSshuttle.emergency.mode = SSshuttle.lastMode + if(SSshuttle.lastCallTime < 10 SECONDS && SSshuttle.lastMode != SHUTTLE_IDLE) + SSshuttle.lastCallTime = 10 SECONDS //Make sure no insta departures. + SSshuttle.emergency.setTimer(SSshuttle.lastCallTime) + priority_announce("Warning: Emergency Shuttle uplink reestablished, shuttle enabled.", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg') + /client/proc/everyone_random() set category = "Fun" set name = "Make Everyone Random" diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 781675858cc..970a167dc62 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -57,6 +57,8 @@ return if(!IS_DOCKED) // shuttle computer only has uses when onstation return + if(SSshuttle.emergency.mode == SHUTTLE_DISABLED) // admins have disabled the shuttle. + return var/mob/user = usr . = FALSE @@ -243,7 +245,7 @@ else SSshuttle.emergencyLastCallLoc = null - priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlecalled.ogg', "Priority") + priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.adminEmergencyNoRecall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", null, 'sound/ai/shuttlecalled.ogg', "Priority") /obj/docking_port/mobile/emergency/cancel(area/signalOrigin) if(mode != SHUTTLE_CALL) @@ -387,9 +389,10 @@ INVOKE_ASYNC(SSticker, /datum/controller/subsystem/ticker.proc/poll_hearts) SSmapping.mapvote() //If no map vote has been run yet, start one. - if(SHUTTLE_STRANDED) + if(SHUTTLE_STRANDED, SHUTTLE_DISABLED) SSshuttle.checkHostileEnvironment() + if(SHUTTLE_ESCAPE) if(sound_played && time_left <= HYPERSPACE_END_TIME) var/list/areas = list() diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index bbb159fcb0b..c123e4a4e34 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -707,11 +707,13 @@ return "RCH" if(SHUTTLE_PREARRIVAL) return "LDN" + if(SHUTTLE_DISABLED) + return "DIS" return "" // returns 5-letter timer string, used by status screens and mob status panel /obj/docking_port/mobile/proc/getTimerStr() - if(mode == SHUTTLE_STRANDED) + if(mode == SHUTTLE_STRANDED || mode == SHUTTLE_DISABLED) return "--:--" var/timeleft = timeLeft()