From a6578ec8dd978acc5c8236111299132b3ffc31b6 Mon Sep 17 00:00:00 2001 From: PeaAshMeter Date: Wed, 18 Mar 2026 02:01:59 +0300 Subject: [PATCH] Refactor target distance check using query intersection 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 --- lib/spell/spell.lua | 11 +---------- lib/spell/target_query.lua | 6 +++--- lib/spell/target_test.lua | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/spell/spell.lua b/lib/spell/spell.lua index 43f8a65..099ec85 100644 --- a/lib/spell/spell.lua +++ b/lib/spell/spell.lua @@ -41,16 +41,7 @@ function spell.new(data) } function newSpell:cast(caster, target) - -- проверка на расстояние до цели - if self.distance and caster:try(Tree.behaviors.positioned, function(p) - local dist = math.max(math.abs(p.position.x - target.x), math.abs(p.position.y - target.y)) - print("dist:", dist) - return dist > self.distance - end) then - return - end - - if not self.targetQuery.test(caster, target) then return end -- проверка корректности цели + if not self.targetQuery:intersect(Query(targetTest.distance(self.distance))).test(caster, target) then return end -- проверка корректности цели -- проверка на достаточное количество маны if caster:try(Tree.behaviors.stats, function(stats) diff --git a/lib/spell/target_query.lua b/lib/spell/target_query.lua index 6460c47..d84de28 100644 --- a/lib/spell/target_query.lua +++ b/lib/spell/target_query.lua @@ -19,7 +19,7 @@ function query:join(q) test = function(caster, pos) return self.test(caster, pos) or q.test(caster, pos) end - }, q) + }, query) end --- Пересечение @@ -29,7 +29,7 @@ function query:intersect(q) test = function(caster, pos) return self.test(caster, pos) and q.test(caster, pos) end - }, q) + }, query) end --- Исключение (не коммутативное, "те, что есть в query, но нет в q") @@ -39,7 +39,7 @@ function query:exclude(q) test = function(caster, pos) return self.test(caster, pos) and not q.test(caster, pos) end - }, q) + }, query) end --- Находит все соответствующие условиям координаты тайлов и возвращает их в виде списка diff --git a/lib/spell/target_test.lua b/lib/spell/target_test.lua index f7646a7..0f99146 100644 --- a/lib/spell/target_test.lua +++ b/lib/spell/target_test.lua @@ -1,13 +1,28 @@ --- @alias SpellTargetTest fun(caster: Character, targetPosition: Vec3) : boolean return { + -- любой тайл any = function() return true end, + -- тайл, где находится кастующий caster = function(caster, targetPosition) local targetCharacterId = Tree.level.characterGrid:get(targetPosition) return caster.id == targetCharacterId end, + -- тайл, где находится любой персонаж character = function(caster, targetPosition) local targetCharacterId = Tree.level.characterGrid:get(targetPosition) return not not targetCharacterId + end, + -- тайл в пределах окружности в нашей кривой метрике + --- @param radius number + distance = function(radius) + return function(caster, targetPosition) + return caster:try(Tree.behaviors.positioned, function(p) + local dist = math.max(math.abs(p.position.x - targetPosition.x), + math.abs(p.position.y - targetPosition.y)) + print("dist:", dist) + return dist <= radius + end) + end end }