spatial_grid
Vars | |
dummy_list | empty spatial grid cell content lists are just a reference to this instead of a standalone list to save memory without needed to check if its null when iterating |
---|---|
grids_by_z_level | list of the spatial_grid_cell datums per z level, arranged in the order of y index then x index |
number_of_oranges_ears | how many pregenerated /mob/oranges_ear instances currently exist. this should hopefully never exceed its starting value |
pregenerated_oranges_ears | list of all of /mob/oranges_ear instances we have pregenerated for view() iteration speedup |
spatial_grid_categories | associative list of the form: movable.spatial_grid_key (string) -> inner list of spatial grid types for that key. inner lists contain contents channel types such as SPATIAL_GRID_CONTENTS_TYPE_HEARING etc. we use this to make adding to a cell static cost, and to save on memory |
waiting_to_add_by_type | everything that spawns before us is added to this list until we initialize |
Procs | |
add_grid_awareness | Adds grid awareness to the passed in atom, of the passed in type Basically, when this atom moves between grids, it wants to have enter/exit cell called on it |
add_grid_membership | Alerts the atom's current cell that it wishes to be treated as a member This functionally amounts to "hey, I was recently made aware by [add_grid_awareness], please insert me into my current cell" |
add_single_type | acts like enter_cell() but only adds the target to a specified type of grid cell contents list |
after_world_bounds_expanded | adds cells to the grid for every z level when world.maxx or world.maxy is expanded after this subsystem is initialized. hopefully this is never needed. because i never tested this. |
assign_oranges_ears | allocate one /mob/oranges_ear mob per turf containing atoms_that_need_ears and give them a reference to every listed atom in their turf. if an oranges_ear is allocated to a turf that already has an oranges_ear then the second one fails to allocate (and gives the existing one the atom it was assigned to) |
enter_cell | find the spatial map cell that target belongs to, then add the target to it, as its type prefers. make sure to provide the turf new_target is "in" |
enter_pre_init_queue | add a movable to the pre init queue for whichever type is specified so that when the subsystem initializes they get added to the grid |
exit_cell | find the spatial map cell that target used to belong to, then remove the target (and sometimes it's important_recusive_contents) from it. make sure to provide the turf old_target used to be "in" |
find_hanging_cell_refs_for_movable | if shit goes south, this will find hanging references for qdeleting movables inside the spatial grid |
force_remove_from_cell | remove this movable from the given spatial_grid_cell |
force_remove_from_grid | example: |
get_cell_of | get the grid cell encomapassing targets coordinates |
get_cells_in_bounds | get all grid cells intersecting the bounding box around center with sides of length (2 * range_x, 2 * range_y) |
get_cells_in_range | get all grid cells intersecting the bounding box around center with sides of length 2 * range |
orthogonal_range_search | https://en.wikipedia.org/wiki/Range_searching#Orthogonal_range_searching |
pregenerate_more_oranges_ears | creates number_to_generate new oranges_ear's and adds them to the subsystems list of ears. i really fucking hope this never gets called after init :clueless: |
propogate_spatial_grid_to_new_z | creates the spatial grid for a new z level |
queued_item_deleted | if a movable is inside our pre init queue before we're initialized and it gets deleted we need to remove that reference with this proc |
remove_from_pre_init_queue | removes an initialized and probably deleted movable from our pre init queue before we're initialized |
remove_grid_awareness | Removes grid awareness from the passed in atom, of the passed in type |
remove_grid_membership | Removes grid membership from the passed in atom, of the passed in type |
remove_single_type | acts like exit_cell() but only removes the target from the specified type of grid cell contents list |
untracked_movable_error | if for whatever reason this movable is "untracked" e.g. it breaks the assumption that a movable is only inside the contents of any grid cell associated with its loc, this will error. this checks every grid cell in the world so dont call this on live unless you have to. returns TRUE if this movable is untracked, FALSE otherwise |
update_grid_awareness | Updates the string that atoms hold that stores their grid awareness We will use it to key into their spatial grid categories later |
Var Details
dummy_list
empty spatial grid cell content lists are just a reference to this instead of a standalone list to save memory without needed to check if its null when iterating
grids_by_z_level
list of the spatial_grid_cell datums per z level, arranged in the order of y index then x index
number_of_oranges_ears
how many pregenerated /mob/oranges_ear instances currently exist. this should hopefully never exceed its starting value
pregenerated_oranges_ears
list of all of /mob/oranges_ear instances we have pregenerated for view() iteration speedup
spatial_grid_categories
associative list of the form: movable.spatial_grid_key (string) -> inner list of spatial grid types for that key. inner lists contain contents channel types such as SPATIAL_GRID_CONTENTS_TYPE_HEARING etc. we use this to make adding to a cell static cost, and to save on memory
waiting_to_add_by_type
everything that spawns before us is added to this list until we initialize
Proc Details
add_grid_awareness
Adds grid awareness to the passed in atom, of the passed in type Basically, when this atom moves between grids, it wants to have enter/exit cell called on it
add_grid_membership
Alerts the atom's current cell that it wishes to be treated as a member This functionally amounts to "hey, I was recently made aware by [add_grid_awareness], please insert me into my current cell"
add_single_type
acts like enter_cell() but only adds the target to a specified type of grid cell contents list
after_world_bounds_expanded
adds cells to the grid for every z level when world.maxx or world.maxy is expanded after this subsystem is initialized. hopefully this is never needed. because i never tested this.
assign_oranges_ears
allocate one /mob/oranges_ear mob per turf containing atoms_that_need_ears and give them a reference to every listed atom in their turf. if an oranges_ear is allocated to a turf that already has an oranges_ear then the second one fails to allocate (and gives the existing one the atom it was assigned to)
enter_cell
find the spatial map cell that target belongs to, then add the target to it, as its type prefers. make sure to provide the turf new_target is "in"
enter_pre_init_queue
add a movable to the pre init queue for whichever type is specified so that when the subsystem initializes they get added to the grid
exit_cell
find the spatial map cell that target used to belong to, then remove the target (and sometimes it's important_recusive_contents) from it. make sure to provide the turf old_target used to be "in"
- old_target - the thing we want to remove from the spatial grid cell
- target_turf - the turf we use to determine the cell we're removing from
- exclusive_type - either null or a valid contents channel. if you just want to remove a single type from the grid cell then use this
find_hanging_cell_refs_for_movable
if shit goes south, this will find hanging references for qdeleting movables inside the spatial grid
force_remove_from_cell
remove this movable from the given spatial_grid_cell
force_remove_from_grid
example:
/mob/living/trolls_the_maintainer instance, which is supposed to only be in the contents of a spatial grid cell at coords: (136, 136, 14), was in the contents of 3 spatial grid cells when it was only supposed to be in one! within the contents of the following cells: {(68, 153, 2), within channels: hearing}, {coords: (221, 170, 3), within channels: hearing}, {coords: (255, 153, 11), within channels: hearing}, {coords: (136, 136, 14), within channels: hearing}.
remove this movable from the grid by finding the grid cell its in and removing it from that. if it cant infer a grid cell its located in (e.g. if its in nullspace but it can happen if the grid isnt expanded to a z level), search every grid cell.
get_cell_of
get the grid cell encomapassing targets coordinates
get_cells_in_bounds
get all grid cells intersecting the bounding box around center with sides of length (2 * range_x, 2 * range_y)
get_cells_in_range
get all grid cells intersecting the bounding box around center with sides of length 2 * range
orthogonal_range_search
https://en.wikipedia.org/wiki/Range_searching#Orthogonal_range_searching
searches through the grid cells intersecting a rectangular search space (with sides of length 2 * range) then returns all contents of type inside them. much faster than iterating through view() to find all of what you want.
this does NOT return things only in range distance from center! the search space is a square not a circle, if you want only things in a certain distance then you need to filter that yourself
- center - the atom that is the center of the searched circle
- type - the type of grid contents you are looking for, see __DEFINES/spatial_grid.dm
- range - the bigger this is, the more spatial grid cells the search space intersects
pregenerate_more_oranges_ears
creates number_to_generate new oranges_ear's and adds them to the subsystems list of ears. i really fucking hope this never gets called after init :clueless:
propogate_spatial_grid_to_new_z
creates the spatial grid for a new z level
queued_item_deleted
if a movable is inside our pre init queue before we're initialized and it gets deleted we need to remove that reference with this proc
remove_from_pre_init_queue
removes an initialized and probably deleted movable from our pre init queue before we're initialized
remove_grid_awareness
Removes grid awareness from the passed in atom, of the passed in type
remove_grid_membership
Removes grid membership from the passed in atom, of the passed in type
remove_single_type
acts like exit_cell() but only removes the target from the specified type of grid cell contents list
untracked_movable_error
if for whatever reason this movable is "untracked" e.g. it breaks the assumption that a movable is only inside the contents of any grid cell associated with its loc, this will error. this checks every grid cell in the world so dont call this on live unless you have to. returns TRUE if this movable is untracked, FALSE otherwise
update_grid_awareness
Updates the string that atoms hold that stores their grid awareness We will use it to key into their spatial grid categories later