mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-29 02:51:41 +00:00
* Fix disky teleporting itself off the emergency shuttle on transit. (#61786) Fixes #61782 Did a minor cleanup in the stationloving component to better represent what the proc the destination_in_bounds proc actually did. It is now atom_in_bounds since it's called after the atom has moved and works on the atom's turf. This doesn't fix the problem, but it obfuscated things a bit since it was deceptively named. The issue is that when the e-shuttle leaves the station, for every turf on the shuttle it first moves the turf's contents to hyperspace, then moves the turf to hyperspace, then changes the area. Since the player holding disky enters Hyperspace first then has the shuttle turf constructed around them, disky teleports back to the station because it enters a non-whitelisted location. Instead of whitelisting Hyperspace, I changed the order of operations to turf transfer, area transfer and finally atom transfer. This fixes the issue (as now disky moves from z=2 to z=12 /area/shuttle/escape, where escape shuttle is whitelisted instead of z=12 /area/transit, where /area/transit is not whitelisted). * Fix disky teleporting itself off the emergency shuttle on transit. Co-authored-by: Timberpoes <silent_insomnia_pp@hotmail.co.uk>
213 lines
7.5 KiB
Plaintext
213 lines
7.5 KiB
Plaintext
/// This is the main proc. It instantly moves our mobile port to stationary port `new_dock`.
|
|
/obj/docking_port/mobile/proc/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
|
|
// Crashing this ship with NO SURVIVORS
|
|
|
|
if(admin_forced)
|
|
force = admin_forced
|
|
|
|
if(new_dock.get_docked() == src)
|
|
remove_ripples()
|
|
return DOCKING_SUCCESS
|
|
|
|
if(!force)
|
|
if(!check_dock(new_dock))
|
|
remove_ripples()
|
|
return DOCKING_BLOCKED
|
|
if(!canMove())
|
|
remove_ripples()
|
|
return DOCKING_IMMOBILIZED
|
|
|
|
var/obj/docking_port/stationary/old_dock = get_docked()
|
|
|
|
// The area that gets placed under where the shuttle moved from
|
|
var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
|
|
|
|
if(old_dock) //Dock overwrites
|
|
underlying_area_type = old_dock.area_type
|
|
|
|
/**************************************************************************************************************
|
|
Both lists are associative with a turf:bitflag structure. (new_turfs bitflag space unused currently)
|
|
The bitflag contains the data for what inhabitants of that coordinate should be moved to the new location
|
|
The bitflags can be found in __DEFINES/shuttles.dm
|
|
*/
|
|
var/list/old_turfs = return_ordered_turfs(x, y, z, dir)
|
|
var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir)
|
|
CHECK_TICK
|
|
/**************************************************************************************************************/
|
|
|
|
// The underlying old area is the area assumed to be under the shuttle's starting location
|
|
// If it no longer/has never existed it will be created
|
|
var/area/underlying_old_area = GLOB.areas_by_type[underlying_area_type]
|
|
if(!underlying_old_area)
|
|
underlying_old_area = new underlying_area_type(null)
|
|
|
|
var/rotation = 0
|
|
if(new_dock.dir != dir) //Even when the dirs are the same rotation is coming out as not 0 for some reason
|
|
rotation = dir2angle(new_dock.dir)-dir2angle(dir)
|
|
if ((rotation % 90) != 0)
|
|
rotation += (rotation % 90) //diagonal rotations not allowed, round up
|
|
rotation = SIMPLIFY_DEGREES(rotation)
|
|
|
|
if(!movement_direction)
|
|
movement_direction = turn(preferred_direction, 180)
|
|
|
|
var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle
|
|
var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved
|
|
|
|
. = preflight_check(old_turfs, new_turfs, areas_to_move, rotation)
|
|
if(.)
|
|
remove_ripples()
|
|
return
|
|
|
|
/*******************************************Hiding turfs if necessary*******************************************/
|
|
// TODO: Move this somewhere sane
|
|
var/list/new_hidden_turfs
|
|
if(hidden)
|
|
new_hidden_turfs = list()
|
|
for(var/i in 1 to old_turfs.len)
|
|
CHECK_TICK
|
|
var/turf/oldT = old_turfs[i]
|
|
if(old_turfs[oldT] & MOVE_TURF)
|
|
new_hidden_turfs += new_turfs[i]
|
|
SSshuttle.update_hidden_docking_ports(null, new_hidden_turfs)
|
|
/***************************************************************************************************************/
|
|
|
|
if(!force)
|
|
if(!check_dock(new_dock))
|
|
remove_ripples()
|
|
return DOCKING_BLOCKED
|
|
if(!canMove())
|
|
remove_ripples()
|
|
return DOCKING_IMMOBILIZED
|
|
|
|
// Moving to the new location will trample the ripples there at the exact
|
|
// same time any mobs there are trampled, to avoid any discrepancy where
|
|
// the ripples go away before it is safe.
|
|
takeoff(old_turfs, new_turfs, moved_atoms, rotation, movement_direction, old_dock, underlying_old_area)
|
|
|
|
CHECK_TICK
|
|
|
|
cleanup_runway(new_dock, old_turfs, new_turfs, areas_to_move, moved_atoms, rotation, movement_direction, underlying_old_area)
|
|
|
|
CHECK_TICK
|
|
|
|
/*******************************************Unhiding turfs if necessary******************************************/
|
|
if(new_hidden_turfs)
|
|
SSshuttle.update_hidden_docking_ports(hidden_turfs, null)
|
|
hidden_turfs = new_hidden_turfs
|
|
/****************************************************************************************************************/
|
|
|
|
check_poddoors()
|
|
new_dock.last_dock_time = world.time
|
|
setDir(new_dock.dir)
|
|
|
|
// remove any stragglers just in case, and clear the list
|
|
remove_ripples()
|
|
return DOCKING_SUCCESS
|
|
|
|
/obj/docking_port/mobile/proc/preflight_check(list/old_turfs, list/new_turfs, list/areas_to_move, rotation)
|
|
for(var/i in 1 to old_turfs.len)
|
|
CHECK_TICK
|
|
var/turf/oldT = old_turfs[i]
|
|
var/turf/newT = new_turfs[i]
|
|
if(!newT)
|
|
return DOCKING_NULL_DESTINATION
|
|
if(!oldT)
|
|
return DOCKING_NULL_SOURCE
|
|
|
|
var/area/old_area = oldT.loc
|
|
var/move_mode = old_area.beforeShuttleMove(shuttle_areas) //areas
|
|
|
|
var/list/old_contents = oldT.contents
|
|
for(var/k in 1 to old_contents.len)
|
|
CHECK_TICK
|
|
var/atom/movable/moving_atom = old_contents[k]
|
|
if(moving_atom.loc != oldT) //fix for multi-tile objects
|
|
continue
|
|
move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode, src) //atoms
|
|
|
|
move_mode = oldT.fromShuttleMove(newT, move_mode) //turfs
|
|
move_mode = newT.toShuttleMove(oldT, move_mode, src) //turfs
|
|
|
|
if(move_mode & MOVE_AREA)
|
|
areas_to_move[old_area] = TRUE
|
|
|
|
old_turfs[oldT] = move_mode
|
|
|
|
/obj/docking_port/mobile/proc/takeoff(list/old_turfs, list/new_turfs, list/moved_atoms, rotation, movement_direction, old_dock, area/underlying_old_area)
|
|
for(var/i in 1 to old_turfs.len)
|
|
var/turf/oldT = old_turfs[i]
|
|
var/turf/newT = new_turfs[i]
|
|
var/move_mode = old_turfs[oldT]
|
|
|
|
if(move_mode & MOVE_TURF)
|
|
oldT.onShuttleMove(newT, movement_force, movement_direction) //turfs
|
|
|
|
if(move_mode & MOVE_AREA)
|
|
var/area/shuttle_area = oldT.loc
|
|
shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas
|
|
|
|
if(move_mode & MOVE_CONTENTS)
|
|
for(var/k in oldT)
|
|
var/atom/movable/moving_atom = k
|
|
if(moving_atom.loc != oldT) //fix for multi-tile objects
|
|
continue
|
|
moving_atom.onShuttleMove(newT, oldT, movement_force, movement_direction, old_dock, src) //atoms
|
|
moved_atoms[moving_atom] = oldT
|
|
|
|
|
|
/obj/docking_port/mobile/proc/cleanup_runway(obj/docking_port/stationary/new_dock, list/old_turfs, list/new_turfs, list/areas_to_move, list/moved_atoms, rotation, movement_direction, area/underlying_old_area)
|
|
underlying_old_area.afterShuttleMove()
|
|
|
|
// Parallax handling
|
|
// This needs to be done before the atom after move
|
|
var/new_parallax_dir = FALSE
|
|
if(istype(new_dock, /obj/docking_port/stationary/transit))
|
|
new_parallax_dir = preferred_direction
|
|
for(var/i in 1 to areas_to_move.len)
|
|
CHECK_TICK
|
|
var/area/internal_area = areas_to_move[i]
|
|
internal_area.afterShuttleMove(new_parallax_dir) //areas
|
|
|
|
for(var/i in 1 to old_turfs.len)
|
|
CHECK_TICK
|
|
if(!(old_turfs[old_turfs[i]] & MOVE_TURF))
|
|
continue
|
|
var/turf/oldT = old_turfs[i]
|
|
var/turf/newT = new_turfs[i]
|
|
newT.afterShuttleMove(oldT, rotation) //turfs
|
|
|
|
for(var/i in 1 to moved_atoms.len)
|
|
CHECK_TICK
|
|
var/atom/movable/moved_object = moved_atoms[i]
|
|
if(QDELETED(moved_object))
|
|
continue
|
|
var/turf/oldT = moved_atoms[moved_object]
|
|
moved_object.afterShuttleMove(oldT, movement_force, dir, preferred_direction, movement_direction, rotation)//atoms
|
|
|
|
// lateShuttleMove (There had better be a really good reason for additional stages beyond this)
|
|
|
|
underlying_old_area.lateShuttleMove()
|
|
|
|
for(var/i in 1 to areas_to_move.len)
|
|
CHECK_TICK
|
|
var/area/internal_area = areas_to_move[i]
|
|
internal_area.lateShuttleMove()
|
|
|
|
for(var/i in 1 to old_turfs.len)
|
|
CHECK_TICK
|
|
if(!(old_turfs[old_turfs[i]] & MOVE_CONTENTS | MOVE_TURF))
|
|
continue
|
|
var/turf/oldT = old_turfs[i]
|
|
var/turf/newT = new_turfs[i]
|
|
newT.lateShuttleMove(oldT)
|
|
|
|
for(var/i in 1 to moved_atoms.len)
|
|
CHECK_TICK
|
|
var/atom/movable/moved_object = moved_atoms[i]
|
|
if(QDELETED(moved_object))
|
|
continue
|
|
var/turf/oldT = moved_atoms[moved_object]
|
|
moved_object.lateShuttleMove(oldT, movement_force, movement_direction)
|
|
|