263 lines
10 KiB
Lua
263 lines
10 KiB
Lua
local ____lualib = require("lualib_bundle")
|
|
local Map = ____lualib.Map
|
|
local __TS__New = ____lualib.__TS__New
|
|
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
|
|
local __TS__Class = ____lualib.__TS__Class
|
|
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
|
local __TS__Decorate = ____lualib.__TS__Decorate
|
|
local ____exports = {}
|
|
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
|
local BaseAbility = ____dota_ts_adapter.BaseAbility
|
|
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
|
local registerAbility = ____dota_ts_adapter.registerAbility
|
|
local registerModifier = ____dota_ts_adapter.registerModifier
|
|
local isApplyingArcaneSupremacyDamage = false
|
|
local pendingDamageMap = __TS__New(Map)
|
|
local AGGREGATE_WINDOW = 0.15
|
|
local function getPendingKey(self, victim, attacker)
|
|
return (tostring(victim:entindex()) .. "_") .. tostring(attacker:entindex())
|
|
end
|
|
local function processArcaneSupremacyDamage(self, pending)
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
local ____pending_0 = pending
|
|
local totalDamage = ____pending_0.totalDamage
|
|
local victim = ____pending_0.victim
|
|
local attacker = ____pending_0.attacker
|
|
local caster = ____pending_0.caster
|
|
local ability = ____pending_0.ability
|
|
if victim:IsNull() or attacker:IsNull() or caster:IsNull() or not ability then
|
|
return
|
|
end
|
|
local radius = ability:GetSpecialValueFor("aura_radius")
|
|
local allEnemies = FindUnitsInRadius(
|
|
caster:GetTeamNumber(),
|
|
caster:GetAbsOrigin(),
|
|
nil,
|
|
radius,
|
|
DOTA_UNIT_TARGET_TEAM_ENEMY,
|
|
bit.bor(DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_BASIC),
|
|
DOTA_UNIT_TARGET_FLAG_NONE,
|
|
FIND_ANY_ORDER,
|
|
false
|
|
)
|
|
local enemies = __TS__ArrayFilter(
|
|
allEnemies,
|
|
function(____, e) return e ~= victim end
|
|
)
|
|
local enemyCount = #enemies
|
|
if enemyCount <= 0 then
|
|
return
|
|
end
|
|
local damagePct = ability:GetSpecialValueFor("damage_pct") * 0.01
|
|
local finalDamage = totalDamage * damagePct / enemyCount
|
|
if finalDamage <= 0 then
|
|
return
|
|
end
|
|
isApplyingArcaneSupremacyDamage = true
|
|
local particleName = "particles/units/heroes/hero_rubick/rubick_finger_of_death_core_cloud.vpcf"
|
|
for ____, enemy in ipairs(enemies) do
|
|
do
|
|
if not enemy or enemy:IsNull() or not enemy:IsAlive() then
|
|
goto __continue9
|
|
end
|
|
local particle = ParticleManager:CreateParticle(particleName, PATTACH_ABSORIGIN_FOLLOW, enemy)
|
|
ParticleManager:ReleaseParticleIndex(particle)
|
|
SendOverheadEventMessage(
|
|
nil,
|
|
OVERHEAD_ALERT_BONUS_SPELL_DAMAGE,
|
|
enemy,
|
|
finalDamage,
|
|
nil
|
|
)
|
|
ApplyDamage({
|
|
victim = enemy,
|
|
attacker = attacker,
|
|
damage = finalDamage,
|
|
damage_type = DAMAGE_TYPE_MAGICAL,
|
|
damage_flags = DOTA_DAMAGE_FLAG_NO_SPELL_AMPLIFICATION,
|
|
ability = ability
|
|
})
|
|
end
|
|
::__continue9::
|
|
end
|
|
Timers:CreateTimer(
|
|
0.034,
|
|
function()
|
|
isApplyingArcaneSupremacyDamage = false
|
|
return nil
|
|
end
|
|
)
|
|
end
|
|
____exports.ability_rubick_arcane_supremacy = __TS__Class()
|
|
local ability_rubick_arcane_supremacy = ____exports.ability_rubick_arcane_supremacy
|
|
ability_rubick_arcane_supremacy.name = "ability_rubick_arcane_supremacy"
|
|
ability_rubick_arcane_supremacy.____file_path = "scripts/vscripts/abilities/heroes/rubick/ability_rubick_arcane_supremacy.lua"
|
|
__TS__ClassExtends(ability_rubick_arcane_supremacy, BaseAbility)
|
|
function ability_rubick_arcane_supremacy.prototype.GetIntrinsicModifierName(self)
|
|
return ____exports.modifier_rubick_arcane_supremacy_aura.name
|
|
end
|
|
function ability_rubick_arcane_supremacy.prototype.Precache(self, context)
|
|
PrecacheResource("particle", "particles/units/heroes/hero_rubick/rubick_finger_of_death_core_cloud.vpcf", context)
|
|
end
|
|
function ability_rubick_arcane_supremacy.prototype.GetAOERadius(self)
|
|
return self:GetSpecialValueFor("aura_radius")
|
|
end
|
|
ability_rubick_arcane_supremacy = __TS__Decorate(
|
|
ability_rubick_arcane_supremacy,
|
|
ability_rubick_arcane_supremacy,
|
|
{registerAbility(nil)},
|
|
{kind = "class", name = "ability_rubick_arcane_supremacy"}
|
|
)
|
|
____exports.ability_rubick_arcane_supremacy = ability_rubick_arcane_supremacy
|
|
____exports.modifier_rubick_arcane_supremacy_aura = __TS__Class()
|
|
local modifier_rubick_arcane_supremacy_aura = ____exports.modifier_rubick_arcane_supremacy_aura
|
|
modifier_rubick_arcane_supremacy_aura.name = "modifier_rubick_arcane_supremacy_aura"
|
|
modifier_rubick_arcane_supremacy_aura.____file_path = "scripts/vscripts/abilities/heroes/rubick/ability_rubick_arcane_supremacy.lua"
|
|
__TS__ClassExtends(modifier_rubick_arcane_supremacy_aura, BaseModifier)
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.IsHidden(self)
|
|
return true
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.IsPurgable(self)
|
|
return false
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.IsDebuff(self)
|
|
return false
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.RemoveOnDeath(self)
|
|
return true
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.IsAura(self)
|
|
return true
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.GetModifierAura(self)
|
|
return ____exports.modifier_rubick_arcane_supremacy_enemy.name
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.GetAuraRadius(self)
|
|
return self:GetAbility():GetSpecialValueFor("aura_radius")
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.GetAuraDuration(self)
|
|
return 0.5
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.GetAuraSearchTeam(self)
|
|
return DOTA_UNIT_TARGET_TEAM_ENEMY
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.GetAuraSearchType(self)
|
|
return bit.bor(DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_BASIC)
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.GetAuraSearchFlags(self)
|
|
return DOTA_UNIT_TARGET_FLAG_NONE
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.DeclareFunctions(self)
|
|
return {MODIFIER_PROPERTY_SPELL_AMPLIFY_PERCENTAGE}
|
|
end
|
|
function modifier_rubick_arcane_supremacy_aura.prototype.GetModifierSpellAmplify_Percentage(self, event)
|
|
if self:GetParent():PassivesDisabled() then
|
|
return 0
|
|
end
|
|
return self:GetAbility():GetSpecialValueFor("spell_amp") + self:GetAbility():GetSpecialValueFor("spell_amp_pct_lvl") * self:GetCaster():GetLevel()
|
|
end
|
|
modifier_rubick_arcane_supremacy_aura = __TS__Decorate(
|
|
modifier_rubick_arcane_supremacy_aura,
|
|
modifier_rubick_arcane_supremacy_aura,
|
|
{registerModifier(nil)},
|
|
{kind = "class", name = "modifier_rubick_arcane_supremacy_aura"}
|
|
)
|
|
____exports.modifier_rubick_arcane_supremacy_aura = modifier_rubick_arcane_supremacy_aura
|
|
____exports.modifier_rubick_arcane_supremacy_enemy = __TS__Class()
|
|
local modifier_rubick_arcane_supremacy_enemy = ____exports.modifier_rubick_arcane_supremacy_enemy
|
|
modifier_rubick_arcane_supremacy_enemy.name = "modifier_rubick_arcane_supremacy_enemy"
|
|
modifier_rubick_arcane_supremacy_enemy.____file_path = "scripts/vscripts/abilities/heroes/rubick/ability_rubick_arcane_supremacy.lua"
|
|
__TS__ClassExtends(modifier_rubick_arcane_supremacy_enemy, BaseModifier)
|
|
function modifier_rubick_arcane_supremacy_enemy.prototype.IsHidden(self)
|
|
return true
|
|
end
|
|
function modifier_rubick_arcane_supremacy_enemy.prototype.IsPurgable(self)
|
|
return false
|
|
end
|
|
function modifier_rubick_arcane_supremacy_enemy.prototype.IsDebuff(self)
|
|
return true
|
|
end
|
|
function modifier_rubick_arcane_supremacy_enemy.prototype.RemoveOnDeath(self)
|
|
return true
|
|
end
|
|
function modifier_rubick_arcane_supremacy_enemy.prototype.DeclareFunctions(self)
|
|
return {MODIFIER_EVENT_ON_TAKEDAMAGE}
|
|
end
|
|
function modifier_rubick_arcane_supremacy_enemy.prototype.OnTakeDamage(self, event)
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
if isApplyingArcaneSupremacyDamage then
|
|
return
|
|
end
|
|
local victim = event.unit
|
|
local attacker = event.attacker
|
|
local damage = event.damage
|
|
local damageType = event.damage_type
|
|
if not victim or not attacker then
|
|
return
|
|
end
|
|
local caster = self:GetCaster()
|
|
local ability = self:GetAbility()
|
|
if not caster or not ability or caster:IsNull() or ability:IsNull() then
|
|
return
|
|
end
|
|
if damageType ~= DAMAGE_TYPE_MAGICAL then
|
|
return
|
|
end
|
|
if caster:PassivesDisabled() then
|
|
return
|
|
end
|
|
local radius = ability:GetSpecialValueFor("aura_radius")
|
|
local isCaster = attacker == caster
|
|
local dist = (attacker:GetAbsOrigin() - caster:GetAbsOrigin()):Length2D()
|
|
local isAllyInRadius = attacker:GetTeamNumber() == caster:GetTeamNumber() and dist <= radius
|
|
if not isCaster and not isAllyInRadius then
|
|
return
|
|
end
|
|
local key = getPendingKey(nil, victim, attacker)
|
|
local existing = pendingDamageMap:get(key)
|
|
if existing then
|
|
existing.totalDamage = existing.totalDamage + damage
|
|
if not existing.timerScheduled then
|
|
existing.timerScheduled = true
|
|
Timers:CreateTimer(
|
|
AGGREGATE_WINDOW,
|
|
function()
|
|
processArcaneSupremacyDamage(nil, existing)
|
|
pendingDamageMap:delete(key)
|
|
return nil
|
|
end
|
|
)
|
|
end
|
|
return
|
|
end
|
|
local pending = {
|
|
totalDamage = damage,
|
|
victim = victim,
|
|
attacker = attacker,
|
|
caster = caster,
|
|
ability = ability,
|
|
timerScheduled = true
|
|
}
|
|
pendingDamageMap:set(key, pending)
|
|
Timers:CreateTimer(
|
|
AGGREGATE_WINDOW,
|
|
function()
|
|
processArcaneSupremacyDamage(nil, pending)
|
|
pendingDamageMap:delete(key)
|
|
return nil
|
|
end
|
|
)
|
|
end
|
|
modifier_rubick_arcane_supremacy_enemy = __TS__Decorate(
|
|
modifier_rubick_arcane_supremacy_enemy,
|
|
modifier_rubick_arcane_supremacy_enemy,
|
|
{registerModifier(nil)},
|
|
{kind = "class", name = "modifier_rubick_arcane_supremacy_enemy"}
|
|
)
|
|
____exports.modifier_rubick_arcane_supremacy_enemy = modifier_rubick_arcane_supremacy_enemy
|
|
return ____exports
|