Files
Dota-Zombie-Invasion/scripts/vscripts/utils/sync_owner_modifiers_to_summon.lua
T
2026-05-29 15:11:31 +07:00

126 lines
4.9 KiB
Lua

local ____lualib = require("lualib_bundle")
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
local ____exports = {}
--- Модификаторы призыва, которые нельзя снимать при синхронизации.
local SUMMON_ONLY_MODIFIER_NAMES = {modifier_dark_friends = true, modifier_stacking_crit = true}
--- Модификаторы владельца, которые не копируем на призыв.
local OWNER_MODIFIER_SYNC_EXCLUDED = {modifier_dark_friends = true, modifier_dark_friends_create = true}
local function isOwnerModifierEligibleForSummonSync(self, mod)
local name = mod:GetName()
if OWNER_MODIFIER_SYNC_EXCLUDED[name] then
return false
end
if mod.IsDebuff and mod:IsDebuff() then
return false
end
return true
end
local function groupModifiersByName(self, modifiers)
local groups = {}
for ____, mod in ipairs(modifiers) do
local name = mod:GetName()
if not groups[name] then
groups[name] = {}
end
local ____groups_name_0 = groups[name]
____groups_name_0[#____groups_name_0 + 1] = mod
end
return groups
end
local function syncStackingCritState(self, ownerMod, summonMod)
summonMod.critModifiers = ownerMod.critModifiers
local ____summonMod_2 = summonMod
local ____ownerMod_guaranteedCritCount_1 = ownerMod.guaranteedCritCount
if ____ownerMod_guaranteedCritCount_1 == nil then
____ownerMod_guaranteedCritCount_1 = 0
end
____summonMod_2.guaranteedCritCount = ____ownerMod_guaranteedCritCount_1
local ____summonMod_4 = summonMod
local ____ownerMod_guaranteedCritUntilDestroy_3 = ownerMod.guaranteedCritUntilDestroy
if ____ownerMod_guaranteedCritUntilDestroy_3 == nil then
____ownerMod_guaranteedCritUntilDestroy_3 = false
end
____summonMod_4.guaranteedCritUntilDestroy = ____ownerMod_guaranteedCritUntilDestroy_3
end
local function syncModifierInstance(self, ownerMod, summonMod)
local ownerStacks = ownerMod:GetStackCount()
if summonMod:GetStackCount() ~= ownerStacks then
summonMod:SetStackCount(ownerStacks)
end
local ownerDuration = ownerMod:GetDuration()
if ownerDuration > 0 then
local remaining = ownerMod:GetRemainingTime()
if remaining > 0 and math.abs(summonMod:GetRemainingTime() - remaining) > 0.15 then
summonMod:SetDuration(remaining, false)
end
end
if ownerMod:GetName() == "modifier_stacking_crit" then
syncStackingCritState(nil, ownerMod, summonMod)
end
end
--- Копирует все бафф-модификаторы владельца на призыв (стаки, длительность, криты).
function ____exports.syncOwnerModifiersToSummon(self, owner, summon)
if not IsServer() then
return
end
if not owner or not summon or not IsValidEntity(owner) or not IsValidEntity(summon) then
return
end
local ownerEligible = {}
for ____, mod in ipairs(owner:FindAllModifiers()) do
if isOwnerModifierEligibleForSummonSync(nil, mod) then
ownerEligible[#ownerEligible + 1] = mod
end
end
local ownerGroups = groupModifiersByName(nil, ownerEligible)
local summonGroups = groupModifiersByName(
nil,
summon:FindAllModifiers()
)
for name in pairs(summonGroups) do
do
if SUMMON_ONLY_MODIFIER_NAMES[name] then
goto __continue21
end
if not ownerGroups[name] then
for ____, mod in ipairs(summonGroups[name]) do
mod:Destroy()
end
end
end
::__continue21::
end
for name in pairs(ownerGroups) do
local ownerInstances = ownerGroups[name]
local summonInstances = __TS__ArrayFilter(
summon:FindAllModifiers(),
function(____, mod) return mod:GetName() == name end
)
while #summonInstances < #ownerInstances do
local source = ownerInstances[#summonInstances + 1]
local caster = source:GetCaster() or owner
local ability = source:GetAbility() or nil
local duration = source:GetDuration() > 0 and source:GetRemainingTime() or -1
local added = summon:AddNewModifier(caster, ability, name, {duration = duration})
if not added then
break
end
summonInstances[#summonInstances + 1] = added
end
while #summonInstances > #ownerInstances do
local extra = table.remove(summonInstances)
if extra ~= nil then
extra:Destroy()
end
end
do
local i = 0
while i < #ownerInstances do
syncModifierInstance(nil, ownerInstances[i + 1], summonInstances[i + 1])
i = i + 1
end
end
end
end
return ____exports