From 7526e3064ff633012ab4630d1ee6ee98d7576e0f Mon Sep 17 00:00:00 2001 From: neckrat Date: Sat, 25 Apr 2026 00:52:38 +0300 Subject: [PATCH] circleVectors function and some ai progress --- lib/character/behaviors/ai.lua | 54 ++++++++++++++++++++++++++++++---- main.lua | 4 +-- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/lib/character/behaviors/ai.lua b/lib/character/behaviors/ai.lua index 64bc736..4b94d69 100644 --- a/lib/character/behaviors/ai.lua +++ b/lib/character/behaviors/ai.lua @@ -1,5 +1,10 @@ local easing = require "lib.utils.easing" +local pf = require "lib.pathfinder" +local utils = require "lib.utils.utils" +EPSILON = 0.01 + +--- @return Character local function closestCharacter(char) local caster = Vec3 {} char:try(Tree.behaviors.positioned, function(b) @@ -20,16 +25,54 @@ local function closestCharacter(char) return charTarget end +--- Возвращает все точки в радиусе в виде векторов +--- @param radius integer +local function circleVectors(radius) + local cam = Tree.level.camera + local vecs = {} + for t = 0, 2 * math.pi, EPSILON do + local x = math.sin(t) * radius + local y = math.cos(t) * radius + vecs[cam:toWorldPosition(Vec3 { x, y })] = true + end + return utils.keys(vecs) +end + +--- @param owner Character +--- @param space integer здесь мы должны сами определять, сколько должны не доходить до персонажа (1 <= n) +--- @return Vec3|nil +local function pathToClosestCharacter(owner, space) + local charTarget = closestCharacter(owner) + local targetPosition, ownerPosition = charTarget:has(Tree.behaviors.positioned), owner:has(Tree.behaviors.positioned) + if not targetPosition or not ownerPosition then return end + local target = Vec3 {} + print(ownerPosition.position, targetPosition.position) + local path = pf(ownerPosition.position, targetPosition.position) + for c in path:values() do + print(c) + end + print(path) + space = math.min(space, path:size()) + print(space, path:size()) + for _ = 0, space - 1 do + path:pop_back() + end + if path:size() ~= 0 then + target = path:pop_back() + else + target = ownerPosition.position + end + print(target, targetPosition.position) + --- @todo тут захардкожено + 1, но мы должны как-то хитро определять с какой стороны обойти + return target +end + ---@type {[Class]: fun(self: AIBehavior): Task} возможно где-то здесь на объявлении типа сломается типизация local aiNature = { ["dev_warrior"] = function(self) return function(callback) -- почему так, описано в Task self.owner:try(Tree.behaviors.spellcaster, function(spellB) - local charTarget = closestCharacter(self.owner) - charTarget:try(Tree.behaviors.positioned, function(b) - self.target = Vec3 { b.position.x, b.position.y + 1 } --- @todo тут захардкожено + 1, но мы должны как-то хитро определять с какой стороны обойти - end) - + self.target = pathToClosestCharacter(self.owner, 2) local task1 = spellB.spellbook[1]:cast(self.owner, self.target) if task1 then task1( @@ -46,6 +89,7 @@ local aiNature = { end ) else + print('рот этого казино') callback() end end) diff --git a/main.lua b/main.lua index 519bc34..c9d6422 100644 --- a/main.lua +++ b/main.lua @@ -30,7 +30,7 @@ function love.load() :addBehavior { Tree.behaviors.residentsleeper.new(), Tree.behaviors.stats.new(nil, nil, 1), - Tree.behaviors.positioned.new(Vec3 { 4, 3 }), + Tree.behaviors.positioned.new(Vec3 { 3, 1 }), Tree.behaviors.tiled.new(), Tree.behaviors.sprite.new(Tree.assets.files.sprites.character), Tree.behaviors.shadowcaster.new(), @@ -41,7 +41,7 @@ function love.load() :addBehavior { Tree.behaviors.residentsleeper.new(), Tree.behaviors.stats.new(nil, nil, 3), - Tree.behaviors.positioned.new(Vec3 { 5, 3 }), + Tree.behaviors.positioned.new(Vec3 { 7, 1 }), Tree.behaviors.tiled.new(), Tree.behaviors.sprite.new(Tree.assets.files.sprites.character), Tree.behaviors.shadowcaster.new(),