heroes-of-nerevelon/lib/spell/target_query.lua
PeaAshMeter 4431934e6b Refactor spell target selection to use composable queries
Introduce SpellTargetQuery abstraction for flexible target filtering.
Replace fixed target types with query-based system supporting union,
intersection, and exclusion of target conditions. Update spells
accordingly.
2026-03-17 23:09:36 +03:00

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
}, q)
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
}, q)
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
}, q)
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