local utils = require "lib.utils.utils" local taskUtils = require "lib.utils.task" --- @class Effect --- @field tag string local effect = {} effect.__index = effect --- Предполагается, что в каждую функцию будет передаваться `Character` и параметр `intensity`, который отвечает за силу спелла --- @alias EffectFunc fun(owner: Character, intensity: integer): Task, nil -- бред конечно, но иначе всё в жёлтом --- @alias EffectStatementFunc fun(owner: Character, intensity: integer): Task, boolean --- @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|EffectStatementFunc|EffectDamageFunc|EffectRegenFunc } --- Срабатывает перед применением эффекта --- --- Возвращает, а можно ли применить эффект? --- @param owner Character --- @param intensity integer --- @return Task, boolean function effect:beforeBirth(owner, intensity) return taskUtils.wait {}, true end --- Срабатывает после применения эффекта --- @param owner Character --- @param intensity integer --- @return Task function effect:afterBirth(owner, intensity) return taskUtils.wait {} end --- Срабатывает перед смертью владельца эффекта --- --- Возвращает, умирает ли персонаж? --- @param owner Character --- @param intensity integer --- @return Task, boolean function effect:beforeDeath(owner, intensity) return taskUtils.wait {}, true end --- Срабатывает после смерти владельца эффекта --- @param owner Character --- @param intensity integer --- @return Task function effect:afterDeath(owner, intensity) return taskUtils.wait {} end --- Срабатывает перед ходом владельца эффекта --- --- Возвращает, будет ли персонаж ходить? --- @param owner Character --- @param intensity integer --- @return Task, boolean function effect:beforeTurn(owner, intensity) return taskUtils.wait {}, true end --- Срабатывает после хода владельца эффекта --- @param owner Character --- @param intensity integer --- @return Task function effect:afterTurn(owner, intensity) return taskUtils.wait {} end --- Срабатывает перед кастом заклинания владельцем эффекта --- --- Возвращает, произойдёт ли каст? --- @param owner Character --- @param intensity integer --- @return Task, boolean function effect:beforeCast(owner, intensity) return taskUtils.wait {}, true end --- Срабатывает после каста заклинания владельцем эффекта --- @param owner Character --- @param intensity integer --- @return Task function effect:afterCast(owner, intensity) return taskUtils.wait {} end --- Срабатывает перед нанесением урона владельцем эффекта --- --- Возвращает урон, который собираются нанести --- @param owner Character --- @param intensity integer --- @param damage integer --- @return Task, integer function effect:beforeAttack(owner, intensity, damage) return taskUtils.wait {}, damage end --- Срабатывает после нанесения урона владельцем эффекта --- @param owner Character --- @param intensity integer --- @return Task function effect:afterAttack(owner, intensity) return taskUtils.wait {} end --- Срабатывает перед получением урона владельцем эффекта --- --- Возвращает урон, который должны получить --- @param owner Character --- @param intensity integer --- @param damage integer --- @return Task, integer function effect:beforeDamage(owner, intensity, damage) return taskUtils.wait {}, damage end --- Срабатывает после получения урона владельцем эффекта --- @param owner Character --- @param intensity integer --- @return Task function effect:afterDamage(owner, intensity) return taskUtils.wait {} end --- Срабатывает перед регенерацией здоровья владельцем эффекта --- --- Возвращает количество здоровья, которое должно быть восстановлено --- @param owner Character --- @param intensity integer --- @param amountHp integer кол-во хп для регена --- @return Task, integer function effect:beforeRegeneration(owner, intensity, amountHp) return taskUtils.wait {}, amountHp end --- Срабатывает после регенерации здоровья владельцем эффекта --- @param owner Character --- @param intensity integer --- @return Task function effect:afterRegeneration(owner, intensity) return taskUtils.wait {} end --- @param other Effect --- @return Effect|nil function effect:sum(other) end function effect:update(dt) end function effect:draw() end --- дип сравнение эффектов --- @param other Effect --- @return boolean function effect:__eq(other) return utils.deepComprasion(self, other) end --- @param data EffectData --- @return Effect local function new(data) local newEffect = setmetatable({ tag = data.tag }, effect) function newEffect:beforeBirth(owner, intensity) if not data.beforeBirth then return end local task, statement = data.beforeBirth(owner, intensity) return task, statement end function newEffect:afterBirth(owner, intensity) if not data.afterBirth then return end return data.afterBirth(owner, intensity) end function newEffect:beforeDeath(owner, intensity) if not data.beforeDeath then return end local task, statement = data.beforeBirth(owner, intensity) return task, statement end function newEffect:afterDeath(owner, intensity) if not data.afterDeath then return end return data.afterDeath(owner, intensity) end function newEffect:beforeTurn(owner, intensity) if not data.beforeTurn then return end local task, statement = data.beforeBirth(owner, intensity) return task, statement end function newEffect:afterTurn(owner, intensity) if not data.afterTurn then return end return data.afterTurn(owner, intensity) end function newEffect:beforeCast(owner, intensity) if not data.beforeCast then return end local task, statement = data.beforeBirth(owner, intensity) return task, statement end function newEffect:afterCast(owner, intensity) if not data.afterCast then return end return data.afterCast(owner, intensity) end function newEffect:beforeAttack(owner, intensity, damage) if not data.beforeAttack then return end local task, newDamage = data.beforeDamage(owner, intensity, damage) return task, newDamage end function newEffect:afterAttack(owner, intensity) if not data.afterAttack then return end return data.afterAttack(owner, intensity) end function newEffect:beforeDamage(owner, intensity, damage) if not data.beforeDamage then return end local task, newDamage = data.beforeDamage(owner, intensity, damage) return task, newDamage end function newEffect:afterDamage(owner, intensity) if not data.afterDamage then return end return data.afterDamage(owner, intensity) end function newEffect:beforeRegeneration(owner, intensity, amountHp) if not data.beforeRegeneration then return end local task, newAmountHp = data.beforeRegeneration(owner, intensity, amountHp) return task, newAmountHp end function newEffect:afterRegeneration(owner, intensity) if not data.afterRegeneration then return end return data.afterRegeneration(owner, intensity) end --- дип сравнение эффектов --- @param other Effect --- @return boolean function newEffect:__eq(other) return utils.deepComparison(self, other) end return newEffect end return { new = new }