198 lines
7.0 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local task = require "lib.utils.task"
local efb = require "lib.effectbook"
--- ===========ЛОГИКА ЭФФЕКТОВ И ЧТО С ЭТИМ ЕДЯТ===========
--- читать здесь: https://docs.google.com/document/d/1Hxa5dOLaeRpLQOs5H-oIDDuLLhKbDw40lR9d62Zb4Tg/edit?usp=sharing
--- и здесь: https://docs.google.com/document/d/1jvhuM3mxqYSQTEM8m-WL-uUSie9QRsZOCCUEiw9ZqzM/edit?tab=t.0
--- behavior thats holds all effects that we applied
--- @class EffectsBehavior : Behavior
--- @field effectsPriority Effect[] хранит эффекты в порядке их применения
--- @field effectsProperties table<Effect, { stacks: integer, intensity: integer }> хранит характеристики эффектов
--- @field effectbook Effect[] все возможные эффекты (хз надо ли так вообще)
local behavior = {}
behavior.__index = behavior
behavior.id = "effects"
--- @return EffectsBehavior
function behavior.new()
return setmetatable({
effectbook = efb.of { efb.bleeding, efb.aversionToDeath },
effectsPriority = {},
effectsProperties = {},
}, behavior)
end
--- проверяет, можно ли наложить эффект и при наложении его применяет
--- @param effect Effect
--- @param stacks integer
function behavior:addEffect(effect, stacks, intensity)
local task1, birthStatement = effect:beforeBirth(self.owner, intensity)
if task1 then
task1(function() end)
end
if not birthStatement then return end
-- проверяем эффект на возможности суммирования (aka противоречия)
for i, ef in ipairs(self.effectsPriority) do
if ef == effect then
self.effectsProperties[ef] = {
stacks = stacks + self.effectsProperties[ef].stacks,
intensity = intensity
}
local task2 = effect:afterBirth(self.owner, intensity)
if task2 then
task2(function() end)
end
return
end
if effect.tag == ef.tag then break end
for k, v in pairs(efb.sums) do
if k[effect.tag] and k[ef.tag] then
if not v(self.owner, effect, ef) then return end
end
end
end
self.effectsPriority[#self.effectsPriority + 1] = effect
self.effectsProperties[effect] = {
stacks = stacks,
intensity = intensity
}
local task3 = effect:afterBirth(self.owner, intensity)
if task3 then
task3(function()
print("[Effects]: мы применили эффект!!")
end)
end
end
--- Удаляет один эффект по порядку
--- @param effect Effect
function behavior:deleteEffect(effect)
self.effectsProperties[effect] = nil
for i, ef in ipairs(self.effectsPriority) do
if ef == effect then
table.remove(self.effectsPriority, i)
return
end
end
end
--- О ДААА ЭТА ФУНКЦИЯ МЕНЯЕТ СОСТОЯНИЕ О ДАААААА О ДАААААААААА
--- @param effect Effect
--- @param amount integer
function behavior:deleteStacks(effect, amount)
print("[Effects]: удаляем стаки!!")
self.effectsProperties[effect].stacks = self.effectsProperties[effect].stacks -
amount -- !!!!!!!!!!!!!!!! <<<<< 21+ only
if self.effectsProperties[effect].stacks <= 0 then
print("[Effects]:", effect.tag, "ДОЛЖЕН БЫТЬ СТЁРТ")
self:deleteEffect(effect)
print("[Effects]:", effect.tag, "СТЁРТ")
end
end
--- должна вызываться перед смертью персонажа;
---
--- возвращает, убивать ли персонажа
--- @return boolean
function behavior:beforeDeath()
for i, ef in ipairs(self.effectsPriority) do
local task1, deathStatement = ef:beforeDeath(self.owner, self.effectsProperties[ef].intensity)
if task1 then
task1(function() end)
end
if deathStatement == false then return false end
end
return true
end
--- должна вызываться после смерти персонажа (может ли такая ситуация возникнуть вообще?)
function behavior:afterDeath()
for i, ef in ipairs(self.effectsPriority) do
local task1 = ef:afterDeath(self.owner, self.effectsProperties[ef].intensity)
if task1 then
task1(function() end)
end
end
end
--- должен вызываться в начале хода
---
--- возвращает, может ли персонаж сделать ход?
--- @return boolean
function behavior:beforeTurn()
for i, ef in ipairs(self.effectsPriority) do
local task1, turnStatement = ef:beforeTurn(self.owner, self.effectsProperties[ef].intensity)
if task1 then
task1(function() end)
end
if turnStatement == false then return false end
end
return true
end
--- должен вызываться в конце хода
function behavior:afterTurn()
for i, ef in pairs(self.effectsPriority) do
local task1 = ef:afterTurn(self.owner, self.effectsProperties[ef].intensity)
if task1 then
task1(function() end)
end
end
end
--- должен вызываться перед кастом спелла
---
--- возвращает, может ли персонаж скастовать спелл?
--- @return boolean
function behavior:beforeCast()
for i, ef in ipairs(self.effectsPriority) do
local task1, castStatement = ef:beforeCast(self.owner, self.effectsProperties[ef].intensity)
if task1 then
task1(function() end)
end
if castStatement == false then return false end
end
return true
end
--- должен вызываться после каста спелла
function behavior:afterCast()
for i, ef in pairs(self.effectsPriority) do
local task1 = ef:afterCast(self.owner, self.effectsProperties[ef].intensity)
if task1 then
task1(function() end)
end
end
end
--- должен вызываться перед получением урона
---
--- возвращает получаемый урон
--- @return integer
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