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

338 lines
13 KiB
Lua

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 BaseItem = ____dota_ts_adapter.BaseItem
local BaseModifier = ____dota_ts_adapter.BaseModifier
local registerAbility = ____dota_ts_adapter.registerAbility
local registerModifier = ____dota_ts_adapter.registerModifier
local ____incoming_damage_reduction_combine = require("utils.incoming_damage_reduction_combine")
local removeIncomingDamageReductionSource = ____incoming_damage_reduction_combine.removeIncomingDamageReductionSource
local setIncomingDamageReductionSource = ____incoming_damage_reduction_combine.setIncomingDamageReductionSource
local MJOLNIR_ACTIVE_INCOMING_SOURCE = "modifier_item_mjolnir_active"
____exports.item_mjolnir_custom = __TS__Class()
local item_mjolnir_custom = ____exports.item_mjolnir_custom
item_mjolnir_custom.name = "item_mjolnir_custom"
item_mjolnir_custom.____file_path = "scripts/vscripts/items/default_items/item_mjolnir_custom.lua"
__TS__ClassExtends(item_mjolnir_custom, BaseItem)
function item_mjolnir_custom.prototype.GetIntrinsicModifierName(self)
return "modifier_item_mjolnir_custom"
end
function item_mjolnir_custom.prototype.OnSpellStart(self)
local target = self:GetCursorTarget()
if not target then
return
end
target:EmitSound("DOTA_Item.Mjollnir.Activate")
target:AddNewModifier(
self:GetCaster(),
self,
"modifier_item_mjolnir_active",
{duration = self:GetSpecialValueFor("duration")}
)
end
item_mjolnir_custom = __TS__Decorate(
item_mjolnir_custom,
item_mjolnir_custom,
{registerAbility(nil)},
{kind = "class", name = "item_mjolnir_custom"}
)
____exports.item_mjolnir_custom = item_mjolnir_custom
____exports.modifier_item_mjolnir_active = __TS__Class()
local modifier_item_mjolnir_active = ____exports.modifier_item_mjolnir_active
modifier_item_mjolnir_active.name = "modifier_item_mjolnir_active"
modifier_item_mjolnir_active.____file_path = "scripts/vscripts/items/default_items/item_mjolnir_custom.lua"
__TS__ClassExtends(modifier_item_mjolnir_active, BaseModifier)
function modifier_item_mjolnir_active.prototype.GetEffectName(self)
return "particles/econ/events/ti6/mjollnir_shield_ti6.vpcf"
end
function modifier_item_mjolnir_active.prototype.GetEffectAttachType(self)
return PATTACH_ABSORIGIN_FOLLOW
end
function modifier_item_mjolnir_active.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_DAMAGEOUTGOING_PERCENTAGE}
end
function modifier_item_mjolnir_active.prototype.OnCreated(self)
if not IsServer() then
return
end
setIncomingDamageReductionSource(
nil,
self:GetParent(),
MJOLNIR_ACTIVE_INCOMING_SOURCE,
function()
local ability = self:GetAbility()
if not ability then
return 0
end
return math.max(
0,
ability:GetSpecialValueFor("incoming_pct")
)
end
)
end
function modifier_item_mjolnir_active.prototype.OnDestroy(self)
if not IsServer() then
return
end
removeIncomingDamageReductionSource(
nil,
self:GetParent(),
MJOLNIR_ACTIVE_INCOMING_SOURCE
)
end
function modifier_item_mjolnir_active.prototype.GetModifierDamageOutgoing_Percentage(self, event)
return self:GetAbility():GetSpecialValueFor("outgoing_pct")
end
function modifier_item_mjolnir_active.prototype.GetTexture(self)
return "item_mjollnir"
end
modifier_item_mjolnir_active = __TS__Decorate(
modifier_item_mjolnir_active,
modifier_item_mjolnir_active,
{registerModifier(nil)},
{kind = "class", name = "modifier_item_mjolnir_active"}
)
____exports.modifier_item_mjolnir_active = modifier_item_mjolnir_active
____exports.modifier_item_mjolnir_custom = __TS__Class()
local modifier_item_mjolnir_custom = ____exports.modifier_item_mjolnir_custom
modifier_item_mjolnir_custom.name = "modifier_item_mjolnir_custom"
modifier_item_mjolnir_custom.____file_path = "scripts/vscripts/items/default_items/item_mjolnir_custom.lua"
__TS__ClassExtends(modifier_item_mjolnir_custom, BaseModifier)
function modifier_item_mjolnir_custom.prototype.____constructor(self, ...)
BaseModifier.prototype.____constructor(self, ...)
self.bonus_damage = 0
self.bonus_attack_speed = 0
self.chain_chance = 0
self.chain_cooldown = 0
self.bChainCooldown = false
end
function modifier_item_mjolnir_custom.prototype.IsHidden(self)
return true
end
function modifier_item_mjolnir_custom.prototype.IsPurgable(self)
return false
end
function modifier_item_mjolnir_custom.prototype.RemoveOnDeath(self)
return false
end
function modifier_item_mjolnir_custom.prototype.GetAttributes(self)
return MODIFIER_ATTRIBUTE_MULTIPLE
end
function modifier_item_mjolnir_custom.prototype.OnCreated(self, params)
if IsServer() then
if not self:GetAbility() then
self:Destroy()
return
end
end
local ability = self:GetAbility()
if ability then
self.bonus_damage = ability:GetSpecialValueFor("bonus_damage")
self.bonus_attack_speed = ability:GetSpecialValueFor("bonus_attack_speed")
self.chain_chance = ability:GetSpecialValueFor("chain_chance")
self.chain_cooldown = ability:GetSpecialValueFor("chain_cooldown")
else
self.bonus_damage = 0
self.bonus_attack_speed = 0
self.chain_chance = 0
self.chain_cooldown = 0
end
self.bChainCooldown = false
end
function modifier_item_mjolnir_custom.prototype.OnIntervalThink(self)
self.bChainCooldown = false
self:StartIntervalThink(-1)
end
function modifier_item_mjolnir_custom.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE, MODIFIER_PROPERTY_ATTACKSPEED_BONUS_CONSTANT, MODIFIER_EVENT_ON_ATTACK_LANDED, MODIFIER_EVENT_ON_ORDER}
end
function modifier_item_mjolnir_custom.prototype.GetModifierPreAttack_BonusDamage(self)
return self.bonus_damage
end
function modifier_item_mjolnir_custom.prototype.GetModifierAttackSpeedBonus_Constant(self)
return self.bonus_attack_speed
end
function modifier_item_mjolnir_custom.prototype.OnAttackLanded(self, event)
if IsServer() and event.attacker == self:GetParent() and self:GetParent():IsAlive() and not self.bChainCooldown and not self:GetParent():IsIllusion() and not event.target:IsMagicImmune() and not event.target:IsBuilding() and not event.target:IsOther() and self:GetParent():GetTeamNumber() ~= event.target:GetTeamNumber() and RollPseudoRandomPercentage(
self.chain_chance,
4,
self:GetParent()
) then
self:GetParent():EmitSound("Item.Maelstrom.Chain_Lightning")
self:GetParent():AddNewModifier(
self:GetCaster(),
self:GetAbility(),
"modifier_chain_lightning",
{starting_unit_entindex = event.target:entindex()}
)
self.bChainCooldown = true
self:StartIntervalThink(self.chain_cooldown)
end
end
modifier_item_mjolnir_custom = __TS__Decorate(
modifier_item_mjolnir_custom,
modifier_item_mjolnir_custom,
{registerModifier(nil)},
{kind = "class", name = "modifier_item_mjolnir_custom"}
)
____exports.modifier_item_mjolnir_custom = modifier_item_mjolnir_custom
____exports.modifier_chain_lightning = __TS__Class()
local modifier_chain_lightning = ____exports.modifier_chain_lightning
modifier_chain_lightning.name = "modifier_chain_lightning"
modifier_chain_lightning.____file_path = "scripts/vscripts/items/default_items/item_mjolnir_custom.lua"
__TS__ClassExtends(modifier_chain_lightning, BaseModifier)
function modifier_chain_lightning.prototype.____constructor(self, ...)
BaseModifier.prototype.____constructor(self, ...)
self.bonus_damage = 0
self.chain_damage = 0
self.chain_damage_self = 0
self.chain_strikes = 0
self.chain_radius = 0
self.chain_delay = 0
self.units_affected = {}
self.unit_counter = 0
self.zapped = false
end
function modifier_chain_lightning.prototype.IsHidden(self)
return true
end
function modifier_chain_lightning.prototype.IsDebuff(self)
return false
end
function modifier_chain_lightning.prototype.IsPurgable(self)
return false
end
function modifier_chain_lightning.prototype.RemoveOnDeath(self)
return false
end
function modifier_chain_lightning.prototype.GetAttributes(self)
return MODIFIER_ATTRIBUTE_MULTIPLE
end
function modifier_chain_lightning.prototype.OnCreated(self, params)
if IsServer() then
if not self:GetAbility() then
self:Destroy()
return
end
end
if not IsServer() then
return
end
local ability = self:GetAbility()
if ability then
self.bonus_damage = ability:GetSpecialValueFor("bonus_damage")
self.chain_damage = ability:GetSpecialValueFor("chain_damage")
self.chain_damage_self = ability:GetSpecialValueFor("chain_damage_self")
self.chain_strikes = ability:GetSpecialValueFor("chain_strikes")
self.chain_radius = ability:GetSpecialValueFor("chain_radius")
self.chain_delay = ability:GetSpecialValueFor("chain_delay")
end
self.starting_unit_entindex = params.starting_unit_entindex
if self.starting_unit_entindex then
local unit = EntIndexToHScript(self.starting_unit_entindex)
if unit and unit:IsBaseNPC() then
self.current_unit = unit
else
self:Destroy()
return
end
else
self:Destroy()
return
end
self.units_affected = {}
self.unit_counter = 0
self:OnIntervalThink()
self:StartIntervalThink(self.chain_delay)
end
function modifier_chain_lightning.prototype.OnIntervalThink(self)
self.zapped = false
local caster = self:GetCaster()
if not self.current_unit or not caster then
return
end
local enemies = FindUnitsInRadius(
caster:GetTeamNumber(),
self.current_unit:GetAbsOrigin(),
nil,
self.chain_radius,
DOTA_UNIT_TARGET_TEAM_ENEMY,
DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
DOTA_UNIT_TARGET_FLAG_FOW_VISIBLE + DOTA_UNIT_TARGET_FLAG_NO_INVIS,
FIND_CLOSEST,
false
)
for ____, enemy in ipairs(enemies) do
if not self.units_affected[enemy:entindex()] then
enemy:EmitSound("Item.Maelstrom.Chain_Lightning.Jump")
local zap_particle = ParticleManager:CreateParticle("particles/items_fx/chain_lightning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self.current_unit)
if self.unit_counter == 0 then
ParticleManager:SetParticleControlEnt(
zap_particle,
0,
self:GetParent(),
PATTACH_POINT_FOLLOW,
"attach_hitloc",
self:GetParent():GetAbsOrigin(),
true
)
else
ParticleManager:SetParticleControlEnt(
zap_particle,
0,
self.current_unit,
PATTACH_POINT_FOLLOW,
"attach_hitloc",
self.current_unit:GetAbsOrigin(),
true
)
end
ParticleManager:SetParticleControlEnt(
zap_particle,
1,
enemy,
PATTACH_POINT_FOLLOW,
"attach_hitloc",
enemy:GetAbsOrigin(),
true
)
ParticleManager:SetParticleControl(
zap_particle,
2,
Vector(1, 1, 1)
)
ParticleManager:ReleaseParticleIndex(zap_particle)
self.unit_counter = self.unit_counter + 1
self.current_unit = enemy
self.units_affected[self.current_unit:entindex()] = true
self.zapped = true
local damage = caster:GetAverageTrueAttackDamage(caster) * (self.chain_damage_self / 100) + self.chain_damage
ApplyDamage({
victim = enemy,
damage = damage,
damage_type = DAMAGE_TYPE_MAGICAL,
damage_flags = DOTA_DAMAGE_FLAG_NONE,
attacker = caster,
ability = self:GetAbility()
})
break
end
end
if self.unit_counter >= self.chain_strikes and self.chain_strikes > 0 or not self.zapped then
self:StartIntervalThink(-1)
self:Destroy()
end
end
modifier_chain_lightning = __TS__Decorate(
modifier_chain_lightning,
modifier_chain_lightning,
{registerModifier(nil)},
{kind = "class", name = "modifier_chain_lightning"}
)
____exports.modifier_chain_lightning = modifier_chain_lightning
return ____exports