diff --git a/code/modules/turbolift/turbolift.dm b/code/modules/turbolift/turbolift.dm
index 0ca172e7e9b..7a670954a0a 100644
--- a/code/modules/turbolift/turbolift.dm
+++ b/code/modules/turbolift/turbolift.dm
@@ -9,16 +9,74 @@
var/floor_wait_delay = 85 // Time to wait at floor stops.
var/obj/structure/lift/panel/control_panel_interior // Lift control panel.
var/doors_closing = 0 // Whether doors are in the process of closing
+ var/list/music = null // Elevator music to set on areas
+ var/priority_mode = FALSE // Flag to block buttons from calling the elevator if in priority mode.
+ var/fire_mode = FALSE // Flag to indicate firefighter mode is active.
var/tmp/moving_upwards
var/tmp/busy
/datum/turbolift/proc/emergency_stop()
- queued_floors.Cut()
+ cancel_pending_floors()
target_floor = null
- open_doors()
+ if(!fire_mode)
+ open_doors()
+
+// Enter priority mode, blocking all calls for awhile
+/datum/turbolift/proc/priority_mode(var/time = 30 SECONDS)
+ priority_mode = TRUE
+ cancel_pending_floors()
+ update_ext_panel_icons()
+ control_panel_interior.audible_message("This turbolift is responding to a priority call. Please exit the lift when it stops and make way.")
+ spawn(time)
+ priority_mode = FALSE
+ update_ext_panel_icons()
+
+/datum/turbolift/proc/update_fire_mode(var/new_fire_mode)
+ if(fire_mode == new_fire_mode)
+ return
+ fire_mode = new_fire_mode
+ if(new_fire_mode)
+ cancel_pending_floors()
+
+ // Turn the lights red and kill the music
+ for(var/datum/turbolift_floor/F in floors)
+ var/area/turbolift/A = locate(F.area_ref)
+ if(new_fire_mode)
+ if(A.forced_ambience)
+ A.forced_ambience.Cut()
+ A.fire_alert()
+ else
+ if(music)
+ A.forced_ambience = music.Copy()
+ A.fire_reset()
+ for(var/mob/living/M in mobs_in_area(A))
+ if(M.mind)
+ A.play_ambience(M)
+ // Disable safeties on the doors during firemode, reset when done
+ for(var/obj/machinery/door/airlock/door in F.doors)
+ door.safe = new_fire_mode ? FALSE : initial(door.safe)
+
+ // Disable safeties on the doors during firemode, reset when done
+ for(var/obj/machinery/door/airlock/door in doors)
+ door.safe = new_fire_mode ? FALSE : initial(door.safe)
+ update_ext_panel_icons()
+ control_panel_interior.update_icon()
+
+// Cancel all pending calls
+/datum/turbolift/proc/cancel_pending_floors()
+ for(var/datum/turbolift_floor/floor in queued_floors)
+ if(floor.ext_panel)
+ floor.ext_panel.reset()
+ queued_floors.Cut()
control_panel_interior.updateDialog()
+// Update the icons of all exterior panels (after we change modes etc)
+/datum/turbolift/proc/update_ext_panel_icons()
+ for(var/datum/turbolift_floor/floor in floors)
+ if(floor.ext_panel)
+ floor.ext_panel.update_icon()
+
/datum/turbolift/proc/doors_are_open(var/datum/turbolift_floor/use_floor = current_floor)
for(var/obj/machinery/door/airlock/door in (use_floor ? (doors + use_floor.doors) : doors))
if(!door.density)
@@ -61,7 +119,8 @@
return 1
else // We failed to close the doors - probably, someone is blocking them; stop trying to move
doors_closing = 0
- open_doors()
+ if(!fire_mode)
+ open_doors()
control_panel_interior.audible_message("\The [current_floor.ext_panel] buzzes loudly.")
playsound(control_panel_interior.loc, "sound/machines/buzz-two.ogg", 50, 1)
return 0
diff --git a/code/modules/turbolift/turbolift_console.dm b/code/modules/turbolift/turbolift_console.dm
index a30aa9be397..e77447c0d2a 100644
--- a/code/modules/turbolift/turbolift_console.dm
+++ b/code/modules/turbolift/turbolift_console.dm
@@ -54,6 +54,7 @@
desc = "A call button for an elevator. Be sure to hit it three hundred times."
icon_state = "button"
var/light_up = FALSE
+ req_access = list(access_eva)
var/datum/turbolift_floor/floor
/obj/structure/lift/button/Destroy()
@@ -66,9 +67,27 @@
light_up = FALSE
update_icon()
+// Hit it with a PDA or ID to enable priority call mode
+/obj/structure/lift/button/attackby(obj/item/W as obj, mob/user as mob)
+ var/obj/item/weapon/card/id/id = W.GetID()
+ if(istype(id))
+ if(!check_access(id))
+ playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
+ return
+ lift.priority_mode()
+ if(floor == lift.current_floor)
+ lift.open_doors()
+ else
+ lift.queue_move_to(floor)
+ return
+ . = ..()
+
/obj/structure/lift/button/interact(var/mob/user)
if(!..())
return
+ if(lift.fire_mode || lift.priority_mode)
+ playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
+ return
light_up()
pressed(user)
if(floor == lift.current_floor)
@@ -83,7 +102,11 @@
update_icon()
/obj/structure/lift/button/update_icon()
- if(light_up)
+ if(lift.fire_mode)
+ icon_state = "button_fire"
+ else if(lift.priority_mode)
+ icon_state = "button_pri"
+ else if(light_up)
icon_state = "button_lit"
else
icon_state = initial(icon_state)
@@ -94,7 +117,24 @@
/obj/structure/lift/panel
name = "elevator control panel"
icon_state = "panel"
+ req_access = list(access_eva)
+ req_one_access = list(access_heads, access_atmospherics, access_medical)
+// Hit it with a PDA or ID to enable priority call mode
+/obj/structure/lift/panel/attackby(obj/item/W as obj, mob/user as mob)
+ var/obj/item/weapon/card/id/id = W.GetID()
+ if(istype(id))
+ if(!check_access(id))
+ playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
+ return
+ lift.update_fire_mode(!lift.fire_mode)
+ if(lift.fire_mode)
+ audible_message("Firefighter Mode Activated. Door safeties disabled. Manual control engaged.")
+ playsound(src.loc, 'sound/machines/airalarm.ogg', 25, 0, 4)
+ else
+ audible_message("Firefighter Mode Deactivated. Door safeties enabled. Automatic control engaged.")
+ return
+ . = ..()
/obj/structure/lift/panel/attack_ghost(var/mob/user)
return interact(user)
@@ -154,4 +194,10 @@
return 0
+/obj/structure/lift/panel/update_icon()
+ if(lift.fire_mode)
+ icon_state = "panel_fire"
+ else
+ icon_state = initial(icon_state)
+
// End panel.
\ No newline at end of file
diff --git a/code/modules/turbolift/turbolift_door.dm b/code/modules/turbolift/turbolift_door.dm
index 79bf1d0c51a..4b83bc60cf9 100644
--- a/code/modules/turbolift/turbolift_door.dm
+++ b/code/modules/turbolift/turbolift_door.dm
@@ -24,6 +24,8 @@
return FALSE //only the lift machinery is allowed to operate this door
/obj/machinery/door/airlock/lift/close(var/forced=0)
+ if(!safe)
+ return ..()
for(var/turf/turf in locs)
for(var/mob/living/LM in turf)
if(LM.mob_size <= MOB_TINY)
diff --git a/code/modules/turbolift/turbolift_floor.dm b/code/modules/turbolift/turbolift_floor.dm
index 46e4dfa0f48..85b4820c7fc 100644
--- a/code/modules/turbolift/turbolift_floor.dm
+++ b/code/modules/turbolift/turbolift_floor.dm
@@ -30,6 +30,7 @@
//called when a lift arrives at this floor
/datum/turbolift_floor/proc/arrived(var/datum/turbolift/lift)
- lift.open_doors(src)
+ if(!lift.fire_mode)
+ lift.open_doors(src)
if(ext_panel)
ext_panel.reset()
\ No newline at end of file
diff --git a/icons/obj/turbolift.dmi b/icons/obj/turbolift.dmi
index cffc8aa140c..fce013604c8 100644
Binary files a/icons/obj/turbolift.dmi and b/icons/obj/turbolift.dmi differ
diff --git a/maps/tether/tether_things.dm b/maps/tether/tether_things.dm
index 06081f5aa75..3c2cc0ad02b 100644
--- a/maps/tether/tether_things.dm
+++ b/maps/tether/tether_things.dm
@@ -18,6 +18,7 @@
lift_size_x = 3
lift_size_y = 3
icon = 'icons/obj/turbolift_preview_3x3.dmi'
+ wall_type = null // Don't make walls
areas_to_use = list(
/area/turbolift/t_surface/level1,
@@ -29,6 +30,9 @@
/area/turbolift/t_station/level3
)
+/datum/turbolift
+ music = list('sound/music/elevator.ogg') // Woo elevator music!
+
/obj/machinery/atmospherics/unary/vent_pump/positive
use_power = 1
icon_state = "map_vent_out"