feature/effects #37
@ -29,6 +29,14 @@ function behavior:addEffect(effect, stacks)
|
|||||||
-- if not effect:beforeBirth() then return end
|
-- if not effect:beforeBirth() then return end
|
||||||
-- проверяем эффект на возможности суммирования (aka противоречия)
|
-- проверяем эффект на возможности суммирования (aka противоречия)
|
||||||
for i, ef in ipairs(self.effectsPriority) do
|
for i, ef in ipairs(self.effectsPriority) do
|
||||||
|
if ef == effect then
|
||||||
|
self.effectsStacks[ef] = stacks
|
||||||
|
local task1 = effect:afterBirth(self.owner)
|
||||||
|
if task1 then
|
||||||
|
task1(function() end)
|
||||||
|
end
|
||||||
|
|
|||||||
|
return
|
||||||
|
end
|
||||||
local effectSum = effect:sum(ef)
|
local effectSum = effect:sum(ef)
|
||||||
if effectSum then
|
if effectSum then
|
||||||
-- применяем результат суммы и удаляем эффект
|
-- применяем результат суммы и удаляем эффект
|
||||||
@ -39,7 +47,10 @@ function behavior:addEffect(effect, stacks)
|
|||||||
self.effectsPriority[#self.effectsPriority + 1] = effect
|
self.effectsPriority[#self.effectsPriority + 1] = effect
|
||||||
self.effectsStacks[effect] = stacks
|
self.effectsStacks[effect] = stacks
|
||||||
print("[Effects]: мы применили эффект!!")
|
print("[Effects]: мы применили эффект!!")
|
||||||
effect:afterBirth(self.owner)
|
local task1 = effect:afterBirth(self.owner)
|
||||||
|
if task1 then
|
||||||
|
task1(function() end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- должен вызываться в начале хода
|
--- должен вызываться в начале хода
|
||||||
@ -52,6 +63,24 @@ function behavior:beforeTurn()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- О ДААА ЭТА ФУНКЦИЯ МЕНЯЕТ СОСТОЯНИЕ О ДАААААА О ДАААААААААА
|
||||||
|
--- @param effect Effect
|
||||||
|
--- @param amount integer
|
||||||
|
function behavior:deleteStacks(effect, amount)
|
||||||
|
print("[Effects]: удаляем стаки!!")
|
||||||
|
self.effectsStacks[effect] = self.effectsStacks[effect] - amount -- !!!!!!!!!!!!!!!! <<<<< 21+ only
|
||||||
|
if self.effectsStacks[effect] <= 0 then
|
||||||
|
print("[Effects]:", effect.tag, "ДОЛЖЕН БЫТЬ СТЁРТ")
|
||||||
|
self.effectsStacks[effect] = nil
|
||||||
|
for i, ef in ipairs(self.effectsPriority) do
|
||||||
|
PeaAshMeter
commented
ладно, это ужас, но не ужас-ужас ладно, это ужас, но не ужас-ужас
neckrat
commented
по академически я должен был написать линейный поиск через цикл while, но я необучаемое быдло 🤡 по академически я должен был написать линейный поиск через цикл while, но я необучаемое быдло 🤡
PeaAshMeter
commented
академически у тебя не должно быть линейных поисков вообще, в этом-то и суть академически у тебя не должно быть линейных поисков вообще, в этом-то и суть
PeaAshMeter
commented
а у тебя получается внутри линейного а у тебя получается внутри линейного `for i, ef in ipairs` линейный `table.remove`. Это не ужас-ужас, потому что ты гарантируешь срабатывание `table.remove` не более одного раза
neckrat
commented
этот моментик я бы тоже переписал этот моментик я бы тоже переписал
PeaAshMeter
commented
типа красиво-алгоритмически - это все на тегах и все за O(1), кроме последовательного срабатывания всех эффектов (очевидно) типа красиво-алгоритмически - это все на тегах и все за O(1), **кроме** последовательного срабатывания всех эффектов (очевидно)
neckrat
commented
думаю, хотя бы для этого система тэгов не пригодится (надеюсь) думаю, хотя бы для этого система тэгов не пригодится (надеюсь)
PeaAshMeter
commented
ну если я правильно собираю в голове ход мыслей, то нужны адекватные теги (уникальные; один тег к одному эффекту), и отдельно группы тегов (один ко многим). Например, чтобы объединить 15 версий невидимости в одну группу "невидимость" и не давать выбрать таких персонажей в таргет ну если я правильно собираю в голове ход мыслей, то нужны адекватные теги (уникальные; один тег к одному эффекту), и отдельно группы тегов (один ко многим). Например, чтобы объединить 15 версий невидимости в одну группу "невидимость" и не давать выбрать таких персонажей в таргет
PeaAshMeter
commented
это переусложнение, которое уже ближе к реальному геймдизайну, где, как обычно, боссы могут иметь немного другие версии тех же самых эффектов это переусложнение, которое уже ближе к реальному геймдизайну, где, как обычно, боссы могут иметь немного другие версии тех же самых эффектов
neckrat
commented
нам же эти же тэги пригодятся для спеллов в конце концов, для их систематизации нам же эти же тэги пригодятся для спеллов в конце концов, для их систематизации
PeaAshMeter
commented
не вижу необходимости иметь одну общую систему тегов для спеллов и для эффектов не вижу необходимости иметь одну общую систему тегов для спеллов и для эффектов
neckrat
commented
не думаю, что это такое уж переусложнение, мы же не только ради эффектов это делаем в конце концов не думаю, что это такое уж переусложнение, мы же не только ради эффектов это делаем в конце концов
PeaAshMeter
commented
типа можно, но пока не знаю, зачем > не вижу необходимости иметь одну общую систему тегов для спеллов и для эффектов
типа можно, но пока не знаю, зачем
neckrat
commented
вай нот? dry и всё такое
вай нот? dry и всё такое
> не вижу необходимости иметь одну общую систему тегов для спеллов и для эффектов
PeaAshMeter
commented
тогда будет нейминг "spell_myspell" и "effect_myeffect" тогда будет нейминг "spell_myspell" и "effect_myeffect"
PeaAshMeter
commented
так-то у нас не стоит задача по тегу понимать еще и тип объекта, у нас для этого инструменты языка есть, не на бейсике пишем так-то у нас не стоит задача по тегу понимать еще и тип объекта, у нас для этого инструменты языка есть, не на бейсике пишем
neckrat
commented
справедливо справедливо
PeaAshMeter
commented
фактически у нас как будто есть таблицы в реляционной СУБД Microsoft Access: spells и effects. фактически у нас как будто есть таблицы в реляционной СУБД Microsoft Access: spells и effects.
мы и так понимаем, что это разные таблицы. В рамках разных таблиц айдишники не обязаны быть уникальными
PeaAshMeter
commented
типа другое дело что у нас у characters айдишники номерные, а у статических данных - строковые. Но это по историческим причинам и потому что, как бы, статические данные типа спеллов и эффектов мы как раз хотим находить по удобному идентификатору, а динамические типа персонажей - не хотим типа другое дело что у нас у characters айдишники номерные, а у статических данных - строковые. Но это по историческим причинам и потому что, как бы, статические данные типа спеллов и эффектов мы как раз хотим находить по удобному идентификатору, а динамические типа персонажей - не хотим
neckrat
commented
ну да, да, очевидно ну да, да, очевидно
neckrat
commented
у нас персонажи вообще в роли энтити, там со строковыми тэгами не выйдет у нас персонажи вообще в роли энтити, там со строковыми тэгами не выйдет
PeaAshMeter
commented
короче нормальная архитектура вроде короче нормальная архитектура вроде
|
|||||||
|
if ef == effect then
|
||||||
|
table.remove(self.effectsPriority, i)
|
||||||
|
print("[Effects]:", effect.tag, "СТЁРТ")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- должен вызываться в конце хода
|
--- должен вызываться в конце хода
|
||||||
function behavior:afterTurn()
|
function behavior:afterTurn()
|
||||||
for i, ef in pairs(self.effectsPriority) do
|
for i, ef in pairs(self.effectsPriority) do
|
||||||
|
|||||||
@ -4,29 +4,37 @@ local easing = require "lib.utils.easing"
|
|||||||
|
|
||||||
local bleeding = effect.new({
|
local bleeding = effect.new({
|
||||||
tag = "bleeding",
|
tag = "bleeding",
|
||||||
beforeTurn = function(owner)
|
|
||||||
print("мы начали применять блидинг!!", owner)
|
|
||||||
local stats = owner:has(Tree.behaviors.stats)
|
|
||||||
local sprite = owner:has(Tree.behaviors.sprite)
|
|
||||||
if not stats or not sprite then return end
|
|
||||||
stats:dealDamage(2)
|
|
||||||
return task.wait({ sprite:animate("hurt") })
|
|
||||||
end,
|
|
||||||
afterBirth = function(owner)
|
afterBirth = function(owner)
|
||||||
local light = require "lib/character/character".spawn("Light Effect")
|
local light = require "lib/character/character".spawn("Bleeding Light Effect")
|
||||||
light:addBehavior {
|
light:addBehavior {
|
||||||
Tree.behaviors.light.new { color = Vec3 { 1, 0., 0. }, intensity = 4 },
|
Tree.behaviors.light.new { color = Vec3 { 1, 0., 0. }, intensity = 4 },
|
||||||
Tree.behaviors.positioned.new(owner:has(Tree.behaviors.positioned).position + Vec3 { 0.5, 0.5 }),
|
Tree.behaviors.positioned.new(owner:has(Tree.behaviors.positioned).position + Vec3 { 0.5, 0.5 }),
|
||||||
}
|
}
|
||||||
|
|
||||||
return task.wait({ task.chain(task.tween(light:has(Tree.behaviors.light) --[[@as LightBehavior]],
|
return task.wait({ task.chain(task.tween(light:has(Tree.behaviors.light) --[[@as LightBehavior]],
|
||||||
{ intensity = 1, color = Vec3 { 1, 0., 0. } }, 800, easing.easeInCubic), function()
|
{ intensity = 1, color = Vec3 { 0, 0., 0. } }, 800, easing.easeInCubic), function()
|
||||||
light:die()
|
light:die()
|
||||||
return task.fromValue()
|
return task.fromValue()
|
||||||
end) })
|
end) })
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function bleeding:beforeTurn(owner)
|
||||||
|
local stats = owner:has(Tree.behaviors.stats)
|
||||||
|
local sprite = owner:has(Tree.behaviors.sprite)
|
||||||
|
if not stats or not sprite then return end
|
||||||
|
stats:dealDamage(2)
|
||||||
|
return task.wait({ sprite:animate("hurt") })
|
||||||
|
end
|
||||||
|
|
||||||
|
function bleeding:afterTurn(owner)
|
||||||
|
local behavior = owner:has(Tree.behaviors.effects)
|
||||||
|
if not behavior then
|
||||||
|
print('[Effect]: yo man what the hell wheres your behavior how thats possible please stop thats not normal')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
behavior:deleteStacks(self, 1)
|
||||||
|
end
|
||||||
|
|
||||||
local effectbook = {
|
local effectbook = {
|
||||||
bleeding = bleeding
|
bleeding = bleeding
|
||||||
|
|||||||
@ -73,6 +73,9 @@ function turnOrder:endRound()
|
|||||||
char:try(Tree.behaviors.spellcaster, function(spellcaster)
|
char:try(Tree.behaviors.spellcaster, function(spellcaster)
|
||||||
spellcaster:processCooldowns()
|
spellcaster:processCooldowns()
|
||||||
end)
|
end)
|
||||||
|
char:try(Tree.behaviors.effects, function(effects)
|
||||||
|
effects:afterTurn()
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.actedQueue, self.pendingQueue = self.pendingQueue, self.actedQueue
|
self.actedQueue, self.pendingQueue = self.pendingQueue, self.actedQueue
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
local utils = require "lib.utils.utils"
|
||||||
|
|
||||||
--- @class Effect
|
--- @class Effect
|
||||||
|
PeaAshMeter
commented
Почему это вообще в папке со спеллами? Почему это вообще в папке со спеллами?
neckrat
commented
я не придумал куда в другое место это запихать, не в либ же кидать 🥵 я не придумал куда в другое место это запихать, не в либ же кидать 🥵
|
|||||||
--- @field tag string
|
--- @field tag string
|
||||||
local effect = {}
|
local effect = {}
|
||||||
@ -76,6 +78,13 @@ function effect:update(dt) end
|
|||||||
|
|
||||||
function effect:draw() end
|
function effect:draw() end
|
||||||
|
|
||||||
|
--- дип сравнение эффектов
|
||||||
|
--- @param other Effect
|
||||||
|
--- @return boolean
|
||||||
|
function effect:__eq(other)
|
||||||
|
return utils.deepComprasion(self, other)
|
||||||
|
end
|
||||||
|
|
||||||
--- @todo переделать дату и прочее
|
--- @todo переделать дату и прочее
|
||||||
-- --- @param data {tag: string, beforeBirth: fun(owner: Character)?, beforeDeath: fun(owner: Character)?, beforeTurn: (fun(owner: Character): Task<nil>|nil), afterTurn: (fun(owner: Character): Task<nil>|nil), sum: fun(owner: Character)?}
|
-- --- @param data {tag: string, beforeBirth: fun(owner: Character)?, beforeDeath: fun(owner: Character)?, beforeTurn: (fun(owner: Character): Task<nil>|nil), afterTurn: (fun(owner: Character): Task<nil>|nil), sum: fun(owner: Character)?}
|
||||||
--- @param data EffectData
|
--- @param data EffectData
|
||||||
@ -155,6 +164,13 @@ local function new(data)
|
|||||||
return data.afterRegeneration(owner)
|
return data.afterRegeneration(owner)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- дип сравнение эффектов
|
||||||
|
--- @param other Effect
|
||||||
|
--- @return boolean
|
||||||
|
function newEffect:__eq(other)
|
||||||
|
return utils.deepComprasion(self, other)
|
||||||
|
end
|
||||||
|
|
||||||
return newEffect
|
return newEffect
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Всё таки позволяет через наложение сильного короткого эффекта поверх слабого длинного получить и сильный, и длинный эффект одновременно?
да, мы вроде так и договорились по итогу
Так вроде смысл реферата по DOS сводился к тому, что так делать не надо? Мы сделали разные выводы?
Так вроде смысл реферата по DOS сводился к тому, что так делать не надо? Мы сделали разные выводы?
получается, ты сделал
видимо ¯(ツ)/¯, я предположил так сделать из-за всех этих скрытых механик, где ты переопределяешь бесконечный эффект конечным и тд
а поддержка бесконечных эффектов же не присутствует в каком-то дополнительном виде, кроме как не указывать эффекту момент потери стака?
да, можно добавить просто какое-то магическое значение по типу -1 ради ui, ну или сделать флаг для этого