local impact = require "lib.utils.impact" --- @alias Class "dev_warrior"|"dev_mage" --- @alias Chars "strength"|"intelligence"|"agility"|"stamina"|"lunacy" --- @alias CharsTable table --- @class StatsBehavior : Behavior --- @field hp integer --- @field mana integer --- @field chars { raw: CharsTable, final: CharsTable } по хорошему, мы не должны менять эту таблицу руками, а делать это только через метод `changeChar` --- @field class Class --- @field isInTurnOrder boolean --- @field amIAlive boolean local behavior = {} behavior.__index = behavior behavior.id = "stats" --- план прост, если что-то не так, то мы просто убиваем бехавиор (по крайней мере так должно было быть, но пиаш мне запретил :sob:) function behavior:checkStats() -- if self.hp <= 0 then behavior:die() end if self.hp <= 0 then self.amIAlive = false end end function behavior:maxHealth() return self.chars.final["stamina"] * 2 end --- @param damage integer --- @param impactType ImpactType function behavior:dealDamage(damage, impactType) local damageImpact = impact(damage, impactType) local effects = self.owner:has(Tree.behaviors.effects) if effects then damageImpact = effects:beforeDamage(damageImpact) end self.hp = self.hp - damageImpact.intensity self:checkStats() end --- позволяет изменять значение характеристики персонажа --- --- менять характеристики мы должны с помощью функции, которая возвращает значение на сколько мы должны изменить характеристику --- относительно сырой характеристики, и это значение мы прибавляем к финальным характеристикам --- --- такой системой (вроде как) мы гарантируем, что все операции над статами будут обратимыми --- --- @TODO: возможно в будущем при появлении эвентов в игре, мы должны регать эвент изменения стата --- --- пара примеров: --- --- прибавляем 1 к стату: `behavior:changeChar("strength", function (charAmount) return 1 end)` --- --- отнимаем от стата 50%: `behavior:changeChar("strength", function (charAmount) return -charAmount / 2 end)` --- @param char Chars --- @param func fun(charAmount: integer): integer charAmount здесь это сырое значение характеристики function behavior:changeChar(char, func) self.chars.final[char] = func(self.chars.raw[char]) end --- @param class? Class --- @param rawChars? table --- @param isInTurnOrder? boolean function behavior.new(class, rawChars, isInTurnOrder) --- @type Chars local chars = { raw = {}, final = {} } if not rawChars then chars = { raw = { strength = 10, stamina = 10, intelligence = 10, agility = 10, lunacy = 0 }, final = { strength = 10, stamina = 10, intelligence = 10, agility = 10, lunacy = 0 } } else chars = { raw = { strength = rawChars.strength or 10, stamina = rawChars.stamina or 10, intelligence = rawChars.intelligence or 10, agility = rawChars.agility or 10, lunacy = rawChars.lunacy or 0, }, final = { strength = rawChars.strength or 10, stamina = rawChars.stamina or 10, intelligence = rawChars.intelligence or 10, agility = rawChars.agility or 10, lunacy = rawChars.lunacy or 0, }, } end return setmetatable({ hp = chars.final["stamina"] * 2, mana = 10, -- я полагаю, у всех будет одинаковое кол-во маны (оно же кол-во действий) chars = chars, class = class or "dev_warrior", isInTurnOrder = isInTurnOrder or true, amIAlive = true }, behavior) end return behavior