Grid
A spatial hash over the X/Y plane. Entries are sorted into square cells, so asking "what is near this position" only looks at a handful of entries instead of all of them. MSK.Zones uses it internally to keep large numbers of zones cheap.
An entry is any table with either
coords(vector) andradius(number), ormin(vector) andmax(vector) as an axis-aligned bounding box.
The height (Z) is ignored. The grid does not check real distances, it only narrows down the candidates. Do your own distance or shape check on the entries it returns.
MSK.Grid has no exports. Use it through the import in your own resource.
MSK.Grid.New
Creates a grid with cells of cellSize units.
Parameters
cellSize - number - Optional - Default: 250.0 - Size of one cell in game units
Returns
grid - table - The grid
local grid = MSK.Grid.New(cellSize)
-- Example
local grid = MSK.Grid.New(100.0)
Choose a cell size somewhat larger than your typical entry. Tiny cells make large entries span many cells, huge cells put too many entries into each one.
grid:Add
Adds an entry. If the entry is already in the grid, it is sorted in again, which is how you update an entry after changing its position or size.
Parameters
entry - table - The entry (coords + radius or min + max)
Returns
entry - table - The same entry
local entry = grid:Add(entry)
-- Example
local shop = grid:Add({ name = 'shop', coords = vector3(25.7, -1347.3, 29.5), radius = 15.0 })
local area = grid:Add({ name = 'area', min = vector3(0.0, 0.0, 0.0), max = vector3(300.0, 300.0, 50.0) })
-- Moved? Add it again
shop.coords = vector3(30.0, -1340.0, 29.5)
grid:Add(shop)
grid:Remove
Removes an entry from the grid.
Parameters
entry - table - The entry
Returns
removed - boolean - Whether the entry was in the grid
local removed = grid:Remove(entry)
grid:GetNearby
Returns the entries that share the cell containing coords. This is the cheapest lookup, useful for "is the player inside any zone" checks.
Parameters
coords - vector3/vector2/table - The position
Returns
entries - table - List of entries in that cell
local entries = grid:GetNearby(coords)
-- Example
local coords = GetEntityCoords(PlayerPedId())
for _, entry in ipairs(grid:GetNearby(coords)) do
if #(coords - entry.coords) <= entry.radius then
print('Inside', entry.name)
end
end
grid:GetInRange
Returns the entries in every cell touched by the square around coords with the given radius. No entry appears twice.
Parameters
coords - vector3/vector2/table - The position
radius - number - Half the side length of the search square
Returns
entries - table - List of candidate entries
local entries = grid:GetInRange(coords, radius)
-- Example
local candidates = grid:GetInRange(GetEntityCoords(PlayerPedId()), 500.0)
grid:Has
Checks whether an entry is in the grid.
Parameters
entry - table - The entry
Returns
has - boolean - Whether the entry is in the grid
local has = grid:Has(entry)
grid:Clear
Removes every entry from the grid.
grid:Clear()