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) caster = b.position end) local charTarget local minDist = 88005553535 -- spooky magic number for k, v in pairs(Tree.level.characters) do v:try(Tree.behaviors.positioned, function(b) local dist = ((caster.x - b.position.x) ^ 2 + (caster.y - b.position.y) ^ 2) ^ 0.5 if dist < minDist and dist ~= 0 then minDist = dist charTarget = v end -- print(k, b.position) end) end 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) self.target = pathToClosestCharacter(self.owner, 2) local task1 = spellB.spellbook[1]:cast(self.owner, self.target) if task1 then task1( function() -- здесь мы оказываемся после того, как сходили в первый раз local newTarget = Vec3 { 1, 1 } local task2 = spellB.spellbook[1]:cast(self.owner, newTarget) if task2 then -- дергаем функцию после завершения хода task2(callback) else callback() end end ) else print('рот этого казино') callback() end end) end end, ["dev_mage"] = function(self) return function(callback) print("etoh... bleh") callback() end end } --- @class AIBehavior : Behavior --- @field target Vec3? local behavior = {} behavior.__index = behavior behavior.id = "ai" --- @param class Class function behavior.new(class) return setmetatable({ makeTurn = aiNature[class] }, behavior) end return behavior