Files
Aurora.3/code/_helpers/area_movement.dm
LordFowl f604e14933 Refactors baseturf (#2778)
Modifies baseturf to be used instead of not used. Now all functions that used to call "get_base_turf_by_area(T)" will now call "T.baseturf". Turfs that do not have a baseturf defined will set their baseturf to be the result of "get_base_turf_by_area()", which will descend into "get_base_turf_by_z" and ultimately into "turf/space", if none of the previous stages catch.

ChangeTurf will now only keep baseturf persistent from father to child if the child has no baseturf set by code.

This allows for special turfs, such as ceilings, to have their own base turf, such as open space, to be used instead of the area/z baseturf.

Fixes #2763
2017-06-22 13:16:06 +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(ST.baseturf)
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 = T.baseturf
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)