Files
Bubberstation/code/modules/transport/linear_controller.dm
grungussuss 58501dce77 Reorganizes the sound folder (#86726)
## About The Pull Request

<details>

- renamed ai folder to announcer

-- announcer --
- moved vox_fem to announcer
- moved approachingTG to announcer

- separated the ambience folder into ambience and instrumental
-- ambience --

- created holy folder moved all related sounds there
- created engineering folder and moved all related sounds there
- created security folder and moved ambidet there
- created general folder and moved ambigen there
- created icemoon folder and moved all icebox-related ambience there
- created medical folder and moved all medbay-related ambi there
- created ruin folder and moves all ruins ambi there
- created beach folder and moved seag and shore there
- created lavaland folder and moved related ambi there
- created aurora_caelus folder and placed its ambi there
- created misc folder and moved the rest of the files that don't have a
specific category into it

-- instrumental --

- moved traitor folder here
- created lobby_music folder and placed our songs there (title0 not used
anywhere? - server-side modification?)

-- items --

- moved secdeath to hailer
- moved surgery to handling

-- effects --

- moved chemistry into effects
- moved hallucinations into effects
- moved health into effects
- moved magic into effects

-- vehicles --

- moved mecha into vehicles


created mobs folder

-- mobs --

- moved creatures folder into mobs
- moved voice into mobs

renamed creatures to non-humanoids
renamed voice to humanoids

-- non-humanoids--

created cyborg folder
created hiss folder
moved harmalarm.ogg to cyborg

-- humanoids --




-- misc --

moved ghostwhisper to misc
moved insane_low_laugh to misc

I give up trying to document this.

</details>

- [X] ambience
- [x] announcer
- [x] effects
- [X] instrumental
- [x] items
- [x] machines
- [x] misc 
- [X] mobs
- [X] runtime
- [X] vehicles

- [ ] attributions

## Why It's Good For The Game

This folder is so disorganized that it's vomit inducing, will make it
easier to find and add new sounds, providng a minor structure to the
sound folder.

## Changelog
🆑 grungussuss
refactor: the sound folder in the source code has been reorganized,
please report any oddities with sounds playing or not playing
server: lobby music has been repathed to sound/music/lobby_music
/🆑
2024-09-23 22:24:50 -07:00

641 lines
25 KiB
Plaintext

/// If anyone changes the hydraulic sound effect I sure hope they update this...
#define HYDRAULIC_SFX_DURATION (2 SECONDS)
///coordinate and control movement across linked transport_controllers. allows moving large single multitile platforms and many 1 tile platforms.
///also is capable of linking platforms across linked z levels
/datum/transport_controller/linear
///the lift platforms we consider as part of this transport. ordered in order of lowest z level to highest z level after init.
///(the sorting algorithm sucks btw)
var/list/obj/structure/transport/linear/transport_modules
/// Typepath list of what to ignore smashing through, controls all lifts
var/static/list/ignored_smashthroughs = list(
/obj/machinery/power/supermatter_crystal,
/obj/structure/holosign,
/obj/machinery/field,
/obj/structure/fluff/tram_rail,
)
///whether the lift handled by this transport_controller datum is multitile as opposed to nxm platforms per z level
var/modular_set = FALSE
///taken from our lift platforms. if true we go through each z level of platforms and attempt to make the lowest left corner platform
///into one giant multitile object the size of all other platforms on that z level.
var/create_modular_set = FALSE
///lift platforms have already been sorted in order of z level.
var/z_sorted = FALSE
///transport_id taken from our base lift platform, used to put us into SStransport.transports_by_type
var/transport_id = TRANSPORT_TYPE_ELEVATOR
///overridable ID string to link control units to this specific transport_controller datum. created by placing a transport id landmark object
///somewhere on the tram, if its anywhere on the tram we'll find it in init and set this to whatever it specifies
var/specific_transport_id
///bitfield of various transport states
var/controller_status = NONE
/// probability of being thrown hard during an emergency stop
var/throw_chance = 17.5
/datum/transport_controller/linear/New(obj/structure/transport/linear/transport_module)
transport_id = transport_module.transport_id
create_modular_set = transport_module.create_modular_set
link_transport_modules(transport_module)
ignored_smashthroughs = typecacheof(ignored_smashthroughs)
LAZYADDASSOCLIST(SStransport.transports_by_type, transport_id, src)
for(var/obj/structure/transport/linear/lift as anything in transport_modules)
lift.add_initial_contents()
/datum/transport_controller/linear/Destroy()
for(var/obj/structure/transport/linear/transport_module as anything in transport_modules)
transport_module.transport_controller_datum = null
transport_modules = null
LAZYREMOVEASSOC(SStransport.transports_by_type, transport_id, src)
if(isnull(SStransport.transports_by_type))
SStransport.transports_by_type = list()
return ..()
/datum/transport_controller/linear/proc/add_transport_modules(obj/structure/transport/linear/new_transport_module)
if(new_transport_module in transport_modules)
return
for(var/obj/structure/transport/linear/other_module in new_transport_module.loc)
if(other_module != new_transport_module)
stack_trace("there is more than one transport module on a tile when a controller adds it. this causes problems")
qdel(other_module)
new_transport_module.transport_controller_datum = src
LAZYADD(transport_modules, new_transport_module)
RegisterSignal(new_transport_module, COMSIG_QDELETING, PROC_REF(remove_transport_modules))
check_for_landmarks(new_transport_module)
if(z_sorted)//make sure we dont lose z ordering if we get additional platforms after init
order_platforms_by_z_level()
/datum/transport_controller/linear/proc/remove_transport_modules(obj/structure/transport/linear/old_transport_module)
SIGNAL_HANDLER
if(!(old_transport_module in transport_modules))
return
old_transport_module.transport_controller_datum = null
LAZYREMOVE(transport_modules, old_transport_module)
UnregisterSignal(old_transport_module, COMSIG_QDELETING)
if(!length(transport_modules))
qdel(src)
///Collect all bordered platforms via a simple floodfill algorithm. allows multiz trams because its funny
/datum/transport_controller/linear/proc/link_transport_modules(obj/structure/transport/linear/base_transport_module)
add_transport_modules(base_transport_module)
var/list/possible_expansions = list(base_transport_module)
while(possible_expansions.len)
for(var/obj/structure/transport/linear/borderline as anything in possible_expansions)
var/list/result = borderline.module_adjacency(src)
if(length(result))
for(var/obj/structure/transport/linear/transport_module as anything in result)
if(transport_modules.Find(transport_module))
continue
add_transport_modules(transport_module)
possible_expansions |= transport_module
possible_expansions -= borderline
///check for any landmarks placed inside the locs of the given transport_module
/datum/transport_controller/linear/proc/check_for_landmarks(obj/structure/transport/linear/new_transport_module)
SHOULD_CALL_PARENT(TRUE)
for(var/turf/platform_loc as anything in new_transport_module.locs)
var/obj/effect/landmark/transport/transport_id/id_giver = locate() in platform_loc
if(id_giver)
set_info_from_id_landmark(id_giver)
///set vars and such given an overriding transport_id landmark
/datum/transport_controller/linear/proc/set_info_from_id_landmark(obj/effect/landmark/transport/transport_id/landmark)
SHOULD_CALL_PARENT(TRUE)
if(!istype(landmark, /obj/effect/landmark/transport/transport_id))//transport_controller subtypes can want differnet id's than the base type wants
return
if(landmark.specific_transport_id)
specific_transport_id = landmark.specific_transport_id
qdel(landmark)
///orders the lift platforms in order of lowest z level to highest z level.
/datum/transport_controller/linear/proc/order_platforms_by_z_level()
//contains nested lists for every z level in the world. why? because its really easy to sort
var/list/platforms_by_z = list()
platforms_by_z.len = world.maxz
for(var/z in 1 to world.maxz)
platforms_by_z[z] = list()
for(var/obj/structure/transport/linear/transport_module as anything in transport_modules)
if(QDELETED(transport_module) || !transport_module.z)
transport_modules -= transport_module
continue
platforms_by_z[transport_module.z] += transport_module
if(create_modular_set)
for(var/list/z_list as anything in platforms_by_z)
if(!length(z_list))
continue
create_modular_set_for_z_level(z_list)//this will subtract all but one platform from the list
var/list/output = list()
for(var/list/z_list as anything in platforms_by_z)
output += z_list
transport_modules = output
z_sorted = TRUE
///goes through all platforms in the given list and finds the one in the lower left corner
/datum/transport_controller/linear/proc/create_modular_set_for_z_level(list/obj/structure/transport/linear/platforms_in_z)
var/min_x = INFINITY
var/max_x = 0
var/min_y = INFINITY
var/max_y = 0
var/z = 0
for(var/obj/structure/transport/linear/module_to_sort as anything in platforms_in_z)
if(!z)
if(!module_to_sort.z)
stack_trace("create_modular_set_for_z_level() was given a platform in nullspace or not on a turf!")
platforms_in_z -= module_to_sort
continue
z = module_to_sort.z
if(z != module_to_sort.z)
stack_trace("create_modular_set_for_z_level() was given lifts on different z levels!")
platforms_in_z -= module_to_sort
continue
min_x = min(min_x, module_to_sort.x)
max_x = max(max_x, module_to_sort.x)
min_y = min(min_y, module_to_sort.y)
max_y = max(max_y, module_to_sort.y)
var/turf/lower_left_corner_loc = locate(min_x, min_y, z)
if(!lower_left_corner_loc)
CRASH("was unable to find a turf at the lower left corner of this z")
var/obj/structure/transport/linear/lower_left_corner_transport = locate() in lower_left_corner_loc
if(!lower_left_corner_transport)
CRASH("there was no transport in the lower left corner of the given transport")
platforms_in_z.Cut()
platforms_in_z += lower_left_corner_transport//we want to change the list given to us not create a new one. so we do this
lower_left_corner_transport.create_modular_set(min_x, min_y, max_x, max_y, z)
///returns the closest transport to the specified atom, prioritizing transports on the same z level. used for comparing distance
/datum/transport_controller/linear/proc/return_closest_platform_to(atom/comparison, allow_multiple_answers = FALSE)
if(!istype(comparison) || !comparison.z)
return FALSE
var/list/obj/structure/transport/linear/candidate_platforms = list()
for(var/obj/structure/transport/linear/platform as anything in transport_modules)
if(platform.z == comparison.z)
candidate_platforms += platform
var/obj/structure/transport/linear/winner = candidate_platforms[1]
var/winner_distance = get_dist(comparison, winner)
var/list/tied_winners = list(winner)
for(var/obj/structure/transport/linear/platform_to_sort as anything in candidate_platforms)
var/platform_distance = get_dist(comparison, platform_to_sort)
if(platform_distance < winner_distance)
winner = platform_to_sort
winner_distance = platform_distance
if(allow_multiple_answers)
tied_winners = list(winner)
else if(platform_distance == winner_distance && allow_multiple_answers)
tied_winners += platform_to_sort
if(allow_multiple_answers)
return tied_winners
return winner
/// Returns a platform on the z-level which is vertically closest to the passed target_z
/datum/transport_controller/linear/proc/return_closest_platform_to_z(target_z)
var/obj/structure/transport/linear/found_platform
for(var/obj/structure/transport/linear/lift as anything in transport_modules)
// Already at the same Z-level, we can stop
if(lift.z == target_z)
found_platform = lift
break
// Set up an initial lift to compare to
if(!found_platform)
found_platform = lift
continue
// Same level, we can go with the one we currently have
if(lift.z == found_platform.z)
continue
// If the difference between the current found platform and the target
// if less than the distance between the next lift and the target,
// our current platform is closer to the target than the next one, so we can skip it
if(abs(found_platform.z - target_z) < abs(lift.z - target_z))
continue
// The difference is smaller for this lift, so it's closer
found_platform = lift
return found_platform
/// Returns a list of all the z-levels our transport is currently on.
/datum/transport_controller/linear/proc/get_zs_we_are_on()
var/list/zs_we_are_present_on = list()
for(var/obj/structure/transport/linear/lift as anything in transport_modules)
zs_we_are_present_on |= lift.z
return zs_we_are_present_on
///returns all transport modules associated with this transport on the given z level or given atoms z level
/datum/transport_controller/linear/proc/get_platforms_on_level(atom/atom_reference_OR_z_level_number)
var/z = atom_reference_OR_z_level_number
if(isatom(atom_reference_OR_z_level_number))
z = atom_reference_OR_z_level_number.z
if(!isnum(z) || z < 0 || z > world.maxz)
return null
var/list/platforms_in_z = list()
for(var/obj/structure/transport/linear/lift_to_check as anything in transport_modules)
if(lift_to_check.z)
platforms_in_z += lift_to_check
return platforms_in_z
/**
* Moves the platform UP or DOWN, this is what users invoke with their hand.
* This is a SAFE proc, ensuring every part of it moves SANELY.
*
* Arguments:
* going - UP or DOWN directions, where the platform should go. Keep in mind by this point checks of whether it should go up or down have already been done.
* user - Whomever made the movement.
*/
/datum/transport_controller/linear/proc/move_lift_vertically(going, mob/user)
//transport_modules are sorted in order of lowest z to highest z, so going upwards we need to move them in reverse order to not collide
if(going == UP)
var/obj/structure/transport/linear/platform_to_move
var/current_index = length(transport_modules)
while(current_index > 0)
platform_to_move = transport_modules[current_index]
current_index--
platform_to_move.travel(going)
else if(going == DOWN)
for(var/obj/structure/transport/linear/transport_module as anything in transport_modules)
transport_module.travel(going)
/**
* Moves the platform after a passed delay.
*
* This is a more "user friendly" or "realistic" move.
* It includes things like:
* - Allowing platform "travel time"
* - Shutting elevator safety doors
* - Sound effects while moving
* - Safety warnings for anyone below the platform (while it's moving downwards)
*
* Arguments:
* duration - required, how long do we wait to move the platform?
* door_duration - optional, how long should we wait to open the doors after arriving? If null, we won't open or close doors
* direction - which direction are we moving the lift?
* user - optional, who is moving the lift?
*/
/datum/transport_controller/linear/proc/move_after_delay(lift_move_duration, door_duration, direction, mob/user)
if(!isnum(lift_move_duration))
CRASH("[type] move_after_delay called with invalid duration ([lift_move_duration]).")
if(lift_move_duration <= 0 SECONDS)
move_lift_vertically(direction, user)
return
// Get the lowest or highest platform according to which direction we're moving
var/obj/structure/transport/linear/prime_lift = return_closest_platform_to_z(direction == UP ? world.maxz : 0)
// ...because we use the duration of the sound effect to make it last for roughly the duration of the lift travel
playsound(prime_lift, 'sound/vehicles/mecha/hydraulic.ogg', 25, vary = TRUE, frequency = clamp(HYDRAULIC_SFX_DURATION / lift_move_duration, 0.33, 3))
// Move the platform after a timer
addtimer(CALLBACK(src, PROC_REF(move_lift_vertically), direction, user), lift_move_duration, TIMER_UNIQUE)
// Open doors after the set duration if supplied
if(isnum(door_duration))
addtimer(CALLBACK(src, PROC_REF(open_lift_doors_callback)), door_duration, TIMER_UNIQUE)
// Here on we only care about platforms going DOWN
if(direction != DOWN)
return
// Okay we're going down, let's try to display some warnings to people below
var/list/turf/lift_locs = list()
for(var/obj/structure/transport/linear/going_to_move as anything in transport_modules)
// This platform has no warnings so we don't even need to worry about it
if(!going_to_move.warns_on_down_movement)
continue
// Collect all the turfs our platform is found at
lift_locs |= going_to_move.locs
for(var/turf/moving in lift_locs)
// Find what's below the turf that's moving
var/turf/below_us = get_step_multiz(moving, DOWN)
// Hold up the turf below us is also in our locs list. Multi-z? Don't show a warning
if(below_us in lift_locs)
continue
// Display the warning for until we land
new /obj/effect/temp_visual/telegraphing/lift_travel(below_us, lift_move_duration)
/**
* Simple wrapper for checking if we can move 1 zlevel, and if we can, do said move.
* Locks controls, closes all doors, then moves the platform and re-opens the doors afterwards.
*
* Arguments:
* direction - which direction are we moving?
* lift_move_duration - how long does the move take? can be 0 or null for instant move.
* door_duration - how long does it take for the doors to open after a move?
* user - optional, who moved it?
*/
/datum/transport_controller/linear/proc/simple_move_wrapper(direction, lift_move_duration, mob/user)
if(!Check_lift_move(direction))
return FALSE
// Lock controls, to prevent moving-while-moving memes
controls_lock(TRUE)
// Send out a signal that we're going
SEND_SIGNAL(src, COMSIG_LIFT_SET_DIRECTION, direction)
// Close all lift doors
update_lift_doors(action = CYCLE_CLOSED)
if(isnull(lift_move_duration) || lift_move_duration <= 0 SECONDS)
// Do an instant move
move_lift_vertically(direction, user)
// Open doors on the zs we arrive at
update_lift_doors(get_zs_we_are_on(), action = CYCLE_OPEN)
// And unlock the controls after
controls_lock(FALSE)
return TRUE
// Do a delayed move
move_after_delay(
lift_move_duration = lift_move_duration,
door_duration = lift_move_duration * 1.5,
direction = direction,
user = user,
)
addtimer(CALLBACK(src, PROC_REF(finish_simple_move_wrapper)), lift_move_duration * 1.5)
return TRUE
/**
* Wrap everything up from simple_move_wrapper finishing its movement
*/
/datum/transport_controller/linear/proc/finish_simple_move_wrapper()
SEND_SIGNAL(src, COMSIG_LIFT_SET_DIRECTION, 0)
controls_lock(FALSE)
/**
* Moves the platform to the passed z-level.
*
* Checks for validity of the move: Are we moving to the same z-level, can we actually move to that z-level?
* Does NOT check if the controls are currently locked.
*
* Moves to the passed z-level by calling move_after_delay repeatedly until the passed z-level is reached.
* This proc sleeps as it moves.
*
* Arguments:
* target_z - required, the Z we want to move to
* loop_callback - optional, an additional callback invoked during the loop that allows the move to cancel.
* user - optional, who started the move
*/
/datum/transport_controller/linear/proc/move_to_zlevel(target_z, datum/callback/loop_callback, mob/user)
if(!isnum(target_z) || target_z <= 0)
CRASH("[type] move_to_zlevel was passed an invalid target_z ([target_z]).")
var/obj/structure/transport/linear/prime_lift = return_closest_platform_to_z(target_z)
var/lift_z = prime_lift.z
// We're already at the desired z-level!
if(target_z == lift_z)
return FALSE
// The amount of z levels between the our and target_z
var/z_difference = abs(target_z - lift_z)
// Direction (up/down) needed to go to reach target_z
var/direction = lift_z < target_z ? UP : DOWN
// We can't go that way anymore, or possibly ever
if(!Check_lift_move(direction))
return FALSE
// Okay we're ready to start moving now.
controls_lock(TRUE)
// Send out a signal that we're going
SEND_SIGNAL(src, COMSIG_LIFT_SET_DIRECTION, direction)
var/travel_speed = prime_lift.elevator_vertical_speed
// Close all lift doors
update_lift_doors(action = CYCLE_CLOSED)
sleep(1.1 SECONDS)
// Approach the desired z-level one step at a time
for(var/i in 1 to z_difference)
if(!Check_lift_move(direction))
break
if(loop_callback && !loop_callback.Invoke())
break
// move_after_delay will set up a timer and cause us to move after a time
move_after_delay(
lift_move_duration = travel_speed,
direction = direction,
user = user,
)
// and we don't want to send another request until the timer's done
stoplag(travel_speed + 0.1 SECONDS)
if(QDELETED(src) || QDELETED(prime_lift))
return
update_lift_doors(get_zs_we_are_on(), action = CYCLE_OPEN)
SEND_SIGNAL(src, COMSIG_LIFT_SET_DIRECTION, 0)
controls_lock(FALSE)
return TRUE
/**
* Updates all blast doors and shutters that share an ID with our lift.
*
* Arguments:
* on_z_level - optional, only open doors on this z-level or list of z-levels
* action - how do we update the doors? CYCLE_OPEN to make them open, CYCLE_CLOSED to make them shut
*/
/datum/transport_controller/linear/proc/update_lift_doors(on_z_level, action)
if(!isnull(on_z_level) && !islist(on_z_level))
on_z_level = list(on_z_level)
var/played_ding = FALSE
for(var/obj/machinery/door/elevator_door as anything in GLOB.elevator_doors)
if(elevator_door.transport_linked_id != specific_transport_id)
continue
if(on_z_level && !(elevator_door.z in on_z_level))
continue
switch(action)
if(CYCLE_OPEN)
elevator_door.elevator_status = LIFT_PLATFORM_UNLOCKED
if(!played_ding)
playsound(elevator_door, 'sound/machines/ping.ogg', 50, TRUE)
played_ding = TRUE
addtimer(CALLBACK(elevator_door, TYPE_PROC_REF(/obj/machinery/door, open)), 0.7 SECONDS)
if(CYCLE_CLOSED)
elevator_door.elevator_status = LIFT_PLATFORM_LOCKED
INVOKE_ASYNC(elevator_door, TYPE_PROC_REF(/obj/machinery/door, close))
else
stack_trace("Elevator lift update_lift_doors called with an improper action ([action]).")
/// Helper used in callbacks to open all the doors our platform is on
/datum/transport_controller/linear/proc/open_lift_doors_callback()
update_lift_doors(get_zs_we_are_on(), action = CYCLE_OPEN)
/**
* Moves the platform, this is what users invoke with their hand.
* This is a SAFE proc, ensuring every part of the lift moves SANELY.
* It also locks controls for the (miniscule) duration of the movement, so the elevator cannot be broken by spamming.
*/
/datum/transport_controller/linear/proc/move_transport_horizontally(going)
if(modular_set)
controls_lock(TRUE)
for(var/obj/structure/transport/linear/module_to_move as anything in transport_modules)
module_to_move.travel(going)
controls_lock(FALSE)
return
var/max_x = 0
var/max_y = 0
var/max_z = 0
var/min_x = world.maxx
var/min_y = world.maxy
var/min_z = world.maxz
for(var/obj/structure/transport/linear/transport_module as anything in transport_modules)
max_z = max(max_z, transport_module.z)
min_z = min(min_z, transport_module.z)
min_x = min(min_x, transport_module.x)
max_x = max(max_x, transport_module.x)
//this assumes that all z levels have identical horizontal bounding boxes
//but if youre still using a non multitile platform at this point
//then its your own problem. it wont runtime it will just be slower than it needs to be if this assumption isnt
//the case
min_y = min(min_y, transport_module.y)
max_y = max(max_y, transport_module.y)
for(var/z in min_z to max_z)
//This must be safe way to border tile to tile move of bordered platforms, that excludes platform overlapping.
if(going & WEST)
//Go along the X axis from min to max, from left to right
for(var/x in min_x to max_x)
if(going & NORTH)
//Go along the Y axis from max to min, from up to down
for(var/y in max_y to min_y step -1)
var/obj/structure/transport/linear/transport_module = locate(/obj/structure/transport/linear, locate(x, y, z))
transport_module?.travel(going)
else if(going & SOUTH)
//Go along the Y axis from min to max, from down to up
for(var/y in min_y to max_y)
var/obj/structure/transport/linear/transport_module = locate(/obj/structure/transport/linear, locate(x, y, z))
transport_module?.travel(going)
else
for(var/y in min_y to max_y)
var/obj/structure/transport/linear/transport_module = locate(/obj/structure/transport/linear, locate(x, y, z))
transport_module?.travel(going)
else
//Go along the X axis from max to min, from right to left
for(var/x in max_x to min_x step -1)
if(going & NORTH)
//Go along the Y axis from max to min, from up to down
for(var/y in max_y to min_y step -1)
var/obj/structure/transport/linear/transport_module = locate(/obj/structure/transport/linear, locate(x, y, z))
transport_module?.travel(going)
else if (going & SOUTH)
for(var/y in min_y to max_y)
var/obj/structure/transport/linear/transport_module = locate(/obj/structure/transport/linear, locate(x, y, z))
transport_module?.travel(going)
else
//Go along the Y axis from min to max, from down to up
for(var/y in min_y to max_y)
var/obj/structure/transport/linear/transport_module = locate(/obj/structure/transport/linear, locate(x, y, z))
transport_module?.travel(going)
///Check destination turfs
/datum/transport_controller/linear/proc/Check_lift_move(check_dir)
for(var/obj/structure/transport/linear/transport_module as anything in transport_modules)
for(var/turf/bound_turf in transport_module.locs)
var/turf/T = get_step_multiz(transport_module, check_dir)
if(!T)//the edges of multi-z maps
return FALSE
if(check_dir == UP && !istype(T, /turf/open/openspace)) // We don't want to go through the ceiling!
return FALSE
if(check_dir == DOWN && !istype(get_turf(transport_module), /turf/open/openspace)) // No going through the floor!
return FALSE
return TRUE
/**
* Sets transport controls_locked state. Used to prevent moving mid movement, or cooldowns.
*/
/datum/transport_controller/linear/proc/controls_lock(state)
switch(state)
if(FALSE)
controller_status &= ~CONTROLS_LOCKED
else
controller_status |= CONTROLS_LOCKED
/**
* resets the contents of all platforms to their original state in case someone put a bunch of shit onto the platform.
* intended to be called by admins. passes all arguments to reset_contents() for each of our platforms.
*
* Arguments:
* * consider_anything_past - number. if > 0 our platforms will only handle foreign contents that exceed this number in each of their locs
* * foreign_objects - bool. if true our platforms will consider /atom/movable's that arent mobs as part of foreign contents
* * foreign_non_player_mobs - bool. if true our platforms consider mobs that dont have a mind to be foreign
* * consider_player_mobs - bool. if true our platforms consider player mobs to be foreign. only works if foreign_non_player_mobs is true as well
*/
/datum/transport_controller/linear/proc/reset_lift_contents(consider_anything_past = 0, foreign_objects = TRUE, foreign_non_player_mobs = TRUE, consider_player_mobs = FALSE)
for(var/obj/structure/transport/linear/lift_to_reset in transport_modules)
lift_to_reset.reset_contents(consider_anything_past, foreign_objects, foreign_non_player_mobs, consider_player_mobs)
return TRUE
#undef HYDRAULIC_SFX_DURATION