diff --git a/lib/character/behaviors/effects.lua b/lib/character/behaviors/effects.lua index 8687132..1912295 100644 --- a/lib/character/behaviors/effects.lua +++ b/lib/character/behaviors/effects.lua @@ -16,7 +16,7 @@ behavior.id = "effects" function behavior.new() local efb = require "lib.effectbook" return setmetatable({ - effectbook = efb.of { efb.bleeding }, + effectbook = efb.of { efb.bleeding, efb.aversionToDeath }, effectsPriority = {}, effectsProperties = {}, }, behavior) @@ -26,11 +26,9 @@ end --- @param effect Effect --- @param stacks integer function behavior:addEffect(effect, stacks, intensity) - if effect.beforeBirth then - local task1 = effect:beforeBirth(self.owner, intensity) - if task1 then - task1(function() end) - end + local task1 = effect:beforeBirth(self.owner, intensity) + if task1 then + task1(function() end) end -- проверяем эффект на возможности суммирования (aka противоречия) for i, ef in ipairs(self.effectsPriority) do @@ -39,9 +37,9 @@ function behavior:addEffect(effect, stacks, intensity) stacks = stacks + self.effectsProperties[ef].stacks, intensity = intensity } - local task1 = effect:afterBirth(self.owner, intensity) - if task1 then - task1(function() end) + local task2 = effect:afterBirth(self.owner, intensity) + if task2 then + task2(function() end) end return end @@ -58,9 +56,9 @@ function behavior:addEffect(effect, stacks, intensity) intensity = intensity } print("[Effects]: мы применили эффект!!") - local task1 = effect:afterBirth(self.owner, intensity) - if task1 then - task1(function() end) + local task3 = effect:afterBirth(self.owner, intensity) + if task3 then + task3(function() end) end end @@ -143,4 +141,27 @@ function behavior:afterCast() end end +--- должен вызываться перед получением урона +function behavior:beforeDamage(damage) + local totalDamage = damage + for i, ef in ipairs(self.effectsPriority) do + local task1 + task1, totalDamage = ef:beforeDamage(self.owner, self.effectsProperties[ef].intensity, totalDamage or damage) + if task1 then + task1(function() end) + end + end + return totalDamage or damage +end + +--- должен вызываться после получения урона +function behavior:afterDamage() + for i, ef in pairs(self.effectsPriority) do + local task1 = ef:afterDamage(self.owner, self.effectsProperties[ef].intensity) + if task1 then + task1(function() end) + end + end +end + return behavior diff --git a/lib/character/behaviors/stats.lua b/lib/character/behaviors/stats.lua index 55089f2..1bb37c1 100644 --- a/lib/character/behaviors/stats.lua +++ b/lib/character/behaviors/stats.lua @@ -21,6 +21,9 @@ end --- @param damage integer function behavior:dealDamage(damage) + local effects = self.owner:has(Tree.behaviors.effects) + print("[Stats]: применяем эффект") + if effects then damage = effects:beforeDamage(damage) end self.hp = self.hp - damage self:checkStats() end diff --git a/lib/effectbook.lua b/lib/effectbook.lua index 13dae40..aa3270c 100644 --- a/lib/effectbook.lua +++ b/lib/effectbook.lua @@ -45,8 +45,24 @@ function bleeding:beforeCast(owner, intensity) Tree.audio:play(Tree.assets.files.audio.sounds.meow) end +local aversionToDeath = effect.new { + tag = "dev_aversion_to_death" +} + +function aversionToDeath:beforeDamage(owner, intensity, damage) + local stats = owner:has(Tree.behaviors.stats) + local effects = owner:has(Tree.behaviors.effects) + if not stats or not effects then return end + if stats.hp <= damage then + effects:deleteStacks(self, 1) + -- тут должен быть какой-нибудь классный спецэффект, но я не умею в шейдеры + return task.wait({}), stats.hp - 1 + end +end + local effectbook = { - bleeding = bleeding + bleeding = bleeding, + aversionToDeath = aversionToDeath } --- не уверен зачем нам это, но вай нот ай саппоуз diff --git a/lib/spell/effect.lua b/lib/spell/effect.lua index 190ec15..b8304cd 100644 --- a/lib/spell/effect.lua +++ b/lib/spell/effect.lua @@ -6,9 +6,9 @@ local effect = {} effect.__index = effect --- Предполагается, что в каждую функцию будет передаваться `Character` и параметр `intensity`, который отвечает за силу спелла ---- @alias EffectFunc fun(owner: Character, intensity: integer): Task|nil ---- @alias EffectDamageFunc fun(owner: Character, intensity: integer, damage: integer): Task|nil ---- @alias EffectRegenFunc fun(owner: Character, intensity: integer, amountHp: integer): Task|nil +--- @alias EffectFunc fun(owner: Character, intensity: integer): Task? +--- @alias EffectDamageFunc fun(owner: Character, intensity: integer, damage: integer): Task?, integer? +--- @alias EffectRegenFunc fun(owner: Character, intensity: integer, amountHp: integer): Task?, integer? --- @alias EffectData { tag: string, [string]: EffectFunc|EffectDamageFunc|EffectRegenFunc } --- @param owner Character @@ -54,7 +54,7 @@ function effect:afterCast(owner, intensity) end --- @param owner Character --- @param intensity integer --- @param damage integer ---- @return Task|nil +--- @return Task|nil, integer? function effect:beforeAttack(owner, intensity, damage) end --- @param owner Character @@ -65,7 +65,7 @@ function effect:afterAttack(owner, intensity) end --- @param owner Character --- @param intensity integer --- @param damage integer ---- @return Task|nil +--- @return Task|nil, integer? function effect:beforeDamage(owner, intensity, damage) end --- @param owner Character @@ -81,7 +81,7 @@ function effect:beforeRegeneration(owner, intensity, amountHp) end --- @param owner Character --- @param intensity integer ---- @return Task|nil +--- @return Task|nil, integer|nil function effect:afterRegeneration(owner, intensity) end --- @param other Effect @@ -150,7 +150,8 @@ local function new(data) function newEffect:beforeAttack(owner, intensity, damage) if not data.beforeAttack then return end - return data.beforeAttack(owner, intensity, damage) + local task, newDamage = data.beforeDamage(owner, intensity, damage) + return task, newDamage end function newEffect:afterAttack(owner, intensity) @@ -160,7 +161,8 @@ local function new(data) function newEffect:beforeDamage(owner, intensity, damage) if not data.beforeDamage then return end - return data.beforeDamage(owner, intensity, damage) + local task, newDamage = data.beforeDamage(owner, intensity, damage) + return task, newDamage end function newEffect:afterDamage(owner, intensity) @@ -170,7 +172,8 @@ local function new(data) function newEffect:beforeRegeneration(owner, intensity, amountHp) if not data.beforeRegeneration then return end - return data.beforeRegeneration(owner, intensity, amountHp) + local task, newAmountHp = data.beforeRegeneration(owner, intensity, amountHp) + return task, newAmountHp end function newEffect:afterRegeneration(owner, intensity) diff --git a/lib/spellbook.lua b/lib/spellbook.lua index e52e553..42af0f8 100644 --- a/lib/spellbook.lua +++ b/lib/spellbook.lua @@ -52,7 +52,8 @@ local regenerateMana = spell.new { end) local sprite = caster:has(Tree.behaviors.sprite) - if not sprite then return end + local effects = caster:has(Tree.behaviors.effects) + if not sprite or not effects then return end -- и тут возможно на эффекты проверять не стоит print(caster.id, "has regenerated mana and gained initiative") local light = require "lib/character/character".spawn("Light Effect") @@ -67,7 +68,8 @@ local regenerateMana = spell.new { light:die() return task.fromValue() end), - sprite:animate("hurt") + sprite:animate("hurt"), + effects:addEffect(effects.effectbook[2], 1, 1), } end }