Files
Aurora.3/code/_helpers/area_movement.dm
Lohikar 52a4f3a4e3 Shuttle refactor (#2171)
Rewrites the area movement code used by shuttles & elevators in an effort to make it faster, more extensible, and generally easier to read. Also fixes some bugs relating to lighting & moving areas, such as lighting overlays suddenly being teleported into space for absolutely no reason.

Fixes #2161.
Fixes #2166.
2017-05-05 10:16:53 +03:00

126 lines
3.5 KiB
Plaintext

// Builds a list of turfs belonging to an area in a predictable order.
// Two areas of the same size should have directly comparable ordered turf lists.
// If ignore_type has a value, that turf will be excluded from the list.
// Excluded turfs are represented by null values in the list to maintain order.
/area/proc/build_ordered_turf_list(ignore_type)
. = list()
// Find the maximums and minimums of the area.
var/xmax = -1
var/ymax = -1
var/xmin = INFINITY
var/ymin = INFINITY
var/z = -1
for (var/turf/T in src)
if (z == -1)
z = T.z
if (T.x > xmax)
xmax = T.x
if (T.x < xmin)
xmin = T.x
if (T.y > ymax)
ymax = T.y
if (T.y < ymin)
ymin = T.y
//log_debug("build_ordered_turf_list([DEBUG_REF(src)]): xmax=[xmax],xmin=[xmin],ymax=[ymax],ymin=[ymin],z=[z]")
ASSERT(xmax > xmin)
ASSERT(ymax > ymin)
ASSERT(z != -1)
// Now use our information to build an *ordered* list of turfs.
for (var/x = xmin; x <= xmax; x++)
for (var/y = ymin; y <= ymax; y++)
var/turf/T = locate(x, y, z)
if (T.loc != src || T.type == ignore_type)
// Not ours or ignored type, we don't give a crap.
// Add a null to keep the list a predictable size.
. += null
else
// Turf matches, add it.
. += T
// Moves the contents of this area to A. If turf_to_leave is defined, that type will be excluded from the area.
/area/proc/move_contents_to(area/A, turf_to_leave = null)
var/list/source_turfs = src.build_ordered_turf_list(turf_to_leave)
var/list/target_turfs = A.build_ordered_turf_list()
//log_debug("move_contents_to: source_turfs.len=[source_turfs.len],target_turfs.len=[target_turfs.len]")
ASSERT(source_turfs.len == target_turfs.len)
var/list/simulated_turfs = list()
for (var/i = 1; i <= source_turfs.len; i++)
var/turf/ST = source_turfs[i]
if (!ST) // Excluded turfs are null to keep the list ordered.
continue
var/turf/TT = ST.copy_turf(target_turfs[i])
for (var/thing in ST)
var/atom/movable/AM = thing
AM.shuttle_move(TT)
ST.ChangeTurf(get_base_turf_by_area(ST))
if (istype(TT, /turf/simulated))
simulated_turfs += TT
for (var/thing in simulated_turfs)
var/turf/simulated/T = thing
T.update_icon()
if (istype(T.above))
T.above.queue_icon_update()
// Called when a movable area wants to move this object.
/atom/movable/proc/shuttle_move(turf/loc)
forceMove(loc)
// In theory, this copies the contents of the area to another, and returns a list containing every new object it created.
// It's not tested because the holodeck doesn't work yet.
/area/proc/copy_contents_to(area/A, plating_required = FALSE)
var/list/source_turfs = src.build_ordered_turf_list()
var/list/target_turfs = A.build_ordered_turf_list()
. = list()
log_debug("copy_contents_to: source_turfs.len=[source_turfs.len],target_turfs.len=[target_turfs.len]")
ASSERT(source_turfs.len == target_turfs.len)
var/baseturf
if (plating_required)
baseturf = A.base_turf
if (!baseturf)
var/turf/T
for (var/idex = 1; T == null; idex++)
if (idex > target_turfs.len)
CRASH("Empty target_turfs list!")
T = target_turfs[idex]
baseturf = get_base_turf(T.z)
for (var/i = 1; i <= source_turfs.len; i++)
var/turf/ST = source_turfs[i]
var/turf/TTi = target_turfs[i]
if (!ST || (plating_required && TTi.type != baseturf)) // Excluded turfs are null to keep the list ordered.
continue
var/turf/TT = ST.copy_turf(TTi, ignore_air = TRUE)
for (var/thing in ST)
var/atom/movable/AM = thing
var/atom/movable/copy = DuplicateObject(AM, 1)
copy.forceMove(TT)
. += copy
SSair.mark_for_update(TT)