66 lines
2.1 KiB
Lua
66 lines
2.1 KiB
Lua
local utils = require "lib.utils.utils"
|
||
--- Пометровая сетка источников света, чтобы быстро искать ближайшие для некоторого объекта
|
||
--- @class LightGrid : Grid
|
||
--- @field __grid {string: [Id]}
|
||
local grid = setmetatable({}, require "lib.level.grid.base")
|
||
grid.__index = grid
|
||
|
||
--- Adds a character id to the grid
|
||
--- @private
|
||
--- @param id Id
|
||
function grid:add(id)
|
||
local character = Tree.level.characters[id]
|
||
if not character then return end
|
||
|
||
local lightB = character:has(Tree.behaviors.light)
|
||
if not lightB then return end
|
||
|
||
local positioned = character:has(Tree.behaviors.positioned)
|
||
if not positioned then return end
|
||
|
||
local key = tostring(Vec3 { positioned.position.x, positioned.position.y }:floor())
|
||
if not self.__grid[key] then self.__grid[key] = {} end
|
||
table.insert(self.__grid[key], character.id)
|
||
end
|
||
|
||
--- fills the grid with the actual data
|
||
---
|
||
--- should be called as early as possible during every tick
|
||
function grid:reload()
|
||
self:reset()
|
||
utils.each(Tree.level.characters, function(c)
|
||
self:add(c.id)
|
||
end)
|
||
end
|
||
|
||
--- Возвращает все источники света, которые находятся в пределах круга с диаметром [distance] в [метрике Чебышёва](https://ru.wikipedia.org/wiki/Расстояние_Чебышёва)
|
||
--- @param position Vec3
|
||
--- @param distance integer
|
||
function grid:query(position, distance)
|
||
--- @type Id[]
|
||
local res = {}
|
||
local topLeft = position:subtract(Vec3 { distance / 2, distance / 2 }):floor()
|
||
for i = 0, distance, 1 do
|
||
for j = 0, distance, 1 do
|
||
--- @type Id[]?
|
||
local lights = self:get(topLeft:add(Vec3 { i, j }))
|
||
if lights then
|
||
for _, lightChar in ipairs(lights) do
|
||
table.insert(res, lightChar)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
return res
|
||
end
|
||
|
||
--- Generates an empty grid
|
||
--- @return LightGrid
|
||
local function new()
|
||
return setmetatable({
|
||
__grid = {}
|
||
}, grid)
|
||
end
|
||
|
||
return { new = new }
|