mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-19 20:06:28 +01:00
389466360e
Refactored sorting. Added test to verify all horizon areas (outside exceptions) are marked as station areas. Added test to verify shuttle areas are not marked as station areas. Refactored how the area sorting var is made and used. Added a global list of all areas.
143 lines
4.5 KiB
Plaintext
143 lines
4.5 KiB
Plaintext
// Lift master datum. One per turbolift.
|
|
/datum/turbolift
|
|
var/datum/turbolift_floor/target_floor // Where are we going?
|
|
var/datum/turbolift_floor/current_floor // Where is the lift currently?
|
|
var/list/doors = list() // Doors inside the lift structure.
|
|
var/list/queued_floors = list() // Where are we moving to next?
|
|
var/list/floors = list() // All floors in this system.
|
|
var/move_delay = 15 // Time between floor changes.
|
|
var/floor_wait_delay = 95 // 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/tmp/moving_upwards
|
|
var/tmp/busy
|
|
|
|
var/move_timer
|
|
|
|
/datum/turbolift/proc/emergency_stop()
|
|
deltimer(move_timer)
|
|
move_timer = null
|
|
queued_floors.Cut()
|
|
target_floor = null
|
|
open_doors()
|
|
|
|
/datum/turbolift/proc/doors_are_open(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)
|
|
return 1
|
|
return 0
|
|
|
|
/datum/turbolift/proc/open_doors(datum/turbolift_floor/use_floor = current_floor)
|
|
for(var/obj/machinery/door/airlock/door in (use_floor ? (doors + use_floor.doors) : doors))
|
|
door.command("open")
|
|
|
|
/datum/turbolift/proc/close_doors(datum/turbolift_floor/use_floor = current_floor)
|
|
for(var/obj/machinery/door/airlock/door in (use_floor ? (doors + use_floor.doors) : doors))
|
|
door.command("close")
|
|
|
|
/datum/turbolift/proc/do_work()
|
|
var/current_floor_index = floors.Find(current_floor)
|
|
|
|
if(!target_floor)
|
|
if(!queued_floors || !queued_floors.len)
|
|
return 0
|
|
|
|
target_floor = queued_floors[1]
|
|
queued_floors -= target_floor
|
|
if(current_floor_index < floors.Find(target_floor))
|
|
moving_upwards = 1
|
|
else
|
|
moving_upwards = 0
|
|
|
|
if(doors_are_open())
|
|
if(!doors_closing)
|
|
close_doors()
|
|
doors_closing = 1
|
|
queue_movement(move_delay / 2)
|
|
return 1
|
|
|
|
else // We failed to close the doors - probably, someone is blocking them; stop trying to move
|
|
doors_closing = 0
|
|
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
|
|
|
|
doors_closing = 0 // The doors weren't open, so they are done closing
|
|
|
|
var/area/turbolift/origin = locate(current_floor.area_ref) in get_sorted_areas()
|
|
|
|
if(target_floor == current_floor)
|
|
playsound(control_panel_interior.loc, origin.arrival_sound, 50, 1)
|
|
target_floor.arrived(src)
|
|
target_floor = null
|
|
|
|
sleep(15)
|
|
control_panel_interior.visible_message("<b>The elevator</b> announces, \"[origin.lift_announce_str]\"")
|
|
|
|
queue_movement(floor_wait_delay + move_delay)
|
|
return 1
|
|
|
|
// Work out where we're headed.
|
|
var/datum/turbolift_floor/next_floor
|
|
if(moving_upwards)
|
|
next_floor = floors[current_floor_index + 1]
|
|
else
|
|
next_floor = floors[current_floor_index - 1]
|
|
|
|
var/area/turbolift/destination = locate(next_floor.area_ref) in get_sorted_areas()
|
|
|
|
if(!istype(origin) || !istype(destination) || (origin == destination))
|
|
return 0
|
|
|
|
var/list/move_candidates = list()
|
|
if(!moving_upwards)
|
|
for(var/turf/T in destination)
|
|
for(var/atom/movable/AM in T)
|
|
AM.crush_act()
|
|
else
|
|
for(var/turf/simulated/wall/W in origin)
|
|
var/turf/T = GET_TURF_ABOVE(W)
|
|
for(var/atom/movable/AM in T)
|
|
if(next_floor == floors[floors.len])
|
|
AM.crush_act()
|
|
else
|
|
move_candidates += AM
|
|
|
|
origin.move_contents_to(destination)
|
|
for(var/thing in move_candidates)
|
|
var/atom/movable/AM = thing
|
|
var/turf/T = get_turf(AM)
|
|
if(istype(T))
|
|
AM.forceMove(GET_TURF_ABOVE(T))
|
|
|
|
current_floor = next_floor
|
|
control_panel_interior.visible_message("The elevator [moving_upwards ? "rises" : "descends"] smoothly.")
|
|
|
|
queue_movement()
|
|
return 1
|
|
|
|
/datum/turbolift/proc/queue_move_to(datum/turbolift_floor/floor)
|
|
if(!floor || !(floor in floors) || (floor in queued_floors))
|
|
return // STOP PRESSING THE BUTTON.
|
|
floor.pending_move(src)
|
|
queued_floors |= floor
|
|
queue_movement()
|
|
|
|
// TODO: dummy machine ('lift mechanism') in powered area for functionality/blackout checks.
|
|
/datum/turbolift/proc/is_functional()
|
|
return 1
|
|
|
|
/datum/turbolift/proc/handle_movement()
|
|
if (!do_work())
|
|
if (target_floor)
|
|
target_floor.ext_panel.reset()
|
|
target_floor = null
|
|
|
|
/datum/turbolift/proc/queue_movement(delay = move_delay)
|
|
if (!delay)
|
|
delay = move_delay
|
|
|
|
move_timer = addtimer(CALLBACK(src, PROC_REF(handle_movement)), delay, TIMER_STOPPABLE | TIMER_UNIQUE)
|