Replace manual distance check with combined targetQuery and distance query intersection for cleaner spell targeting logic Fix query combinators to correctly reference self in closures
68 lines
1.9 KiB
Lua
68 lines
1.9 KiB
Lua
--- Тип, отвечающий за выбор и фильтрацию подходящих тайлов как цели спелла
|
|
--- теория множеств my beloved?
|
|
--- @class SpellTargetQuery
|
|
local query = {}
|
|
query.__index = query
|
|
|
|
--- Проверяет координаты на соответствие внутреннему условию
|
|
--- @param caster Character
|
|
--- @param position Vec3
|
|
--- @return boolean
|
|
function query.test(caster, position)
|
|
return true
|
|
end
|
|
|
|
--- Объединение
|
|
--- @param q SpellTargetQuery
|
|
function query:join(q)
|
|
return setmetatable({
|
|
test = function(caster, pos)
|
|
return self.test(caster, pos) or q.test(caster, pos)
|
|
end
|
|
}, query)
|
|
end
|
|
|
|
--- Пересечение
|
|
--- @param q SpellTargetQuery
|
|
function query:intersect(q)
|
|
return setmetatable({
|
|
test = function(caster, pos)
|
|
return self.test(caster, pos) and q.test(caster, pos)
|
|
end
|
|
}, query)
|
|
end
|
|
|
|
--- Исключение (не коммутативное, "те, что есть в query, но нет в q")
|
|
--- @param q SpellTargetQuery
|
|
function query:exclude(q)
|
|
return setmetatable({
|
|
test = function(caster, pos)
|
|
return self.test(caster, pos) and not q.test(caster, pos)
|
|
end
|
|
}, query)
|
|
end
|
|
|
|
--- Находит все соответствующие условиям координаты тайлов и возвращает их в виде списка
|
|
--- @param caster Character
|
|
--- @return Vec3[]
|
|
function query:asSet(caster)
|
|
--- @TODO: оптимизировать и брать не всю карту для выборки
|
|
local res = {}
|
|
for _, tile in pairs(Tree.level.tileGrid) do
|
|
if self.test(caster, tile.position) then
|
|
table.insert(res, tile.position)
|
|
end
|
|
end
|
|
|
|
return res
|
|
end
|
|
|
|
--- @param test SpellTargetTest
|
|
local function new(test)
|
|
return setmetatable({
|
|
test = test
|
|
}, query)
|
|
end
|
|
|
|
return new
|