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.
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
|
|
}, 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
|