TLDR: higher-order functions my beloved

Add counter utility and chain async animations in spell cast

Introduce a Counter module to coordinate multiple asynchronous
animation callbacks and update spellbook cast to run chained
animations sequentially. Also lock selector during AI turns.
This commit is contained in:
PeaAshMeter 2026-01-29 02:32:58 +03:00
parent 93a4961419
commit 86a599723e
4 changed files with 71 additions and 1 deletions

View File

@ -37,7 +37,9 @@ function turnOrder:next()
local char = Tree.level.characters[self.current]
char:try(Tree.behaviors.ai, function(ai)
Tree.level.selector:lock()
ai:makeTurn()(function()
Tree.level.selector:unlock()
self:next()
end)
end)

View File

@ -56,7 +56,37 @@ function walk:cast(caster, target)
return
end
return caster:has(Tree.behaviors.tiled):followPath(path)
local testChar = Tree.level.characters[1];
return function(callback) -- <- вызовется после всех анимаций
local counter = require 'lib.utils.counter' (callback)
counter.push()
return caster:has(Tree.behaviors.tiled):followPath(path)(
function()
do
counter.push()
local initialPos2 = caster:has(Tree.behaviors.positioned).position:floor()
local path2 = require "lib.pathfinder" (initialPos2, Vec3 { 10, math.random(1, 10) })
path:pop_front()
caster:has(Tree.behaviors.tiled):followPath(path2)(counter.pop)
end
do
counter.push()
local testInitialPos = testChar:has(Tree.behaviors.positioned).position:floor()
local testPath = require "lib.pathfinder" (testInitialPos, Vec3 { 10, math.random(20, 5) })
path:pop_front()
testChar:has(Tree.behaviors.tiled):followPath(testPath)(counter.pop)
end
counter.pop()
end
) -- <- callback вызовется после followPath
end
end
function walk:update(caster, dt)

View File

38
lib/utils/counter.lua Normal file
View File

@ -0,0 +1,38 @@
--- @class Counter
--- @field private count integer
--- @field private onFinish fun(): nil
--- @field private isAlive boolean
--- @field push fun():nil добавить 1 к счетчику
--- @field pop fun():nil убавить 1 у счетчика
local counter = {}
counter.__index = counter
--- @private
function counter:_push()
self.count = self.count + 1
end
--- @private
function counter:_pop()
self.count = self.count - 1
if self.count == 0 and self.isAlive then
self.isAlive = false
self.onFinish()
end
end
--- @param onFinish fun(): nil
local function new(onFinish)
local t = {
count = 0,
onFinish = onFinish,
isAlive = true,
}
t.push = function() counter._push(t) end
t.pop = function() counter._pop(t) end
return setmetatable(t, counter)
end
return new