local ____lualib = require("lualib_bundle") 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 ____modifier_general_hunger = require("abilities.modifiers.modifier_general_hunger") local modifier_general_hunger = ____modifier_general_hunger.modifier_general_hunger local ____ability_pudge_flesh_heap_custom = require("abilities.heroes.pudge.ability_pudge_flesh_heap_custom") local modifier_pudge_flesh_heap_custom = ____ability_pudge_flesh_heap_custom.modifier_pudge_flesh_heap_custom ____exports.ability_pudge_dismember_custom = __TS__Class() local ability_pudge_dismember_custom = ____exports.ability_pudge_dismember_custom ability_pudge_dismember_custom.name = "ability_pudge_dismember_custom" ability_pudge_dismember_custom.____file_path = "scripts/vscripts/abilities/heroes/pudge/ability_pudge_dismember_custom.lua" __TS__ClassExtends(ability_pudge_dismember_custom, BaseAbility) function ability_pudge_dismember_custom.prototype.____constructor(self, ...) BaseAbility.prototype.____constructor(self, ...) self.pulseAccumulator = 0 self.channelTargetPoint = Vector(0, 0, 0) end function ability_pudge_dismember_custom.prototype.Precache(self, context) PrecacheResource("particle", "particles/econ/items/pudge/pudge_arcana/pudge_arcana_dismember_default.vpcf", context) end function ability_pudge_dismember_custom.prototype.GetBehavior(self) return bit.bor( bit.bor(DOTA_ABILITY_BEHAVIOR_POINT, DOTA_ABILITY_BEHAVIOR_CHANNELLED), DOTA_ABILITY_BEHAVIOR_AOE ) end function ability_pudge_dismember_custom.prototype.GetCastRange(self, location, target) return self:GetSpecialValueFor("cast_range") end function ability_pudge_dismember_custom.prototype.GetChannelTime(self) return self:GetSpecialValueFor("channel_time") end function ability_pudge_dismember_custom.prototype.GetAOERadius(self) return self:GetSpecialValueFor("width") end function ability_pudge_dismember_custom.prototype.OnSpellStart(self) local caster = self:GetCaster() self.channelTargetPoint = self:GetCursorPosition() self.pulseAccumulator = 0 caster:AddNewModifier( caster, self, ____exports.modifier_pudge_dismember_growth_custom.name, {duration = self:GetChannelTime() + 0.1} ) EmitSoundOn("Hero_Pudge.DismemberSwings", caster) end function ability_pudge_dismember_custom.prototype.OnChannelThink(self, flInterval) if not IsServer() then return end local caster = self:GetCaster() local maxRange = self:GetCastRange( caster:GetAbsOrigin(), nil ) local width = self:GetSpecialValueFor("width") local pullSpeedPerSec = self:GetSpecialValueFor("pull_speed") local pulseInterval = self:GetSpecialValueFor("pulse_interval") local toPoint = self.channelTargetPoint - caster:GetAbsOrigin() toPoint.z = 0 if toPoint:Length2D() < 1 then toPoint = caster:GetForwardVector() * maxRange end local clampedDistance = math.min( toPoint:Length2D(), maxRange ) local centerPoint = caster:GetAbsOrigin() + toPoint:Normalized() * clampedDistance local enemies = FindUnitsInRadius( caster:GetTeamNumber(), centerPoint, nil, width, DOTA_UNIT_TARGET_TEAM_ENEMY, bit.bor(DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_BASIC), DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_ANY_ORDER, false ) if #enemies == 0 then caster:InterruptChannel() return end for ____, enemy in ipairs(enemies) do local delta = centerPoint - enemy:GetAbsOrigin() delta.z = 0 local distance = delta:Length2D() local stopDistance = 60 if distance > stopDistance then local move = math.min(distance - stopDistance, pullSpeedPerSec * flInterval) local newPos = enemy:GetAbsOrigin() + delta:Normalized() * move enemy:SetAbsOrigin(GetGroundPosition(newPos, enemy)) GridNav:DestroyTreesAroundPoint(newPos, 80, false) else FindClearSpaceForUnit( enemy, enemy:GetAbsOrigin(), true ) end end self.pulseAccumulator = self.pulseAccumulator + flInterval if self.pulseAccumulator < pulseInterval then return end self.pulseAccumulator = 0 EmitSoundOn("Hero_Pudge.Dismember", caster) for ____, enemy in ipairs(enemies) do ____exports.modifier_pudge_dismember_custom:apply(enemy, caster, self, {duration = pulseInterval + 0.1}) self:ApplyDismemberTickDamage(caster, enemy) end end function ability_pudge_dismember_custom.prototype.OnChannelFinish(self, interrupted) local caster = self:GetCaster() StopSoundOn("Hero_Pudge.DismemberSwings", caster) local toPoint = self.channelTargetPoint - caster:GetAbsOrigin() toPoint.z = 0 local maxRange = self:GetCastRange( caster:GetAbsOrigin(), nil ) if toPoint:Length2D() < 1 then toPoint = caster:GetForwardVector() * maxRange end local clampedDistance = math.min( toPoint:Length2D(), maxRange ) local centerPoint = caster:GetAbsOrigin() + toPoint:Normalized() * clampedDistance local width = self:GetSpecialValueFor("width") local enemies = FindUnitsInRadius( caster:GetTeamNumber(), centerPoint, nil, width, DOTA_UNIT_TARGET_TEAM_ENEMY, bit.bor(DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_BASIC), DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_ANY_ORDER, false ) for ____, enemy in ipairs(enemies) do FindClearSpaceForUnit( enemy, enemy:GetAbsOrigin(), true ) end end function ability_pudge_dismember_custom.prototype.ApplyDismemberTickDamage(self, caster, target) local interval = self:GetSpecialValueFor("pulse_interval") local baseDamage = self:GetSpecialValueFor("damage_per_second") local strMultiplier = self:GetSpecialValueFor("strength_damage_pct") * 0.01 local maxHpDamagePct = self:GetSpecialValueFor("max_health_damage_pct") * 0.01 local healPct = self:GetSpecialValueFor("heal_from_damage_pct") * 0.01 local maxHpDamagePerSec = caster:GetMaxHealth() * maxHpDamagePct local damagePerSecond = baseDamage + caster:GetStrength() * strMultiplier + maxHpDamagePerSec local tickDamage = damagePerSecond * interval ApplyDamage({ victim = target, attacker = caster, damage = tickDamage, damage_type = DAMAGE_TYPE_MAGICAL, ability = self }) caster:Heal(tickDamage * healPct, self) end ability_pudge_dismember_custom = __TS__Decorate( ability_pudge_dismember_custom, ability_pudge_dismember_custom, {registerAbility(nil)}, {kind = "class", name = "ability_pudge_dismember_custom"} ) ____exports.ability_pudge_dismember_custom = ability_pudge_dismember_custom ____exports.modifier_pudge_dismember_growth_custom = __TS__Class() local modifier_pudge_dismember_growth_custom = ____exports.modifier_pudge_dismember_growth_custom modifier_pudge_dismember_growth_custom.name = "modifier_pudge_dismember_growth_custom" modifier_pudge_dismember_growth_custom.____file_path = "scripts/vscripts/abilities/heroes/pudge/ability_pudge_dismember_custom.lua" __TS__ClassExtends(modifier_pudge_dismember_growth_custom, BaseModifier) function modifier_pudge_dismember_growth_custom.prototype.IsHidden(self) return false end function modifier_pudge_dismember_growth_custom.prototype.IsPurgable(self) return false end function modifier_pudge_dismember_growth_custom.prototype.DeclareFunctions(self) return {MODIFIER_PROPERTY_MODEL_SCALE} end function modifier_pudge_dismember_growth_custom.prototype.GetModifierModelScale(self) local parent = self:GetParent() if not parent then return 0 end return math.min( 100, math.floor(parent:GetMaxHealth() / 120) ) end modifier_pudge_dismember_growth_custom = __TS__Decorate( modifier_pudge_dismember_growth_custom, modifier_pudge_dismember_growth_custom, {registerModifier(nil)}, {kind = "class", name = "modifier_pudge_dismember_growth_custom"} ) ____exports.modifier_pudge_dismember_growth_custom = modifier_pudge_dismember_growth_custom ____exports.modifier_pudge_dismember_custom = __TS__Class() local modifier_pudge_dismember_custom = ____exports.modifier_pudge_dismember_custom modifier_pudge_dismember_custom.name = "modifier_pudge_dismember_custom" modifier_pudge_dismember_custom.____file_path = "scripts/vscripts/abilities/heroes/pudge/ability_pudge_dismember_custom.lua" __TS__ClassExtends(modifier_pudge_dismember_custom, BaseModifier) function modifier_pudge_dismember_custom.prototype.IsDebuff(self) return true end function modifier_pudge_dismember_custom.prototype.IsHidden(self) return false end function modifier_pudge_dismember_custom.prototype.IsPurgable(self) return false end function modifier_pudge_dismember_custom.prototype.GetEffectName(self) return "particles/econ/items/pudge/pudge_arcana/pudge_arcana_dismember_default.vpcf" end function modifier_pudge_dismember_custom.prototype.GetEffectAttachType(self) return PATTACH_OVERHEAD_FOLLOW end function modifier_pudge_dismember_custom.prototype.CheckState(self) return {[MODIFIER_STATE_INVISIBLE] = false} end function modifier_pudge_dismember_custom.prototype.DeclareFunctions(self) return {MODIFIER_PROPERTY_OVERRIDE_ANIMATION, MODIFIER_EVENT_ON_DEATH} end function modifier_pudge_dismember_custom.prototype.GetOverrideAnimation(self) return ACT_DOTA_FLAIL end function modifier_pudge_dismember_custom.prototype.OnDeath(self, event) if not IsServer() then return end local caster = self:GetCaster() local target = self:GetParent() if not caster or not target or not event.unit then return end if event.unit ~= target then return end if target:IsAlive() then return end if target:GetTeamNumber() == caster:GetTeamNumber() then return end if target:IsBuilding() or target:IsOther() or target:IsIllusion() then return end local fleshHeap = caster:FindModifierByName(modifier_pudge_flesh_heap_custom.name) if fleshHeap then fleshHeap:AddHeapStack(1) end local ability = self:GetAbility() if not ability then return end local hungerModifier = caster:AddNewModifier(caster, ability, modifier_general_hunger.name, {}) if not hungerModifier then return end local hungerBonus = math.max( 1, math.floor(ability:GetSpecialValueFor("hunger_bonus")) ) do local i = 0 while i < hungerBonus do hungerModifier:IncrementStackCount() i = i + 1 end end end modifier_pudge_dismember_custom = __TS__Decorate( modifier_pudge_dismember_custom, modifier_pudge_dismember_custom, {registerModifier(nil)}, {kind = "class", name = "modifier_pudge_dismember_custom"} ) ____exports.modifier_pudge_dismember_custom = modifier_pudge_dismember_custom return ____exports