Files

71 lines
2.2 KiB
Plaintext

//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 Citadel Station Developers *//
/**
* registers a /movable in a spatial grid
*/
/datum/component/spatial_grid
dupe_mode = COMPONENT_DUPE_SELECTIVE
registered_type = /datum/component/spatial_grid
/// target spatial grid
var/datum/spatial_grid/grid
/// target grid width
var/grid_width
/// last grid index
var/current_index
/datum/component/spatial_grid/Initialize(datum/spatial_grid/grid)
. = ..()
if(. == COMPONENT_INCOMPATIBLE)
return
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE
if(!grid)
CRASH("attempted to make a spatial grid component without a grid ref")
src.grid = grid
src.grid_width = grid.width
/datum/component/spatial_grid/RegisterWithParent()
construct()
/datum/component/spatial_grid/UnregisterFromParent()
teardown()
/datum/component/spatial_grid/CheckDupeComponent(datum/component/C, datum/spatial_grid/grid)
return grid != src.grid
/datum/component/spatial_grid/proc/construct(atom/root = parent)
while(ismovable(root))
RegisterSignal(root, COMSIG_MOVABLE_MOVED, PROC_REF(update))
root = root.loc
if(isturf(root))
var/idx = ceil(root.x / TURF_CHUNK_RESOLUTION) + grid_width * (ceil(root.y / TURF_CHUNK_RESOLUTION) - 1)
grid.direct_insert(parent, root.z, idx)
current_index = idx
/datum/component/spatial_grid/proc/teardown(atom/root = parent)
while(ismovable(root))
UnregisterSignal(root, COMSIG_MOVABLE_MOVED)
root = root.loc
if(isturf(root))
grid.direct_remove(parent, root.z, current_index)
current_index = null
/datum/component/spatial_grid/proc/update(atom/movable/source, atom/oldloc)
var/atom/newloc = source.loc
if(newloc == oldloc)
return
// turf --> turf, try to do an optimized, lazy update
if(isturf(oldloc) && isturf(newloc) && (oldloc.z == newloc.z))
var/new_index = ceil(newloc.x / TURF_CHUNK_RESOLUTION) + grid_width * (ceil(newloc.y / TURF_CHUNK_RESOLUTION) - 1)
var/z = oldloc.z
if(new_index != current_index)
grid.direct_remove(parent, z, current_index)
grid.direct_insert(parent, z, new_index)
current_index = new_index
// turf --> somewhere else or somewhere else --> turf or somewhere else --> somewhere else, do full cycle
else
teardown(oldloc)
construct(newloc)