From c4dfb5956d8b446c84932d5d8fb94370daeaf3af Mon Sep 17 00:00:00 2001 From: PeaAshMeter Date: Sun, 28 Sep 2025 23:34:17 +0300 Subject: [PATCH] add spellcaster behavior --- lib/character/behaviors/spellcaster.lua | 25 +++++++++++++++++++++++++ lib/character/character.lua | 17 ++++++----------- lib/level/selector.lua | 9 +++++---- lib/spellbook.lua | 3 +-- lib/tree.lua | 15 ++++++++------- lib/ui/layout.lua | 9 +++++---- 6 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 lib/character/behaviors/spellcaster.lua diff --git a/lib/character/behaviors/spellcaster.lua b/lib/character/behaviors/spellcaster.lua new file mode 100644 index 0000000..2195b8f --- /dev/null +++ b/lib/character/behaviors/spellcaster.lua @@ -0,0 +1,25 @@ +--- @class SpellcasterBehavior : Behavior +--- @field spellbook Spell[] собственный набор спеллов персонажа +--- @field cast Spell | nil ссылка на активный спелл из спеллбука +local behavior = {} +behavior.__index = behavior +behavior.id = "spellcaster" + +---@param spellbook Spell[] | nil +---@return SpellcasterBehavior +function behavior.new(spellbook) + local spb = require "lib.spellbook" --- @todo временное добавление ходьбы всем персонажам + local t = {} + t.spellbook = spellbook or spb.of { spb.walk } + return setmetatable(t, behavior) +end + +function behavior:update(dt) + if self.cast then self.cast:update(self.owner, dt) end +end + +function behavior:draw() + if self.cast then self.cast:draw() end +end + +return behavior diff --git a/lib/character/character.lua b/lib/character/character.lua index cf709d3..57205c8 100644 --- a/lib/character/character.lua +++ b/lib/character/character.lua @@ -35,10 +35,10 @@ local function spawn(name, template, spriteDir, position, size, level) char:addBehavior { Tree.behaviors.map.new(position, size), Tree.behaviors.render.new(spriteDir), + Tree.behaviors.spellcaster.new() } - char:setState("idle") --- @todo сделать это отдельным модулем - local spb = require "lib.spellbook" --- @todo это тоже - char.spellbook = spb.of { spb.walk } + char:setState("idle") --- @todo сделать это отдельным модулем + Tree.level.characters[char.id] = char return char @@ -120,20 +120,15 @@ end function character:update(dt) --- @todo ну ты понел - -- for _, b in ipairs(self.behaviors) do - -- if b.update then b:update(dt) end - -- end - self:has(Tree.behaviors.map):update(dt) - if self.cast then self.cast:update(self, dt) end - self:has(Tree.behaviors.render):update(dt) + for _, b in ipairs(self.behaviors) do + if b.update then b:update(dt) end + end end function character:draw() for _, b in ipairs(self.behaviors) do if b.draw then b:draw() end end - - if self.cast then self.cast:draw() end --- @todo 🤡 end return { spawn = spawn } diff --git a/lib/level/selector.lua b/lib/level/selector.lua index 2814ea3..8305a3e 100644 --- a/lib/level/selector.lua +++ b/lib/level/selector.lua @@ -25,10 +25,11 @@ function selector:update(dt) if not characterId and self.id then -- Когда кликаем по тайлу за персонажа в режиме каста, кастуем спелл local char = Tree.level.characters[self.id] - if char.cast then - char.cast:cast(char, mousePosition) - char.cast = nil - end + char:try(Tree.behaviors.spellcaster, function(b) + if not b.cast then return end + b.cast:cast(char, mousePosition) + b.cast = nil + end) end self:select(characterId) diff --git a/lib/spellbook.lua b/lib/spellbook.lua index 6ace2cc..0854045 100644 --- a/lib/spellbook.lua +++ b/lib/spellbook.lua @@ -17,12 +17,11 @@ local walk = setmetatable({ }, spell) function walk:cast(caster, target) - caster.cast = nil local path = self.path path:pop_front() print("Following path: ") for p in path:values() do print(p) end - caster:followPath(path) + caster:has(Tree.behaviors.map):followPath(path) end function walk:update(caster, dt) diff --git a/lib/tree.lua b/lib/tree.lua index 7e8197f..3bd5858 100644 --- a/lib/tree.lua +++ b/lib/tree.lua @@ -3,13 +3,14 @@ --- В love.update обновлять, в love.draw читать -Tree = { +Tree = { assets = (require "lib.utils.asset_bundle"):load() } -Tree.panning = require "lib/panning" -Tree.controls = require "lib.controls" -Tree.level = (require "lib.level.level").new("procedural", "flower_plains") -- для теста у нас только один уровень, который сразу же загружен +Tree.panning = require "lib/panning" +Tree.controls = require "lib.controls" +Tree.level = (require "lib.level.level").new("procedural", "flower_plains") -- для теста у нас только один уровень, который сразу же загружен -Tree.behaviors = {} --- @todo написать нормальную загрузку поведений -Tree.behaviors.map = require "lib.character.behaviors.map" -Tree.behaviors.render = require "lib.character.behaviors.render" +Tree.behaviors = {} --- @todo написать нормальную загрузку поведений +Tree.behaviors.map = require "lib.character.behaviors.map" +Tree.behaviors.render = require "lib.character.behaviors.render" +Tree.behaviors.spellcaster = require "lib.character.behaviors.spellcaster" diff --git a/lib/ui/layout.lua b/lib/ui/layout.lua index 19f687d..3f0e03f 100644 --- a/lib/ui/layout.lua +++ b/lib/ui/layout.lua @@ -11,10 +11,11 @@ local SkillButton = ui.Rectangle { } function SkillButton:update(dt) ui.Rectangle.update(self, dt) - self.color = self.owner.cast and { 0, 1, 0 } or { 1, 0, 0 } - self:onTap(function() - print(self.owner.spellbook[self.spellId]) - self.owner.cast = self.owner.cast and nil or self.owner.spellbook[self.spellId] + self.owner:try(Tree.behaviors.spellcaster, function(spellcaster) + self.color = spellcaster.cast and { 0, 1, 0 } or { 1, 0, 0 } + self:onTap(function() + spellcaster.cast = spellcaster.cast and nil or spellcaster.spellbook[self.spellId] + end) end) end