diff --git a/code/controllers/subsystems/initialization/codex_dump.dm b/code/controllers/subsystems/initialization/codex_dump.dm
index b12dd686d78b..3f6709a85009 100644
--- a/code/controllers/subsystems/initialization/codex_dump.dm
+++ b/code/controllers/subsystems/initialization/codex_dump.dm
@@ -131,7 +131,8 @@ TODO: work out how to implement an external search function.
/obj/item/organ/external/chest,
/obj/machinery/power/apc,
/obj/machinery/alarm,
- /obj/structure/stairs
+ /obj/structure/stairs,
+ /obj/machinery/computer/shuttle,
)
// Suspend to avoid fluid flows shoving stuff off the testing turf.
diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm
index a63d6d3b2ead..4926d5472950 100644
--- a/code/game/machinery/computer/shuttle.dm
+++ b/code/game/machinery/computer/shuttle.dm
@@ -5,66 +5,60 @@
icon_screen = "shuttle"
light_color = "#00ffff"
construct_state = null
- var/auth_need = 3.0
- var/list/authorized = list( )
+ var/auths_needed = 3
+ var/list/authorized
+/obj/machinery/computer/shuttle/Initialize()
+ if(!istype(SSevac.evacuation_controller, /datum/evacuation_controller/shuttle))
+ PRINT_STACK_TRACE("Shuttle console found without a shuttle evacuation controller!")
+ return INITIALIZE_HINT_QDEL
+ return ..()
/obj/machinery/computer/shuttle/attackby(var/obj/item/used_item, var/mob/user)
- if(stat & (BROKEN|NOPOWER)) return TRUE
-
- var/datum/evacuation_controller/shuttle/evac_control = SSevac.evacuation_controller
- if(!istype(evac_control))
- to_chat(user, "This console should not be in use on this map. Please report this to a developer.")
+ if(stat & (BROKEN|NOPOWER))
return TRUE
- if(!istype(used_item, /obj/item/card)) // don't try to get an ID card if we're an emag
- used_item = used_item.GetIdCard() // handles stored IDs in modcomps and similar
-
- if ((!istype(used_item, /obj/item/card) || evac_control.has_evacuated() || !user))
+ var/obj/item/card/id/id_card = used_item.GetIdCard() // if used_item is already an ID, it'll just return itself
+ if(!istype(id_card, /obj/item/card/id) || SSevac.evacuation_controller.has_evacuated() || SSevac.evacuation_controller.is_prepared() || !user)
return FALSE
- if (istype(used_item, /obj/item/card/id))
- var/obj/item/card/id/id_card = used_item
- if(!LAZYISIN(id_card.access, access_bridge)) //doesn't have this access
- to_chat(user, "The access level of [id_card.registered_name]\'s card is not high enough.")
- return TRUE
-
- var/choice = alert(user, "Would you like to (un)authorize a shortened launch time? [auth_need - authorized.len] authorization\s are still needed. Use abort to cancel all authorizations.", "Shuttle Launch", "Authorize", "Repeal", "Abort")
- if(evac_control.is_prepared() && user.get_active_held_item() != used_item)
- return TRUE
- switch(choice)
- if("Authorize")
- src.authorized -= id_card.registered_name
- src.authorized += id_card.registered_name
- if (src.auth_need - src.authorized.len > 0)
- message_admins("[key_name_admin(user)] has authorized early shuttle launch")
- log_game("[user.ckey] has authorized early shuttle launch")
- to_world("Alert: [auth_need - authorized.len] authorizations needed until shuttle is launched early")
- else
- message_admins("[key_name_admin(user)] has launched the shuttle")
- log_game("[user.ckey] has launched the shuttle early")
- to_world("Alert: Shuttle launch time shortened to 10 seconds!")
- evac_control.set_launch_time(world.time+100)
- //src.authorized = null
- qdel(src.authorized)
- src.authorized = list( )
+ if(!LAZYISIN(id_card.access, access_bridge)) //doesn't have the required access
+ to_chat(user, "The access level of [id_card.registered_name]\'s card is not high enough.")
+ return TRUE
- if("Repeal")
- src.authorized -= id_card.registered_name
- to_world("Alert: [auth_need - authorized.len] authorizations needed until shuttle is launched early")
+ var/choice = alert(user, "Would you like to (un)authorize a shortened launch time? [auths_needed - LAZYLEN(authorized)] authorization\s are still needed. Use abort to cancel all authorizations.", "Shuttle Launch", "Authorize", "Repeal", "Abort")
+ // since alert() sleeps, we need to recheck the previous SSevacuation conditions
+ // and make sure used_item is still being held
+ if(SSevac.evacuation_controller.has_evacuated() || SSevac.evacuation_controller.is_prepared() || user.get_active_held_item() != used_item)
+ return TRUE // we've already had a user-visible interaction, so return TRUE to avoid further interactions this click
+ switch(choice)
+ if("Authorize")
+ LAZYDISTINCTADD(authorized, id_card.registered_name)
+ if (LAZYLEN(authorized) >= auths_needed)
+ message_admins("[key_name_admin(user)] has launched the shuttle")
+ log_game("[user.ckey] has launched the shuttle early")
+ to_world(SPAN_NOTICE("Alert: Shuttle launch time shortened to 10 seconds!"))
+ SSevac.evacuation_controller.evac_launch_time = world.time + 10 SECONDS
+ LAZYCLEARLIST(authorized)
+ else
+ message_admins("[key_name_admin(user)] has authorized early shuttle launch")
+ log_game("[user.ckey] has authorized early shuttle launch")
+ to_world(SPAN_NOTICE("Alert: [auths_needed - LAZYLEN(authorized)] authorizations needed until shuttle is launched early"))
- if("Abort")
- to_world("All authorizations to shortening time for shuttle launch have been revoked!")
- src.authorized.len = 0
- src.authorized = list( )
- return TRUE
+ if("Repeal")
+ LAZYREMOVE(authorized, id_card.registered_name)
+ to_world(SPAN_NOTICE("Alert: [auths_needed - LAZYLEN(authorized)] authorizations needed until shuttle is launched early"))
- else if (istype(used_item, /obj/item/card/emag) && !emagged)
- var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel")
+ if("Abort")
+ to_world(SPAN_NOTICE("All authorizations to shortening time for shuttle launch have been revoked!"))
+ LAZYCLEARLIST(authorized)
+ return TRUE
- if(!emagged && !evac_control.is_prepared() && user.get_active_held_item() == used_item && choice == "Launch")
- to_world("Alert: Shuttle launch time shortened to 10 seconds!")
- evac_control.set_launch_time(world.time+100)
- emagged = 1
- return TRUE
- return FALSE
+/obj/machinery/computer/shuttle/emag_act(remaining_charges, mob/user, emag_source)
+ // Must not be launched or launching, and not already emagged
+ if(SSevac.evacuation_controller.has_evacuated() || SSevac.evacuation_controller.is_prepared() || emagged)
+ return NO_EMAG_ACT
+ to_world(SPAN_NOTICE("Alert: Shuttle launch time shortened to 10 seconds!"))
+ SSevac.evacuation_controller.evac_launch_time = world.time + 10 SECONDS
+ emagged = TRUE
+ return 1 // not a bool, number of charges to consume
\ No newline at end of file
diff --git a/code/unit_tests/del_the_world.dm b/code/unit_tests/del_the_world.dm
index 411ef21b8d33..a8511d562137 100644
--- a/code/unit_tests/del_the_world.dm
+++ b/code/unit_tests/del_the_world.dm
@@ -13,7 +13,9 @@
// throw assert failures around non-null alarm area on spawn
/obj/machinery/alarm,
// Needs a level above.
- /obj/structure/stairs
+ /obj/structure/stairs,
+ // Needs to have the right evac controller
+ /obj/machinery/computer/shuttle,
)
// Suspend to avoid fluid flows shoving stuff off the testing turf.