diff --git a/lib/spell/spell.lua b/lib/spell/spell.lua index 82bcbb1..ec162a9 100644 --- a/lib/spell/spell.lua +++ b/lib/spell/spell.lua @@ -26,6 +26,25 @@ function spell:draw() end function spell:cast(caster, target) return end +--- @param caster Character +--- @param spellTarget SpellTarget +--- @param targetPosition Vec3 +local function checkTarget(caster, spellTarget, targetPosition) + --- @TODO имплементировать все варианты SpellTarget + local targetCharacterId = Tree.level.characterGrid:get(targetPosition) + if spellTarget == "caster" then + return targetCharacterId == caster.id + end + if spellTarget == "character" then + return not not targetCharacterId + end + if spellTarget == "enemy" then + return targetCharacterId and targetCharacterId ~= caster.id + end + + return true +end + --- Конструктор [Spell] --- @param data {tag: string, baseCost: integer, baseCooldown: integer, possibleTarget: SpellTarget, distance: integer?, onCast: fun(caster: Character, target: Vec3): Task} --- @return Spell @@ -39,9 +58,6 @@ function spell.new(data) } function newSpell:cast(caster, target) - -- проверка корректности цели - --- @TODO имплементировать все варианты SpellTarget - -- проверка на расстояние до цели 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)) @@ -51,6 +67,9 @@ function spell.new(data) return end + -- проверка корректности цели + if not checkTarget(caster, self.possibleTarget, target) then return end + -- проверка на достаточное количество маны if caster:try(Tree.behaviors.stats, function(stats) return stats.mana < self.baseCost @@ -58,6 +77,10 @@ function spell.new(data) return end + caster:try(Tree.behaviors.stats, function(stats) + stats.mana = stats.mana - self.baseCost + end) + return data.onCast(caster, target) end diff --git a/lib/spellbook.lua b/lib/spellbook.lua index ee19bfe..bfca196 100644 --- a/lib/spellbook.lua +++ b/lib/spellbook.lua @@ -65,51 +65,54 @@ function walk:draw() love.graphics.setColor(1, 1, 1) end -local regenerateMana = setmetatable({}, spell) -regenerateMana.tag = "dev_mana" +local regenerateMana = spell.new { + tag = "dev_mana", + baseCooldown = 2, + baseCost = 0, + possibleTarget = "caster", + distance = 0, + onCast = function(caster, target) + caster:try(Tree.behaviors.stats, function(stats) + stats.mana = 10 + stats.initiative = stats.initiative + 10 + end) -function regenerateMana:cast(caster, target) - caster:try(Tree.behaviors.stats, function(stats) - stats.mana = 10 - stats.initiative = stats.initiative + 10 - end) + local sprite = caster:has(Tree.behaviors.sprite) + if not sprite then return task.fromValue() end + print(caster.id, "has regenerated mana and gained initiative") - local sprite = caster:has(Tree.behaviors.sprite) - if not sprite then return nil end - print(caster.id, "has regenerated mana and gained initiative") + local light = require "lib/character/character".spawn("Light Effect") + light:addBehavior { + Tree.behaviors.light.new { color = Vec3 { 0.6, 0.3, 0.3 }, intensity = 4 }, + Tree.behaviors.residentsleeper.new(), + Tree.behaviors.positioned.new(caster:has(Tree.behaviors.positioned).position + Vec3 { 0.5, 0.5 }), + } - local light = require "lib/character/character".spawn("Light Effect") - light:addBehavior { - Tree.behaviors.light.new { color = Vec3 { 0.6, 0.3, 0.3 }, intensity = 4 }, - Tree.behaviors.residentsleeper.new(), - Tree.behaviors.positioned.new(caster:has(Tree.behaviors.positioned).position + Vec3 { 0.5, 0.5 }), - } + local flash = function(callback) + light:has(Tree.behaviors.light):animateColor(Vec3 {})( + function() + light:die() + callback() + end + ) + end - local flash = function(callback) - light:has(Tree.behaviors.light):animateColor(Vec3 {})( - function() - light:die() - callback() - end - ) + return task.wait { + flash, + sprite:animate("hurt") + } end - - return task.wait { - flash, - sprite:animate("hurt") - } -end +} local attack = spell.new { tag = "dev_attack", baseCooldown = 1, baseCost = 2, possibleTarget = "enemy", - distance = 2, + distance = 1, onCast = function(caster, target) --- @type Character local targetCharacterId = Tree.level.characterGrid:get(target) - if not targetCharacterId or targetCharacterId == caster.id then return task.fromValue() end local targetCharacter = Tree.level.characters[targetCharacterId] targetCharacter:try(Tree.behaviors.stats, function(stats) stats.hp = stats.hp - 4