initial commit
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
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
|
||||
require("utils.store_effects")
|
||||
____exports.ability_effects = __TS__Class()
|
||||
local ability_effects = ____exports.ability_effects
|
||||
ability_effects.name = "ability_effects"
|
||||
ability_effects.____file_path = "scripts/vscripts/abilities/modifiers/ability_effects.lua"
|
||||
__TS__ClassExtends(ability_effects, BaseAbility)
|
||||
function ability_effects.prototype.GetIntrinsicModifierName(self)
|
||||
return "modifier_effect_manager"
|
||||
end
|
||||
function ability_effects.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
ability_effects = __TS__Decorate(
|
||||
ability_effects,
|
||||
ability_effects,
|
||||
{registerAbility(nil)},
|
||||
{kind = "class", name = "ability_effects"}
|
||||
)
|
||||
____exports.ability_effects = ability_effects
|
||||
____exports.modifier_effect_manager = __TS__Class()
|
||||
local modifier_effect_manager = ____exports.modifier_effect_manager
|
||||
modifier_effect_manager.name = "modifier_effect_manager"
|
||||
modifier_effect_manager.____file_path = "scripts/vscripts/abilities/modifiers/ability_effects.lua"
|
||||
__TS__ClassExtends(modifier_effect_manager, BaseModifier)
|
||||
function modifier_effect_manager.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_effect_manager.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_effect_manager.prototype.OnCreated(self, params)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
if not parent or parent:IsNull() or not IsValidEntity(parent) then
|
||||
return
|
||||
end
|
||||
local hero = parent
|
||||
if not hero or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
local wings = GetEffect(nil, hero, "wings")
|
||||
if wings then
|
||||
hero:AddNewModifier(
|
||||
hero,
|
||||
self:GetAbility(),
|
||||
____exports.modifier_effects_wings.name,
|
||||
{}
|
||||
)
|
||||
end
|
||||
local effect = GetEffect(nil, hero, "effect")
|
||||
if effect then
|
||||
hero:AddNewModifier(
|
||||
hero,
|
||||
self:GetAbility(),
|
||||
____exports.modifier_effects_effect.name,
|
||||
{}
|
||||
)
|
||||
end
|
||||
local model = GetEffect(nil, hero, "model")
|
||||
if model then
|
||||
hero:AddNewModifier(
|
||||
hero,
|
||||
self:GetAbility(),
|
||||
____exports.modifier_effects_model.name,
|
||||
{}
|
||||
)
|
||||
end
|
||||
end
|
||||
modifier_effect_manager = __TS__Decorate(
|
||||
modifier_effect_manager,
|
||||
modifier_effect_manager,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_effect_manager"}
|
||||
)
|
||||
____exports.modifier_effect_manager = modifier_effect_manager
|
||||
____exports.modifier_effects_wings = __TS__Class()
|
||||
local modifier_effects_wings = ____exports.modifier_effects_wings
|
||||
modifier_effects_wings.name = "modifier_effects_wings"
|
||||
modifier_effects_wings.____file_path = "scripts/vscripts/abilities/modifiers/ability_effects.lua"
|
||||
__TS__ClassExtends(modifier_effects_wings, BaseModifier)
|
||||
function modifier_effects_wings.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_effects_wings.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_effects_wings.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_effects_wings.prototype.GetEffectAttachType(self)
|
||||
return PATTACH_ABSORIGIN_FOLLOW
|
||||
end
|
||||
modifier_effects_wings = __TS__Decorate(
|
||||
modifier_effects_wings,
|
||||
modifier_effects_wings,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_effects_wings"}
|
||||
)
|
||||
____exports.modifier_effects_wings = modifier_effects_wings
|
||||
____exports.modifier_effects_effect = __TS__Class()
|
||||
local modifier_effects_effect = ____exports.modifier_effects_effect
|
||||
modifier_effects_effect.name = "modifier_effects_effect"
|
||||
modifier_effects_effect.____file_path = "scripts/vscripts/abilities/modifiers/ability_effects.lua"
|
||||
__TS__ClassExtends(modifier_effects_effect, BaseModifier)
|
||||
function modifier_effects_effect.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_effects_effect.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_effects_effect.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_effects_effect.prototype.GetEffectName(self)
|
||||
local parent = self:GetParent()
|
||||
if not parent or parent:IsNull() or not IsValidEntity(parent) then
|
||||
return ""
|
||||
end
|
||||
local hero = parent
|
||||
if not hero or not hero:IsRealHero() then
|
||||
return ""
|
||||
end
|
||||
local current_effect = GetEffect(nil, hero, "effect")
|
||||
if current_effect == "skin_effect_ice" then
|
||||
return "particles/econ/items/omniknight/omniknight_fall20_immortal/omniknight_fall20_immortal_degen_aura_debuff.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_fire" then
|
||||
return "particles/econ/items/omniknight/omni_crimson_witness_2021/omniknight_crimson_witness_2021_degen_aura_debuff.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_heaven" then
|
||||
return "particles/units/heroes/hero_omniknight/omniknight_heavenly_grace_buff.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_fall_2021_emblem" then
|
||||
return "particles/econ/events/fall_2021/fall_2021_emblem_game_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_blue_gems" then
|
||||
return "particles/blue_gems_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_sponsor" then
|
||||
return "particles/sponsor_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_lotus" then
|
||||
return "particles/lotus_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_bp_red" then
|
||||
return "particles/effect_battlepass_red.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_bp_garden" then
|
||||
return "particles/battlepass_garden_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_bp_golden" then
|
||||
return "particles/battlepass_golden_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_bp_diretide_emblem" then
|
||||
return "particles/econ/events/diretide_2020/emblem/fall20_emblem_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_bp_diretide_emblem_v1" then
|
||||
return "particles/econ/events/diretide_2020/emblem/fall20_emblem_v1_effect.vpcf"
|
||||
end
|
||||
if current_effect == "skin_effect_bp_diretide_emblem_v3" then
|
||||
return "particles/econ/events/diretide_2020/emblem/fall20_emblem_v3_effect.vpcf"
|
||||
end
|
||||
return ""
|
||||
end
|
||||
function modifier_effects_effect.prototype.GetEffectAttachType(self)
|
||||
return PATTACH_ABSORIGIN_FOLLOW
|
||||
end
|
||||
modifier_effects_effect = __TS__Decorate(
|
||||
modifier_effects_effect,
|
||||
modifier_effects_effect,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_effects_effect"}
|
||||
)
|
||||
____exports.modifier_effects_effect = modifier_effects_effect
|
||||
____exports.modifier_effects_model = __TS__Class()
|
||||
local modifier_effects_model = ____exports.modifier_effects_model
|
||||
modifier_effects_model.name = "modifier_effects_model"
|
||||
modifier_effects_model.____file_path = "scripts/vscripts/abilities/modifiers/ability_effects.lua"
|
||||
__TS__ClassExtends(modifier_effects_model, BaseModifier)
|
||||
function modifier_effects_model.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_effects_model.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_effects_model.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_effects_model.prototype.GetEffectName(self)
|
||||
return "particles/units/heroes/hero_omniknight/omniknight_guardian_angel_wings.vpcf"
|
||||
end
|
||||
function modifier_effects_model.prototype.GetEffectAttachType(self)
|
||||
return PATTACH_ABSORIGIN_FOLLOW
|
||||
end
|
||||
modifier_effects_model = __TS__Decorate(
|
||||
modifier_effects_model,
|
||||
modifier_effects_model,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_effects_model"}
|
||||
)
|
||||
____exports.modifier_effects_model = modifier_effects_model
|
||||
return ____exports
|
||||
@@ -0,0 +1,164 @@
|
||||
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
|
||||
____exports.ability_glyph_custom = __TS__Class()
|
||||
local ability_glyph_custom = ____exports.ability_glyph_custom
|
||||
ability_glyph_custom.name = "ability_glyph_custom"
|
||||
ability_glyph_custom.____file_path = "scripts/vscripts/abilities/modifiers/ability_glyph_custom.lua"
|
||||
__TS__ClassExtends(ability_glyph_custom, BaseAbility)
|
||||
function ability_glyph_custom.prototype.GetIntrinsicModifierName(self)
|
||||
return "modifier_glyph_custom_passive"
|
||||
end
|
||||
ability_glyph_custom = __TS__Decorate(
|
||||
ability_glyph_custom,
|
||||
ability_glyph_custom,
|
||||
{registerAbility(nil)},
|
||||
{kind = "class", name = "ability_glyph_custom"}
|
||||
)
|
||||
____exports.ability_glyph_custom = ability_glyph_custom
|
||||
____exports.modifier_glyph_custom_passive = __TS__Class()
|
||||
local modifier_glyph_custom_passive = ____exports.modifier_glyph_custom_passive
|
||||
modifier_glyph_custom_passive.name = "modifier_glyph_custom_passive"
|
||||
modifier_glyph_custom_passive.____file_path = "scripts/vscripts/abilities/modifiers/ability_glyph_custom.lua"
|
||||
__TS__ClassExtends(modifier_glyph_custom_passive, BaseModifier)
|
||||
function modifier_glyph_custom_passive.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.isActive = true
|
||||
end
|
||||
function modifier_glyph_custom_passive.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_glyph_custom_passive.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MIN_HEALTH, MODIFIER_EVENT_ON_TAKEDAMAGE}
|
||||
end
|
||||
function modifier_glyph_custom_passive.prototype.GetMinHealth(self)
|
||||
if self.isActive then
|
||||
return 1
|
||||
end
|
||||
return 0
|
||||
end
|
||||
function modifier_glyph_custom_passive.prototype.OnTakeDamage(self, event)
|
||||
local parent = self:GetParent()
|
||||
if event.unit == parent then
|
||||
if parent:GetHealthPercent() <= 10 and self.isActive then
|
||||
FireGameEvent("dota_glyph_used", {teamnumber = DOTA_TEAM_GOODGUYS})
|
||||
self.isActive = false
|
||||
parent:AddNewModifier(
|
||||
parent,
|
||||
self:GetAbility(),
|
||||
"modifier_glyph_custom",
|
||||
{duration = 6}
|
||||
)
|
||||
Timers:CreateTimer(
|
||||
306,
|
||||
function()
|
||||
self.isActive = true
|
||||
end
|
||||
)
|
||||
parent:RemoveModifierByName("modifier_glyph_custom_passive")
|
||||
end
|
||||
end
|
||||
end
|
||||
modifier_glyph_custom_passive = __TS__Decorate(
|
||||
modifier_glyph_custom_passive,
|
||||
modifier_glyph_custom_passive,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_glyph_custom_passive"}
|
||||
)
|
||||
____exports.modifier_glyph_custom_passive = modifier_glyph_custom_passive
|
||||
____exports.modifier_glyph_custom = __TS__Class()
|
||||
local modifier_glyph_custom = ____exports.modifier_glyph_custom
|
||||
modifier_glyph_custom.name = "modifier_glyph_custom"
|
||||
modifier_glyph_custom.____file_path = "scripts/vscripts/abilities/modifiers/ability_glyph_custom.lua"
|
||||
__TS__ClassExtends(modifier_glyph_custom, BaseModifier)
|
||||
function modifier_glyph_custom.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_glyph_custom.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_glyph_custom.prototype.OnCreated(self, params)
|
||||
local parent = self:GetParent()
|
||||
local particle = ParticleManager:CreateParticle("particles/items_fx/glyph.vpcf", PATTACH_ABSORIGIN_FOLLOW, parent)
|
||||
ParticleManager:SetParticleControl(
|
||||
particle,
|
||||
0,
|
||||
parent:GetAbsOrigin()
|
||||
)
|
||||
ParticleManager:SetParticleControl(
|
||||
particle,
|
||||
1,
|
||||
Vector(150, 1, 1)
|
||||
)
|
||||
self:AddParticle(
|
||||
particle,
|
||||
false,
|
||||
false,
|
||||
-1,
|
||||
false,
|
||||
false
|
||||
)
|
||||
end
|
||||
function modifier_glyph_custom.prototype.OnDestroy(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
local ability = self:GetAbility()
|
||||
if ability then
|
||||
parent:AddNewModifier(parent, ability, "modifier_glyph_custom_passive_cd", {duration = 300})
|
||||
end
|
||||
end
|
||||
function modifier_glyph_custom.prototype.CheckState(self)
|
||||
return {[MODIFIER_STATE_INVULNERABLE] = true}
|
||||
end
|
||||
modifier_glyph_custom = __TS__Decorate(
|
||||
modifier_glyph_custom,
|
||||
modifier_glyph_custom,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_glyph_custom"}
|
||||
)
|
||||
____exports.modifier_glyph_custom = modifier_glyph_custom
|
||||
____exports.modifier_glyph_custom_passive_cd = __TS__Class()
|
||||
local modifier_glyph_custom_passive_cd = ____exports.modifier_glyph_custom_passive_cd
|
||||
modifier_glyph_custom_passive_cd.name = "modifier_glyph_custom_passive_cd"
|
||||
modifier_glyph_custom_passive_cd.____file_path = "scripts/vscripts/abilities/modifiers/ability_glyph_custom.lua"
|
||||
__TS__ClassExtends(modifier_glyph_custom_passive_cd, BaseModifier)
|
||||
function modifier_glyph_custom_passive_cd.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_glyph_custom_passive_cd.prototype.IsDebuff(self)
|
||||
return true
|
||||
end
|
||||
function modifier_glyph_custom_passive_cd.prototype.IsPurgable(self)
|
||||
return true
|
||||
end
|
||||
function modifier_glyph_custom_passive_cd.prototype.OnDestroy(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
local ability = self:GetAbility()
|
||||
if ability then
|
||||
self:GetParent():AddNewModifier(
|
||||
self:GetParent(),
|
||||
ability,
|
||||
"modifier_glyph_custom_passive",
|
||||
{}
|
||||
)
|
||||
end
|
||||
end
|
||||
modifier_glyph_custom_passive_cd = __TS__Decorate(
|
||||
modifier_glyph_custom_passive_cd,
|
||||
modifier_glyph_custom_passive_cd,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_glyph_custom_passive_cd"}
|
||||
)
|
||||
____exports.modifier_glyph_custom_passive_cd = modifier_glyph_custom_passive_cd
|
||||
return ____exports
|
||||
@@ -0,0 +1,43 @@
|
||||
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 registerAbility = ____dota_ts_adapter.registerAbility
|
||||
____exports.MODIFIER_SOURCE_ABILITY_NAME = "ability_modifier_source"
|
||||
____exports.ability_modifier_source = __TS__Class()
|
||||
local ability_modifier_source = ____exports.ability_modifier_source
|
||||
ability_modifier_source.name = "ability_modifier_source"
|
||||
ability_modifier_source.____file_path = "scripts/vscripts/abilities/modifiers/ability_modifier_source.lua"
|
||||
__TS__ClassExtends(ability_modifier_source, BaseAbility)
|
||||
function ability_modifier_source.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function ability_modifier_source.prototype.IsInnateAbility(self)
|
||||
return true
|
||||
end
|
||||
ability_modifier_source = __TS__Decorate(
|
||||
ability_modifier_source,
|
||||
ability_modifier_source,
|
||||
{registerAbility(nil)},
|
||||
{kind = "class", name = "ability_modifier_source"}
|
||||
)
|
||||
____exports.ability_modifier_source = ability_modifier_source
|
||||
function ____exports.getModifierSourceAbility(self, unit)
|
||||
if not IsServer() or not unit or not IsValidEntity(unit) or unit:IsNull() then
|
||||
return nil
|
||||
end
|
||||
local ability = unit:FindAbilityByName(____exports.MODIFIER_SOURCE_ABILITY_NAME)
|
||||
if not ability then
|
||||
ability = unit:AddAbility(____exports.MODIFIER_SOURCE_ABILITY_NAME)
|
||||
end
|
||||
if ability and ability:GetLevel() <= 0 then
|
||||
ability:SetLevel(1)
|
||||
end
|
||||
return ability or nil
|
||||
end
|
||||
local g = _G
|
||||
g.getModifierSourceAbility = ____exports.getModifierSourceAbility
|
||||
return ____exports
|
||||
@@ -0,0 +1,341 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
|
||||
local __TS__ArrayFindIndex = ____lualib.__TS__ArrayFindIndex
|
||||
local __TS__ArraySort = ____lualib.__TS__ArraySort
|
||||
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
|
||||
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 ____crit_mult = require("utils.crit_mult")
|
||||
local getFinalStackingCritMultiplier = ____crit_mult.getFinalStackingCritMultiplier
|
||||
local CRIT_LUCK_ADDITIVE_PERCENT_PER_POINT = 1
|
||||
____exports.ability_stacking_crit = __TS__Class()
|
||||
local ability_stacking_crit = ____exports.ability_stacking_crit
|
||||
ability_stacking_crit.name = "ability_stacking_crit"
|
||||
ability_stacking_crit.____file_path = "scripts/vscripts/abilities/modifiers/ability_stacking_crit.lua"
|
||||
__TS__ClassExtends(ability_stacking_crit, BaseAbility)
|
||||
function ability_stacking_crit.prototype.GetIntrinsicModifierName(self)
|
||||
return "modifier_stacking_crit"
|
||||
end
|
||||
ability_stacking_crit = __TS__Decorate(
|
||||
ability_stacking_crit,
|
||||
ability_stacking_crit,
|
||||
{registerAbility(nil)},
|
||||
{kind = "class", name = "ability_stacking_crit"}
|
||||
)
|
||||
____exports.ability_stacking_crit = ability_stacking_crit
|
||||
____exports.modifier_stacking_crit = __TS__Class()
|
||||
local modifier_stacking_crit = ____exports.modifier_stacking_crit
|
||||
modifier_stacking_crit.name = "modifier_stacking_crit"
|
||||
modifier_stacking_crit.____file_path = "scripts/vscripts/abilities/modifiers/ability_stacking_crit.lua"
|
||||
__TS__ClassExtends(modifier_stacking_crit, BaseModifier)
|
||||
function modifier_stacking_crit.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.critModifiers = {}
|
||||
self.guaranteedCritCount = 0
|
||||
self.guaranteedCritUntilDestroy = false
|
||||
self.wasCrit = false
|
||||
self.pendingGuaranteedCritConsume = false
|
||||
self.forcedTargetCritEntityIndex = nil
|
||||
self.lastCritChance = 0
|
||||
self.lastCritMult = 1
|
||||
end
|
||||
function modifier_stacking_crit.GetForUnit(self, unit)
|
||||
local mod = unit:FindModifierByName("modifier_stacking_crit")
|
||||
return mod and mod or nil
|
||||
end
|
||||
function modifier_stacking_crit.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_stacking_crit.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_stacking_crit.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_stacking_crit.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_PREATTACK_CRITICALSTRIKE, MODIFIER_EVENT_ON_ATTACK_LANDED, MODIFIER_PROPERTY_MAGICAL_RESISTANCE_DIRECT_MODIFICATION}
|
||||
end
|
||||
function modifier_stacking_crit.prototype.GetModifierMagicalResistanceDirectModification(self)
|
||||
return self:GetParent():GetIntellect(true) * -0.1
|
||||
end
|
||||
function modifier_stacking_crit.prototype.GetModifierPreAttack_CriticalStrike(self, params)
|
||||
if not IsServer() then
|
||||
return 0
|
||||
end
|
||||
self.wasCrit = false
|
||||
self.lastCritChance = 0
|
||||
self.lastCritMult = 1
|
||||
local totalBonus = 0
|
||||
local parent = self:GetParent()
|
||||
local target = params and params.target
|
||||
if self.forcedTargetCritEntityIndex ~= nil and target and IsValidEntity(target) and target:GetEntityIndex() == self.forcedTargetCritEntityIndex then
|
||||
self.forcedTargetCritEntityIndex = nil
|
||||
if #self.critModifiers > 0 then
|
||||
local baseCritMult = 0
|
||||
__TS__ArrayForEach(
|
||||
self.critModifiers,
|
||||
function(____, critData)
|
||||
baseCritMult = baseCritMult + critData.mult / 100
|
||||
end
|
||||
)
|
||||
local finalMult = getFinalStackingCritMultiplier(nil, parent, baseCritMult)
|
||||
self.wasCrit = true
|
||||
self.lastCritMult = finalMult
|
||||
self.lastCritChance = 100
|
||||
return finalMult * 100
|
||||
end
|
||||
end
|
||||
if self.guaranteedCritUntilDestroy and #self.critModifiers > 0 then
|
||||
print((("[STACKING_CRIT] guaranteedCritUntilDestroy=TRUE, unit=" .. parent:GetUnitName()) .. ", crits=") .. tostring(#self.critModifiers))
|
||||
local baseCritMult = 0
|
||||
__TS__ArrayForEach(
|
||||
self.critModifiers,
|
||||
function(____, critData)
|
||||
print((((((("[STACKING_CRIT] source=" .. critData.source) .. " chance=") .. tostring(critData.chance)) .. " mult=") .. tostring(critData.mult)) .. " entityIndex=") .. tostring(critData.entityIndex or -1))
|
||||
baseCritMult = baseCritMult + critData.mult / 100
|
||||
end
|
||||
)
|
||||
local finalMult = getFinalStackingCritMultiplier(nil, parent, baseCritMult)
|
||||
print((("[STACKING_CRIT] baseCritMult_sum=" .. tostring(baseCritMult)) .. " finalMult=") .. tostring(finalMult))
|
||||
self.wasCrit = true
|
||||
self.lastCritMult = finalMult
|
||||
self.lastCritChance = 100
|
||||
return finalMult * 100
|
||||
end
|
||||
if self.guaranteedCritCount > 0 and #self.critModifiers > 0 then
|
||||
local baseCritMult = 0
|
||||
__TS__ArrayForEach(
|
||||
self.critModifiers,
|
||||
function(____, critData)
|
||||
baseCritMult = baseCritMult + critData.mult / 100
|
||||
end
|
||||
)
|
||||
local finalMult = getFinalStackingCritMultiplier(nil, parent, baseCritMult)
|
||||
self.pendingGuaranteedCritConsume = true
|
||||
self.wasCrit = true
|
||||
self.lastCritMult = finalMult
|
||||
self.lastCritChance = 100
|
||||
return finalMult * 100
|
||||
end
|
||||
local hadAnyCrit = false
|
||||
local bestProcChance = 0
|
||||
__TS__ArrayForEach(
|
||||
self.critModifiers,
|
||||
function(____, critData)
|
||||
local luck = parent and parent:IsHero() and getLuck(nil, parent) or 0
|
||||
local effectiveChance = parent and parent:IsHero() and luck > 0 and math.min(
|
||||
100,
|
||||
math.max(0, critData.chance + luck * CRIT_LUCK_ADDITIVE_PERCENT_PER_POINT)
|
||||
) or critData.chance
|
||||
if parent and parent:IsHero() and luck > 0 then
|
||||
end
|
||||
if RollPseudoRandomPercentage(
|
||||
effectiveChance,
|
||||
1,
|
||||
self:GetParent()
|
||||
) then
|
||||
totalBonus = totalBonus + critData.mult / 100
|
||||
hadAnyCrit = true
|
||||
if effectiveChance > bestProcChance then
|
||||
bestProcChance = effectiveChance
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
if hadAnyCrit then
|
||||
local baseCritMult = totalBonus
|
||||
local finalMult = getFinalStackingCritMultiplier(nil, parent, baseCritMult)
|
||||
self.wasCrit = true
|
||||
self.lastCritChance = bestProcChance
|
||||
self.lastCritMult = finalMult
|
||||
return finalMult * 100
|
||||
end
|
||||
return 0
|
||||
end
|
||||
function modifier_stacking_crit.prototype.ForceNextCritOnTarget(self, target)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if not target or not IsValidEntity(target) or target:IsNull() then
|
||||
self.forcedTargetCritEntityIndex = nil
|
||||
return
|
||||
end
|
||||
self.forcedTargetCritEntityIndex = target:GetEntityIndex()
|
||||
end
|
||||
function modifier_stacking_crit.prototype.OnCreated(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:ClearCritModifiers()
|
||||
end
|
||||
function modifier_stacking_crit.prototype.ClearCritModifiers(self)
|
||||
self.critModifiers = {}
|
||||
end
|
||||
function modifier_stacking_crit.prototype.UpdateCrit(self, oldChance, oldMult, newChance, newMult, source)
|
||||
if source == nil then
|
||||
source = "ability"
|
||||
end
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if newChance < 0 and newMult <= 0 then
|
||||
self:RemoveCrit(source)
|
||||
return
|
||||
end
|
||||
self:UpdateExistingCrit(newChance, newMult, source)
|
||||
end
|
||||
function modifier_stacking_crit.prototype.UpdateExistingCrit(self, chance, mult, source, entity)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if chance < 0 and mult <= 0 then
|
||||
self:RemoveCrit(source, entity)
|
||||
return
|
||||
end
|
||||
local entityIndex = entity and entity:GetEntityIndex()
|
||||
local existingIndex = __TS__ArrayFindIndex(
|
||||
self.critModifiers,
|
||||
function(____, crit)
|
||||
if crit.source ~= source then
|
||||
return false
|
||||
end
|
||||
if entityIndex ~= nil then
|
||||
return crit.entityIndex == entityIndex
|
||||
end
|
||||
return true
|
||||
end
|
||||
)
|
||||
if existingIndex ~= -1 then
|
||||
self.critModifiers[existingIndex + 1].chance = chance
|
||||
self.critModifiers[existingIndex + 1].mult = mult
|
||||
if entityIndex ~= nil then
|
||||
self.critModifiers[existingIndex + 1].entityIndex = entityIndex
|
||||
end
|
||||
else
|
||||
local ____self_critModifiers_4 = self.critModifiers
|
||||
____self_critModifiers_4[#____self_critModifiers_4 + 1] = {chance = chance, mult = mult, source = source, entityIndex = entityIndex}
|
||||
end
|
||||
__TS__ArraySort(
|
||||
self.critModifiers,
|
||||
function(____, a, b) return b.chance - a.chance end
|
||||
)
|
||||
end
|
||||
function modifier_stacking_crit.prototype.AddCustomCrit(self, chance, mult, source, entity)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if chance < 0 and mult <= 0 then
|
||||
return
|
||||
end
|
||||
local entityIndex = entity and entity:GetEntityIndex()
|
||||
local existingIndex = __TS__ArrayFindIndex(
|
||||
self.critModifiers,
|
||||
function(____, crit) return crit.source == source and crit.entityIndex == entityIndex end
|
||||
)
|
||||
if existingIndex ~= -1 then
|
||||
self.critModifiers[existingIndex + 1] = {chance = chance, mult = mult, source = source, entityIndex = entityIndex}
|
||||
else
|
||||
local ____self_critModifiers_7 = self.critModifiers
|
||||
____self_critModifiers_7[#____self_critModifiers_7 + 1] = {chance = chance, mult = mult, source = source, entityIndex = entityIndex}
|
||||
end
|
||||
__TS__ArraySort(
|
||||
self.critModifiers,
|
||||
function(____, a, b) return b.chance - a.chance end
|
||||
)
|
||||
end
|
||||
function modifier_stacking_crit.prototype.GuaranteeNextCrit(self, count)
|
||||
if count == nil then
|
||||
count = 1
|
||||
end
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self.guaranteedCritCount = math.max(0, self.guaranteedCritCount + count)
|
||||
end
|
||||
function modifier_stacking_crit.prototype.GuaranteeCritUntilDestroy(self, enable)
|
||||
if enable == nil then
|
||||
enable = true
|
||||
end
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self.guaranteedCritUntilDestroy = enable
|
||||
end
|
||||
function modifier_stacking_crit.prototype.OnAttackLanded(self, event)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if event.attacker ~= self:GetParent() then
|
||||
return
|
||||
end
|
||||
if self.pendingGuaranteedCritConsume then
|
||||
self.guaranteedCritCount = math.max(0, self.guaranteedCritCount - 1)
|
||||
self.pendingGuaranteedCritConsume = false
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
local target = event.target
|
||||
if not parent or not target then
|
||||
return
|
||||
end
|
||||
if self.wasCrit then
|
||||
local avgTrue = parent:GetAverageTrueAttackDamage(target)
|
||||
local approxDamage = math.floor((avgTrue or 0) * (self.lastCritMult or 1))
|
||||
if self:GetParent():GetUnitName() == "npc_dota_hero_phantom_assassin" then
|
||||
EmitSoundOn("Hero_PhantomAssassin.CoupDeGrace", target)
|
||||
local effect_cast = ParticleManager:CreateParticle("particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", PATTACH_POINT_FOLLOW, target)
|
||||
ParticleManager:SetParticleControlEnt(
|
||||
effect_cast,
|
||||
0,
|
||||
target,
|
||||
PATTACH_POINT_FOLLOW,
|
||||
"attach_hitloc",
|
||||
target:GetOrigin(),
|
||||
true
|
||||
)
|
||||
ParticleManager:SetParticleControl(
|
||||
effect_cast,
|
||||
1,
|
||||
target:GetAbsOrigin()
|
||||
)
|
||||
ParticleManager:SetParticleControlForward(
|
||||
effect_cast,
|
||||
1,
|
||||
(parent:GetOrigin() - target:GetOrigin()):Normalized()
|
||||
)
|
||||
ParticleManager:ReleaseParticleIndex(effect_cast)
|
||||
end
|
||||
self.wasCrit = false
|
||||
end
|
||||
end
|
||||
function modifier_stacking_crit.prototype.RemoveCrit(self, source, entity)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local entityIndex = entity and entity:GetEntityIndex()
|
||||
self.critModifiers = __TS__ArrayFilter(
|
||||
self.critModifiers,
|
||||
function(____, crit) return not (crit.source == source and crit.entityIndex == entityIndex) end
|
||||
)
|
||||
end
|
||||
function modifier_stacking_crit.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self.critModifiers = {}
|
||||
self.guaranteedCritUntilDestroy = false
|
||||
end
|
||||
modifier_stacking_crit = __TS__Decorate(
|
||||
modifier_stacking_crit,
|
||||
modifier_stacking_crit,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_stacking_crit"}
|
||||
)
|
||||
____exports.modifier_stacking_crit = modifier_stacking_crit
|
||||
return ____exports
|
||||
@@ -0,0 +1,234 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
|
||||
local __TS__ArrayFindIndex = ____lualib.__TS__ArrayFindIndex
|
||||
local __TS__ArraySort = ____lualib.__TS__ArraySort
|
||||
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
|
||||
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 ____crit_mult = require("utils.crit_mult")
|
||||
local getFinalStackingCritMultiplier = ____crit_mult.getFinalStackingCritMultiplier
|
||||
local SPELL_CRIT_LUCK_ADDITIVE_PERCENT_PER_POINT = 1
|
||||
local isApplyingSpellCritBonus = false
|
||||
____exports.ability_stacking_spell_crit = __TS__Class()
|
||||
local ability_stacking_spell_crit = ____exports.ability_stacking_spell_crit
|
||||
ability_stacking_spell_crit.name = "ability_stacking_spell_crit"
|
||||
ability_stacking_spell_crit.____file_path = "scripts/vscripts/abilities/modifiers/ability_stacking_spell_crit.lua"
|
||||
__TS__ClassExtends(ability_stacking_spell_crit, BaseAbility)
|
||||
function ability_stacking_spell_crit.prototype.GetIntrinsicModifierName(self)
|
||||
return "modifier_stacking_spell_crit"
|
||||
end
|
||||
ability_stacking_spell_crit = __TS__Decorate(
|
||||
ability_stacking_spell_crit,
|
||||
ability_stacking_spell_crit,
|
||||
{registerAbility(nil)},
|
||||
{kind = "class", name = "ability_stacking_spell_crit"}
|
||||
)
|
||||
____exports.ability_stacking_spell_crit = ability_stacking_spell_crit
|
||||
____exports.modifier_stacking_spell_crit = __TS__Class()
|
||||
local modifier_stacking_spell_crit = ____exports.modifier_stacking_spell_crit
|
||||
modifier_stacking_spell_crit.name = "modifier_stacking_spell_crit"
|
||||
modifier_stacking_spell_crit.____file_path = "scripts/vscripts/abilities/modifiers/ability_stacking_spell_crit.lua"
|
||||
__TS__ClassExtends(modifier_stacking_spell_crit, BaseModifier)
|
||||
function modifier_stacking_spell_crit.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.critModifiers = {}
|
||||
end
|
||||
function modifier_stacking_spell_crit.GetForUnit(self, unit)
|
||||
local mod = unit:FindModifierByName("modifier_stacking_spell_crit")
|
||||
return mod and mod or nil
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_EVENT_ON_TAKEDAMAGE}
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.OnCreated(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self.critModifiers = {}
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.OnTakeDamage(self, event)
|
||||
if not IsServer() or isApplyingSpellCritBonus then
|
||||
return
|
||||
end
|
||||
if event.attacker ~= self:GetParent() then
|
||||
return
|
||||
end
|
||||
if #self.critModifiers == 0 then
|
||||
return
|
||||
end
|
||||
local damage = event.damage
|
||||
if damage <= 0 then
|
||||
return
|
||||
end
|
||||
if event.damage_type ~= DAMAGE_TYPE_MAGICAL then
|
||||
return
|
||||
end
|
||||
if not event.inflictor then
|
||||
return
|
||||
end
|
||||
local damageFlags = event.damage_flags or 0
|
||||
if bit.band(damageFlags, DOTA_DAMAGE_FLAG_HPLOSS) == DOTA_DAMAGE_FLAG_HPLOSS then
|
||||
return
|
||||
end
|
||||
if bit.band(damageFlags, DOTA_DAMAGE_FLAG_REFLECTION) == DOTA_DAMAGE_FLAG_REFLECTION then
|
||||
return
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
local victim = event.unit
|
||||
local inflictor = event.inflictor
|
||||
if not victim or not inflictor or victim:IsNull() or inflictor:IsNull() then
|
||||
return
|
||||
end
|
||||
if inflictor == self:GetAbility() then
|
||||
return
|
||||
end
|
||||
local totalBonusMult = 0
|
||||
local bestProcChance = 0
|
||||
local luck = parent:IsHero() and getLuck(nil, parent) or 0
|
||||
__TS__ArrayForEach(
|
||||
self.critModifiers,
|
||||
function(____, critData)
|
||||
local effectiveChance = parent:IsHero() and luck > 0 and math.min(
|
||||
100,
|
||||
math.max(0, critData.chance + luck * SPELL_CRIT_LUCK_ADDITIVE_PERCENT_PER_POINT)
|
||||
) or critData.chance
|
||||
if RollPseudoRandomPercentage(effectiveChance, 1, parent) then
|
||||
totalBonusMult = totalBonusMult + critData.mult / 100
|
||||
if effectiveChance > bestProcChance then
|
||||
bestProcChance = effectiveChance
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
if totalBonusMult <= 0 then
|
||||
return
|
||||
end
|
||||
local finalMult = getFinalStackingCritMultiplier(nil, parent, totalBonusMult)
|
||||
if finalMult <= 0 then
|
||||
return
|
||||
end
|
||||
local bonusDamage = damage * math.max(0, finalMult - 1)
|
||||
if bonusDamage <= 0 then
|
||||
return
|
||||
end
|
||||
local spellAmpFrac = parent:IsHero() and math.max(
|
||||
0,
|
||||
parent:GetSpellAmplification(false)
|
||||
) or 0
|
||||
local damageToApply = bonusDamage / math.max(0.000001, 1 + spellAmpFrac)
|
||||
isApplyingSpellCritBonus = true
|
||||
ApplyDamage({
|
||||
victim = victim,
|
||||
attacker = parent,
|
||||
damage = damageToApply,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NO_SPELL_AMPLIFICATION,
|
||||
ability = inflictor
|
||||
})
|
||||
isApplyingSpellCritBonus = false
|
||||
SendOverheadEventMessage(
|
||||
nil,
|
||||
OVERHEAD_ALERT_DEADLY_BLOW,
|
||||
victim,
|
||||
math.floor(bonusDamage),
|
||||
nil
|
||||
)
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.AddCustomCrit(self, chance, mult, source, entity)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if chance < 0 and mult <= 0 then
|
||||
return
|
||||
end
|
||||
local entityIndex = entity and entity:GetEntityIndex()
|
||||
local existingIndex = __TS__ArrayFindIndex(
|
||||
self.critModifiers,
|
||||
function(____, crit) return crit.source == source and crit.entityIndex == entityIndex end
|
||||
)
|
||||
if existingIndex ~= -1 then
|
||||
self.critModifiers[existingIndex + 1] = {chance = chance, mult = mult, source = source, entityIndex = entityIndex}
|
||||
else
|
||||
local ____self_critModifiers_2 = self.critModifiers
|
||||
____self_critModifiers_2[#____self_critModifiers_2 + 1] = {chance = chance, mult = mult, source = source, entityIndex = entityIndex}
|
||||
end
|
||||
__TS__ArraySort(
|
||||
self.critModifiers,
|
||||
function(____, a, b) return b.chance - a.chance end
|
||||
)
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.UpdateExistingCrit(self, chance, mult, source, entity)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if chance < 0 and mult <= 0 then
|
||||
self:RemoveCrit(source, entity)
|
||||
return
|
||||
end
|
||||
local entityIndex = entity and entity:GetEntityIndex()
|
||||
local existingIndex = __TS__ArrayFindIndex(
|
||||
self.critModifiers,
|
||||
function(____, crit)
|
||||
if crit.source ~= source then
|
||||
return false
|
||||
end
|
||||
if entityIndex ~= nil then
|
||||
return crit.entityIndex == entityIndex
|
||||
end
|
||||
return true
|
||||
end
|
||||
)
|
||||
if existingIndex ~= -1 then
|
||||
self.critModifiers[existingIndex + 1].chance = chance
|
||||
self.critModifiers[existingIndex + 1].mult = mult
|
||||
if entityIndex ~= nil then
|
||||
self.critModifiers[existingIndex + 1].entityIndex = entityIndex
|
||||
end
|
||||
else
|
||||
self:AddCustomCrit(chance, mult, source, entity)
|
||||
end
|
||||
__TS__ArraySort(
|
||||
self.critModifiers,
|
||||
function(____, a, b) return b.chance - a.chance end
|
||||
)
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.RemoveCrit(self, source, entity)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local entityIndex = entity and entity:GetEntityIndex()
|
||||
self.critModifiers = __TS__ArrayFilter(
|
||||
self.critModifiers,
|
||||
function(____, crit) return not (crit.source == source and crit.entityIndex == entityIndex) end
|
||||
)
|
||||
end
|
||||
function modifier_stacking_spell_crit.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self.critModifiers = {}
|
||||
end
|
||||
modifier_stacking_spell_crit = __TS__Decorate(
|
||||
modifier_stacking_spell_crit,
|
||||
modifier_stacking_spell_crit,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_stacking_spell_crit"}
|
||||
)
|
||||
____exports.modifier_stacking_spell_crit = modifier_stacking_spell_crit
|
||||
return ____exports
|
||||
@@ -0,0 +1,51 @@
|
||||
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
|
||||
____exports.ability_unit_less_laggy = __TS__Class()
|
||||
local ability_unit_less_laggy = ____exports.ability_unit_less_laggy
|
||||
ability_unit_less_laggy.name = "ability_unit_less_laggy"
|
||||
ability_unit_less_laggy.____file_path = "scripts/vscripts/abilities/modifiers/ability_unit_less_laggy.lua"
|
||||
__TS__ClassExtends(ability_unit_less_laggy, BaseAbility)
|
||||
function ability_unit_less_laggy.prototype.GetIntrinsicModifierName(self)
|
||||
return "modifier_unit_less_laggy"
|
||||
end
|
||||
ability_unit_less_laggy = __TS__Decorate(
|
||||
ability_unit_less_laggy,
|
||||
ability_unit_less_laggy,
|
||||
{registerAbility(nil)},
|
||||
{kind = "class", name = "ability_unit_less_laggy"}
|
||||
)
|
||||
____exports.ability_unit_less_laggy = ability_unit_less_laggy
|
||||
____exports.modifier_unit_less_laggy = __TS__Class()
|
||||
local modifier_unit_less_laggy = ____exports.modifier_unit_less_laggy
|
||||
modifier_unit_less_laggy.name = "modifier_unit_less_laggy"
|
||||
modifier_unit_less_laggy.____file_path = "scripts/vscripts/abilities/modifiers/ability_unit_less_laggy.lua"
|
||||
__TS__ClassExtends(modifier_unit_less_laggy, BaseModifier)
|
||||
function modifier_unit_less_laggy.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_unit_less_laggy.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_unit_less_laggy.prototype.CheckState(self)
|
||||
if self:GetParent():GetHealthPercent() <= 99.9 then
|
||||
return {[MODIFIER_STATE_NO_HEALTH_BAR] = false}
|
||||
else
|
||||
return {[MODIFIER_STATE_NO_HEALTH_BAR] = true}
|
||||
end
|
||||
end
|
||||
modifier_unit_less_laggy = __TS__Decorate(
|
||||
modifier_unit_less_laggy,
|
||||
modifier_unit_less_laggy,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_unit_less_laggy"}
|
||||
)
|
||||
____exports.modifier_unit_less_laggy = modifier_unit_less_laggy
|
||||
return ____exports
|
||||
@@ -0,0 +1,160 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local __TS__NumberToFixed = ____lualib.__TS__NumberToFixed
|
||||
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
|
||||
print("[DPS Tracker] ===== Файл dps_tracker.ts загружен ===== ")
|
||||
--- Модификатор для отслеживания урона, нанесенного юнитом
|
||||
-- Отображает DPS и последний урон снизу юнита
|
||||
--
|
||||
-- Использование:
|
||||
-- const modifier = unit.AddNewModifier(unit, getModifierSourceAbility(unit), "modifier_dps_tracker", {});
|
||||
____exports.dps_tracker = __TS__Class()
|
||||
local dps_tracker = ____exports.dps_tracker
|
||||
dps_tracker.name = "dps_tracker"
|
||||
dps_tracker.____file_path = "scripts/vscripts/abilities/modifiers/dps_tracker.lua"
|
||||
__TS__ClassExtends(dps_tracker, BaseAbility)
|
||||
function dps_tracker.prototype.GetIntrinsicModifierName(self)
|
||||
print("[DPS Tracker] GetIntrinsicModifierName вызван")
|
||||
return "modifier_dps_tracker"
|
||||
end
|
||||
dps_tracker = __TS__Decorate(
|
||||
dps_tracker,
|
||||
dps_tracker,
|
||||
{registerAbility(nil)},
|
||||
{kind = "class", name = "dps_tracker"}
|
||||
)
|
||||
____exports.dps_tracker = dps_tracker
|
||||
____exports.modifier_dps_tracker = __TS__Class()
|
||||
local modifier_dps_tracker = ____exports.modifier_dps_tracker
|
||||
modifier_dps_tracker.name = "modifier_dps_tracker"
|
||||
modifier_dps_tracker.____file_path = "scripts/vscripts/abilities/modifiers/dps_tracker.lua"
|
||||
__TS__ClassExtends(modifier_dps_tracker, BaseModifier)
|
||||
function modifier_dps_tracker.prototype.____constructor(self)
|
||||
BaseModifier.prototype.____constructor(self)
|
||||
self.totalDamage = 0
|
||||
self.lastHitDamage = 0
|
||||
self.startTime = 0
|
||||
self.lastHitTime = 0
|
||||
self.INACTIVE_TIMEOUT = 14
|
||||
print("[DPS Tracker] Конструктор modifier_dps_tracker вызван")
|
||||
end
|
||||
function modifier_dps_tracker.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_dps_tracker.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_dps_tracker.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_dps_tracker.prototype.OnCreated(self, params)
|
||||
print((("[DPS Tracker] OnCreated вызван, IsServer: " .. tostring(IsServer())) .. ", IsClient: ") .. tostring(IsClient()))
|
||||
if not IsServer() then
|
||||
print("[DPS Tracker] OnCreated: не на сервере, выходим")
|
||||
return
|
||||
end
|
||||
self.totalDamage = 0
|
||||
self.lastHitDamage = 0
|
||||
self.startTime = GameRules:GetGameTime()
|
||||
self.lastHitTime = self.startTime
|
||||
local unit = self:GetParent()
|
||||
if unit and IsValidEntity(unit) then
|
||||
print((("[DPS Tracker] Модификатор создан для юнита (цели): " .. unit:GetUnitName()) .. ", индекс: ") .. tostring(unit:entindex()))
|
||||
else
|
||||
print("[DPS Tracker] ОШИБКА: юнит невалиден при создании модификатора!")
|
||||
end
|
||||
self:StartIntervalThink(1)
|
||||
print("[DPS Tracker] StartIntervalThink установлен на 1.0")
|
||||
end
|
||||
function modifier_dps_tracker.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_EVENT_ON_TAKEDAMAGE, MODIFIER_PROPERTY_MIN_HEALTH}
|
||||
end
|
||||
function modifier_dps_tracker.prototype.GetMinHealth(self)
|
||||
return 1
|
||||
end
|
||||
function modifier_dps_tracker.prototype.OnTakeDamage(self, event)
|
||||
if not IsServer() then
|
||||
print("[DPS Tracker] OnTakeDamage: не на сервере")
|
||||
return
|
||||
end
|
||||
local victim = self:GetParent()
|
||||
local attacker = event.attacker
|
||||
if not attacker or not IsValidEntity(attacker) then
|
||||
return
|
||||
end
|
||||
if event.unit ~= self:GetParent() then
|
||||
return
|
||||
end
|
||||
self:GetParent():StartGesture(ACT_DOTA_FLINCH)
|
||||
local currentTime = GameRules:GetGameTime()
|
||||
local damage = event.damage
|
||||
if self.totalDamage == 0 then
|
||||
self.startTime = currentTime
|
||||
end
|
||||
self:GetParent():SetHealth(self:GetParent():GetHealth() + damage)
|
||||
self.totalDamage = self.totalDamage + damage
|
||||
self.lastHitDamage = damage
|
||||
self.lastHitTime = currentTime
|
||||
print((((((("[DPS Tracker] Урон получен: " .. tostring(math.floor(damage + 0.5))) .. ", всего урона: ") .. tostring(math.floor(self.totalDamage + 0.5))) .. ", от ") .. attacker:GetUnitName()) .. ", цель: ") .. victim:GetUnitName())
|
||||
self:updateDPSDisplay(victim:entindex())
|
||||
end
|
||||
function modifier_dps_tracker.prototype.OnIntervalThink(self)
|
||||
if not IsServer() then
|
||||
print("[DPS Tracker] OnIntervalThink: не на сервере")
|
||||
return
|
||||
end
|
||||
local currentTime = GameRules:GetGameTime()
|
||||
local victim = self:GetParent()
|
||||
local victimIndex = victim:entindex()
|
||||
local timeSinceLastHit = currentTime - self.lastHitTime
|
||||
if timeSinceLastHit > self.INACTIVE_TIMEOUT then
|
||||
print(("[DPS Tracker] Цель не получала урон " .. __TS__NumberToFixed(timeSinceLastHit, 1)) .. " секунд, удаляем отображение")
|
||||
CustomGameEventManager:Send_ServerToAllClients("unit_dps_remove", {unitIndex = victimIndex})
|
||||
else
|
||||
self:updateDPSDisplay(victimIndex)
|
||||
end
|
||||
end
|
||||
function modifier_dps_tracker.prototype.updateDPSDisplay(self, victimIndex)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local currentTime = GameRules:GetGameTime()
|
||||
local elapsedTime = currentTime - self.startTime
|
||||
local dps = elapsedTime > 0 and self.totalDamage / elapsedTime or 0
|
||||
local updateData = {
|
||||
unitIndex = victimIndex,
|
||||
attackerIndex = 0,
|
||||
totalDamage = math.floor(self.totalDamage + 0.5),
|
||||
dps = math.floor(dps + 0.5),
|
||||
lastHitDamage = math.floor(self.lastHitDamage + 0.5)
|
||||
}
|
||||
CustomGameEventManager:Send_ServerToAllClients("unit_dps_update", updateData)
|
||||
end
|
||||
function modifier_dps_tracker.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local unit = self:GetParent()
|
||||
if unit and IsValidEntity(unit) then
|
||||
local victimIndex = unit:entindex()
|
||||
print((((("[DPS Tracker] Модификатор уничтожен для юнита: " .. unit:GetUnitName()) .. ", индекс: ") .. tostring(victimIndex)) .. ", финальный урон: ") .. tostring(math.floor(self.totalDamage + 0.5)))
|
||||
CustomGameEventManager:Send_ServerToAllClients("unit_dps_remove", {unitIndex = victimIndex})
|
||||
else
|
||||
print("[DPS Tracker] Ошибка: юнит невалиден при уничтожении модификатора")
|
||||
end
|
||||
end
|
||||
modifier_dps_tracker = __TS__Decorate(
|
||||
modifier_dps_tracker,
|
||||
modifier_dps_tracker,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_dps_tracker"}
|
||||
)
|
||||
____exports.modifier_dps_tracker = modifier_dps_tracker
|
||||
return ____exports
|
||||
@@ -0,0 +1,99 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__StringStartsWith = ____lualib.__TS__StringStartsWith
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
local THINK_INTERVAL = 0.2
|
||||
--- Волновые боссы + только npc_boss_nevermore (остальные npc_boss_* — без верхнего бара)
|
||||
function ____exports.isBossHudHealthBarUnit(self, unitName)
|
||||
return __TS__StringStartsWith(unitName, "npc_wave_boss_") or unitName == "npc_boss_nevermore"
|
||||
end
|
||||
--- Локализованное имя в HUD для Nevermore из spawn_boss_units / кат-сцены
|
||||
____exports.BOSS_NEVERMORE_NAME_TOKEN = "#npc_boss_nevermore"
|
||||
function ____exports.applyBossHudHealthBar(self, unit, nameToken)
|
||||
if not IsServer() or unit == nil or not unit:IsAlive() then
|
||||
return
|
||||
end
|
||||
if unit:HasModifier(____exports.modifier_boss_hud_health_bar.name) then
|
||||
return
|
||||
end
|
||||
unit:AddNewModifier(
|
||||
unit,
|
||||
getModifierSourceAbility(nil, unit),
|
||||
____exports.modifier_boss_hud_health_bar.name,
|
||||
{name_token = nameToken}
|
||||
)
|
||||
end
|
||||
____exports.modifier_boss_hud_health_bar = __TS__Class()
|
||||
local modifier_boss_hud_health_bar = ____exports.modifier_boss_hud_health_bar
|
||||
modifier_boss_hud_health_bar.name = "modifier_boss_hud_health_bar"
|
||||
modifier_boss_hud_health_bar.____file_path = "scripts/vscripts/abilities/modifiers/modifier_boss_hud_health_bar.lua"
|
||||
__TS__ClassExtends(modifier_boss_hud_health_bar, BaseModifier)
|
||||
function modifier_boss_hud_health_bar.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.nameToken = ""
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.RemoveOnDeath(self)
|
||||
return true
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.OnCreated(self, params)
|
||||
self.parent = self:GetParent()
|
||||
self.nameToken = params.name_token or "#" .. self.parent:GetUnitName()
|
||||
self:sendUpdate()
|
||||
self:StartIntervalThink(THINK_INTERVAL)
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_EVENT_ON_TAKEDAMAGE}
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.OnTakeDamage(self)
|
||||
self:sendUpdate()
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.OnIntervalThink(self)
|
||||
if not IsValidEntity(self.parent) or not self.parent:IsAlive() then
|
||||
self:StartIntervalThink(-1)
|
||||
return
|
||||
end
|
||||
self:sendUpdate()
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.OnDestroy(self)
|
||||
if IsServer() then
|
||||
CustomGameEventManager:Send_ServerToAllClients("boss_health_bar_hide", {})
|
||||
end
|
||||
end
|
||||
function modifier_boss_hud_health_bar.prototype.sendUpdate(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if not IsValidEntity(self.parent) or not self.parent:IsAlive() then
|
||||
return
|
||||
end
|
||||
CustomGameEventManager:Send_ServerToAllClients(
|
||||
"boss_health_bar_update",
|
||||
{
|
||||
health = math.floor(self.parent:GetHealth()),
|
||||
maxHealth = math.max(
|
||||
1,
|
||||
math.floor(self.parent:GetMaxHealth())
|
||||
),
|
||||
nameToken = self.nameToken
|
||||
}
|
||||
)
|
||||
end
|
||||
modifier_boss_hud_health_bar = __TS__Decorate(
|
||||
modifier_boss_hud_health_bar,
|
||||
modifier_boss_hud_health_bar,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_boss_hud_health_bar"}
|
||||
)
|
||||
____exports.modifier_boss_hud_health_bar = modifier_boss_hud_health_bar
|
||||
return ____exports
|
||||
@@ -0,0 +1,30 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_cutscene_ready_lock = __TS__Class()
|
||||
local modifier_cutscene_ready_lock = ____exports.modifier_cutscene_ready_lock
|
||||
modifier_cutscene_ready_lock.name = "modifier_cutscene_ready_lock"
|
||||
modifier_cutscene_ready_lock.____file_path = "scripts/vscripts/abilities/modifiers/modifier_cutscene_ready_lock.lua"
|
||||
__TS__ClassExtends(modifier_cutscene_ready_lock, BaseModifier)
|
||||
function modifier_cutscene_ready_lock.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_cutscene_ready_lock.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_cutscene_ready_lock.prototype.CheckState(self)
|
||||
return {[MODIFIER_STATE_STUNNED] = true, [MODIFIER_STATE_COMMAND_RESTRICTED] = true}
|
||||
end
|
||||
modifier_cutscene_ready_lock = __TS__Decorate(
|
||||
modifier_cutscene_ready_lock,
|
||||
modifier_cutscene_ready_lock,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_cutscene_ready_lock"}
|
||||
)
|
||||
____exports.modifier_cutscene_ready_lock = modifier_cutscene_ready_lock
|
||||
return ____exports
|
||||
@@ -0,0 +1,51 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_donate_item = __TS__Class()
|
||||
local modifier_donate_item = ____exports.modifier_donate_item
|
||||
modifier_donate_item.name = "modifier_donate_item"
|
||||
modifier_donate_item.____file_path = "scripts/vscripts/abilities/modifiers/modifier_donate_item.lua"
|
||||
__TS__ClassExtends(modifier_donate_item, BaseModifier)
|
||||
function modifier_donate_item.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_donate_item.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_donate_item.prototype.IsPurgeException(self)
|
||||
return false
|
||||
end
|
||||
function modifier_donate_item.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_donate_item.prototype.CheckState(self)
|
||||
return {
|
||||
[MODIFIER_STATE_OUT_OF_GAME] = true,
|
||||
[MODIFIER_STATE_INVULNERABLE] = true,
|
||||
[MODIFIER_STATE_NOT_ON_MINIMAP] = true,
|
||||
[MODIFIER_STATE_COMMAND_RESTRICTED] = true,
|
||||
[MODIFIER_STATE_STUNNED] = true,
|
||||
[MODIFIER_STATE_FLYING_FOR_PATHING_PURPOSES_ONLY] = true,
|
||||
[MODIFIER_STATE_NO_HEALTH_BAR] = true,
|
||||
[MODIFIER_STATE_NO_UNIT_COLLISION] = true,
|
||||
[MODIFIER_STATE_INVISIBLE] = true
|
||||
}
|
||||
end
|
||||
function modifier_donate_item.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
end
|
||||
modifier_donate_item = __TS__Decorate(
|
||||
modifier_donate_item,
|
||||
modifier_donate_item,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_donate_item"}
|
||||
)
|
||||
____exports.modifier_donate_item = modifier_donate_item
|
||||
return ____exports
|
||||
@@ -0,0 +1,164 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Number = ____lualib.__TS__Number
|
||||
local __TS__NumberIsFinite = ____lualib.__TS__NumberIsFinite
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
local ____luck = require("utils.luck")
|
||||
local addLuck = ____luck.addLuck
|
||||
local reduceLuck = ____luck.reduceLuck
|
||||
____exports.modifier_equipment_stats = __TS__Class()
|
||||
local modifier_equipment_stats = ____exports.modifier_equipment_stats
|
||||
modifier_equipment_stats.name = "modifier_equipment_stats"
|
||||
modifier_equipment_stats.____file_path = "scripts/vscripts/abilities/modifiers/modifier_equipment_stats.lua"
|
||||
__TS__ClassExtends(modifier_equipment_stats, BaseModifier)
|
||||
function modifier_equipment_stats.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.appliedLuck = 0
|
||||
self.strengthPct = 0
|
||||
self.intellectPct = 0
|
||||
self.damagePct = 0
|
||||
self.damageReductionPct = 0
|
||||
self.spellAmpPct = 0
|
||||
self.strengthBonus = 0
|
||||
self.intellectBonus = 0
|
||||
end
|
||||
function modifier_equipment_stats.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_equipment_stats.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_equipment_stats.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_equipment_stats.prototype.OnCreated(self, params)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:readParams(params)
|
||||
self:applyLuck()
|
||||
self:StartIntervalThink(1)
|
||||
self:updateDerivedAttributeBonuses()
|
||||
end
|
||||
function modifier_equipment_stats.prototype.OnRefresh(self, params)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:clearLuck()
|
||||
self:readParams(params)
|
||||
self:applyLuck()
|
||||
self:updateDerivedAttributeBonuses()
|
||||
end
|
||||
function modifier_equipment_stats.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:clearLuck()
|
||||
end
|
||||
function modifier_equipment_stats.prototype.OnIntervalThink(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:updateDerivedAttributeBonuses()
|
||||
end
|
||||
function modifier_equipment_stats.prototype.DeclareFunctions(self)
|
||||
return {
|
||||
MODIFIER_PROPERTY_STATS_STRENGTH_BONUS,
|
||||
MODIFIER_PROPERTY_STATS_INTELLECT_BONUS,
|
||||
MODIFIER_PROPERTY_TOTALDAMAGEOUTGOING_PERCENTAGE,
|
||||
MODIFIER_PROPERTY_INCOMING_DAMAGE_PERCENTAGE,
|
||||
MODIFIER_PROPERTY_SPELL_AMPLIFY_PERCENTAGE
|
||||
}
|
||||
end
|
||||
function modifier_equipment_stats.prototype.GetModifierBonusStats_Strength(self)
|
||||
return self.strengthBonus
|
||||
end
|
||||
function modifier_equipment_stats.prototype.GetModifierBonusStats_Intellect(self)
|
||||
return self.intellectBonus
|
||||
end
|
||||
function modifier_equipment_stats.prototype.GetModifierTotalDamageOutgoing_Percentage(self)
|
||||
return self.damagePct
|
||||
end
|
||||
function modifier_equipment_stats.prototype.GetModifierIncomingDamage_Percentage(self)
|
||||
return -self.damageReductionPct
|
||||
end
|
||||
function modifier_equipment_stats.prototype.GetModifierSpellAmplify_Percentage(self)
|
||||
return self.spellAmpPct
|
||||
end
|
||||
function modifier_equipment_stats.prototype.readParams(self, params)
|
||||
self.appliedLuck = 0
|
||||
self.strengthPct = __TS__Number(params.strengthPct or "0")
|
||||
self.intellectPct = __TS__Number(params.intellectPct or "0")
|
||||
self.damagePct = __TS__Number(params.damagePct or "0")
|
||||
self.damageReductionPct = __TS__Number(params.damageReductionPct or "0")
|
||||
self.spellAmpPct = __TS__Number(params.spellAmpPct or "0")
|
||||
self.appliedLuck = __TS__Number(params.luckPct or "0")
|
||||
if not __TS__NumberIsFinite(self.appliedLuck) then
|
||||
self.appliedLuck = 0
|
||||
end
|
||||
if not __TS__NumberIsFinite(self.strengthPct) then
|
||||
self.strengthPct = 0
|
||||
end
|
||||
if not __TS__NumberIsFinite(self.intellectPct) then
|
||||
self.intellectPct = 0
|
||||
end
|
||||
if not __TS__NumberIsFinite(self.damagePct) then
|
||||
self.damagePct = 0
|
||||
end
|
||||
if not __TS__NumberIsFinite(self.damageReductionPct) then
|
||||
self.damageReductionPct = 0
|
||||
end
|
||||
if not __TS__NumberIsFinite(self.spellAmpPct) then
|
||||
self.spellAmpPct = 0
|
||||
end
|
||||
end
|
||||
function modifier_equipment_stats.prototype.updateDerivedAttributeBonuses(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not hero:IsRealHero() then
|
||||
self.strengthBonus = 0
|
||||
self.intellectBonus = 0
|
||||
return
|
||||
end
|
||||
local baseStrength = math.max(
|
||||
0,
|
||||
hero:GetStrength() - self.strengthBonus
|
||||
)
|
||||
local baseIntellect = math.max(
|
||||
0,
|
||||
hero:GetIntellect(false) - self.intellectBonus
|
||||
)
|
||||
self.strengthBonus = math.floor(baseStrength * (self.strengthPct / 100))
|
||||
self.intellectBonus = math.floor(baseIntellect * (self.intellectPct / 100))
|
||||
self:ForceRefresh()
|
||||
end
|
||||
function modifier_equipment_stats.prototype.applyLuck(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
if self.appliedLuck ~= 0 then
|
||||
addLuck(nil, hero, self.appliedLuck)
|
||||
end
|
||||
end
|
||||
function modifier_equipment_stats.prototype.clearLuck(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
if self.appliedLuck ~= 0 then
|
||||
reduceLuck(nil, hero, self.appliedLuck)
|
||||
end
|
||||
end
|
||||
modifier_equipment_stats = __TS__Decorate(
|
||||
modifier_equipment_stats,
|
||||
modifier_equipment_stats,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_equipment_stats"}
|
||||
)
|
||||
____exports.modifier_equipment_stats = modifier_equipment_stats
|
||||
return ____exports
|
||||
@@ -0,0 +1,133 @@
|
||||
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 BaseModifierMotionBoth = ____dota_ts_adapter.BaseModifierMotionBoth
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_general_arc = __TS__Class()
|
||||
local modifier_general_arc = ____exports.modifier_general_arc
|
||||
modifier_general_arc.name = "modifier_general_arc"
|
||||
modifier_general_arc.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_arc.lua"
|
||||
__TS__ClassExtends(modifier_general_arc, BaseModifierMotionBoth)
|
||||
function modifier_general_arc.prototype.____constructor(self, ...)
|
||||
BaseModifierMotionBoth.prototype.____constructor(self, ...)
|
||||
self.direction = Vector(0, 0, 0)
|
||||
self.interrupted = false
|
||||
self.duration = 0
|
||||
self.distance = 0
|
||||
self.speed = 0
|
||||
self.height = 0
|
||||
self.const1 = 0
|
||||
self.const2 = 0
|
||||
self.isFlail = false
|
||||
end
|
||||
function modifier_general_arc.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_arc.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_arc.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_arc.prototype.OnCreated(self, params)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
local origin = parent:GetOrigin()
|
||||
if not not params.isFlail then
|
||||
self:SetStackCount(1)
|
||||
end
|
||||
if not not params.x then
|
||||
local targetOrigin = Vector(params.x, params.y, 0)
|
||||
local dir = targetOrigin - origin
|
||||
dir = dir:Normalized()
|
||||
self.direction = dir
|
||||
self.distance = (targetOrigin - origin):Length()
|
||||
else
|
||||
self.direction = parent:GetForwardVector()
|
||||
self.distance = params.distance
|
||||
end
|
||||
self.duration = params.duration
|
||||
self.height = params.height
|
||||
self.speed = self.distance / self.duration
|
||||
if self:ApplyHorizontalMotionController() == false or self:ApplyVerticalMotionController() == false then
|
||||
self:Destroy()
|
||||
return
|
||||
end
|
||||
local posEnd = origin + self.direction * self.distance
|
||||
local heightStart = GetGroundHeight(origin, parent)
|
||||
local heightEnd = GetGroundHeight(posEnd, parent)
|
||||
local tempmin = heightStart
|
||||
local tempmax = heightEnd
|
||||
if tempmin > tempmax then
|
||||
tempmin = tempmax
|
||||
tempmax = tempmin
|
||||
end
|
||||
local delta = (tempmax - tempmin) * 2 / 3
|
||||
local heightMax = tempmin + delta + self.height
|
||||
heightEnd = heightEnd - heightStart
|
||||
heightMax = heightMax - heightStart
|
||||
if heightMax < heightEnd then
|
||||
heightMax = heightEnd + 0.01
|
||||
end
|
||||
if heightMax <= 0 then
|
||||
heightMax = 0.01
|
||||
end
|
||||
local durationEnd = (1 + math.sqrt(1 - heightEnd / heightMax)) / 2
|
||||
self.const1 = 4 * heightMax * durationEnd / self.duration
|
||||
self.const2 = 4 * heightMax * durationEnd * durationEnd / (self.duration * self.duration)
|
||||
end
|
||||
function modifier_general_arc.prototype.OnDestroy(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
parent:RemoveHorizontalMotionController(self)
|
||||
parent:RemoveVerticalMotionController(self)
|
||||
end
|
||||
function modifier_general_arc.prototype.GetVerticalSpeed(self, time)
|
||||
return self.const1 - 2 * self.const2 * time
|
||||
end
|
||||
function modifier_general_arc.prototype.UpdateHorizontalMotion(self, me, dt)
|
||||
local pos = me:GetOrigin() + self.direction * self.speed * dt
|
||||
me:SetOrigin(pos)
|
||||
end
|
||||
function modifier_general_arc.prototype.UpdateVerticalMotion(self, me, dt)
|
||||
local pos = me:GetOrigin()
|
||||
local time = self:GetElapsedTime()
|
||||
local height = pos.z
|
||||
local speed = self:GetVerticalSpeed(time)
|
||||
pos.z = height + speed * dt
|
||||
me:SetOrigin(pos)
|
||||
end
|
||||
function modifier_general_arc.prototype.OnHorizontalMotionInterrupted(self)
|
||||
self.interrupted = true
|
||||
end
|
||||
function modifier_general_arc.prototype.OnVerticalMotionInterrupted(self)
|
||||
self:Destroy()
|
||||
end
|
||||
function modifier_general_arc.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_OVERRIDE_ANIMATION}
|
||||
end
|
||||
function modifier_general_arc.prototype.CheckState(self)
|
||||
return {[MODIFIER_STATE_STUNNED] = true}
|
||||
end
|
||||
function modifier_general_arc.prototype.GetOverrideAnimation(self)
|
||||
if self:GetStackCount() == 1 then
|
||||
return ACT_DOTA_FLAIL
|
||||
else
|
||||
return ACT_DOTA_OVERRIDE_ABILITY_2
|
||||
end
|
||||
end
|
||||
modifier_general_arc = __TS__Decorate(
|
||||
modifier_general_arc,
|
||||
modifier_general_arc,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_general_arc"}
|
||||
)
|
||||
____exports.modifier_general_arc = modifier_general_arc
|
||||
return ____exports
|
||||
@@ -0,0 +1,126 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_general_fired = __TS__Class()
|
||||
local modifier_general_fired = ____exports.modifier_general_fired
|
||||
modifier_general_fired.name = "modifier_general_fired"
|
||||
modifier_general_fired.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_fired.lua"
|
||||
__TS__ClassExtends(modifier_general_fired, BaseModifier)
|
||||
function modifier_general_fired.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.isBurned = false
|
||||
self.STACKS_TO_BURN = 0
|
||||
self.STACKS_TO_ARMOR_REDUCE = 70
|
||||
end
|
||||
function modifier_general_fired.prototype.IsDebuff(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_fired.prototype.IsPurgable(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_fired.prototype.OnCreated(self)
|
||||
if IsServer() then
|
||||
self:CheckBurnedState()
|
||||
self:StartIntervalThink(1)
|
||||
end
|
||||
end
|
||||
function modifier_general_fired.prototype.OnRefresh(self)
|
||||
if IsServer() then
|
||||
self:CheckBurnedState()
|
||||
end
|
||||
end
|
||||
function modifier_general_fired.prototype.OnDestroy(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
if self.particleId then
|
||||
ParticleManager:DestroyParticle(self.particleId, false)
|
||||
ParticleManager:ReleaseParticleIndex(self.particleId)
|
||||
end
|
||||
if self.burnedParticleId then
|
||||
ParticleManager:DestroyParticle(self.burnedParticleId, false)
|
||||
ParticleManager:ReleaseParticleIndex(self.burnedParticleId)
|
||||
end
|
||||
self.burnedParticleId = nil
|
||||
end
|
||||
function modifier_general_fired.prototype.OnIntervalThink(self)
|
||||
local frozeModifier = self:GetParent():FindModifierByName("modifier_general_froze")
|
||||
local frozeStacks = frozeModifier and frozeModifier:GetStackCount() or 0
|
||||
if self:GetStackCount() > 0 then
|
||||
local decreaseAmount = math.max(
|
||||
1,
|
||||
math.ceil(self:GetStackCount() * 0.1)
|
||||
)
|
||||
self:SetStackCount(self:GetStackCount() - decreaseAmount)
|
||||
self:SetDuration(1.01, true)
|
||||
else
|
||||
self:GetParent():RemoveModifierByName("modifier_general_fired")
|
||||
end
|
||||
if frozeStacks > 0 then
|
||||
local decreaseAmount = math.min(
|
||||
self:GetStackCount(),
|
||||
frozeStacks
|
||||
)
|
||||
self:SetStackCount(self:GetStackCount() - decreaseAmount)
|
||||
if frozeModifier then
|
||||
frozeModifier:SetStackCount(frozeStacks - decreaseAmount)
|
||||
end
|
||||
end
|
||||
if self:GetStackCount() > 0 then
|
||||
ApplyDamage({
|
||||
victim = self:GetParent(),
|
||||
attacker = self:GetCaster() or self:GetParent(),
|
||||
damage = self:GetStackCount() * 3,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
ability = self:GetAbility()
|
||||
})
|
||||
end
|
||||
end
|
||||
function modifier_general_fired.prototype.CheckState(self)
|
||||
if self.isBurned and self:GetStackCount() >= self.STACKS_TO_ARMOR_REDUCE then
|
||||
return {[MODIFIER_STATE_PASSIVES_DISABLED] = true}
|
||||
end
|
||||
return {}
|
||||
end
|
||||
function modifier_general_fired.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS, MODIFIER_PROPERTY_MAGICAL_RESISTANCE_BONUS, MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS}
|
||||
end
|
||||
function modifier_general_fired.prototype.GetModifierPhysicalArmorBonus(self)
|
||||
return self:GetStackCount() >= self.STACKS_TO_ARMOR_REDUCE and -self:GetStackCount() * 0.25 or 0
|
||||
end
|
||||
function modifier_general_fired.prototype.GetModifierMagicalResistanceBonus(self)
|
||||
return self:GetStackCount() >= self.STACKS_TO_ARMOR_REDUCE and -self:GetStackCount() * 0.25 or 0
|
||||
end
|
||||
function modifier_general_fired.prototype.GetEffectName(self)
|
||||
return "particles/units/heroes/hero_huskar/huskar_burning_spear_debuff.vpcf"
|
||||
end
|
||||
function modifier_general_fired.prototype.GetEffectAttachType(self)
|
||||
return PATTACH_ABSORIGIN_FOLLOW
|
||||
end
|
||||
function modifier_general_fired.prototype.CheckBurnedState(self)
|
||||
local parent = self:GetParent()
|
||||
if self:GetStackCount() >= self.STACKS_TO_BURN and not self.isBurned then
|
||||
self.isBurned = true
|
||||
EmitSoundOn("Hero_Huskar.BurningSpear.Target", parent)
|
||||
elseif self:GetStackCount() < self.STACKS_TO_BURN and self.isBurned then
|
||||
self.isBurned = false
|
||||
if self.burnedParticleId then
|
||||
ParticleManager:DestroyParticle(self.burnedParticleId, false)
|
||||
ParticleManager:ReleaseParticleIndex(self.burnedParticleId)
|
||||
self.burnedParticleId = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
modifier_general_fired = __TS__Decorate(
|
||||
modifier_general_fired,
|
||||
modifier_general_fired,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_general_fired"}
|
||||
)
|
||||
____exports.modifier_general_fired = modifier_general_fired
|
||||
return ____exports
|
||||
@@ -0,0 +1,133 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_general_froze = __TS__Class()
|
||||
local modifier_general_froze = ____exports.modifier_general_froze
|
||||
modifier_general_froze.name = "modifier_general_froze"
|
||||
modifier_general_froze.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_froze.lua"
|
||||
__TS__ClassExtends(modifier_general_froze, BaseModifier)
|
||||
function modifier_general_froze.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.isFrozen = false
|
||||
self.STACKS_TO_FREEZE = 100
|
||||
self.STACKS_TO_DAMAGEUP = 30
|
||||
end
|
||||
function modifier_general_froze.prototype.IsDebuff(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_froze.prototype.IsPurgable(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_froze.prototype.OnCreated(self)
|
||||
if IsServer() then
|
||||
self:CheckFrozenState()
|
||||
self:StartIntervalThink(1)
|
||||
end
|
||||
end
|
||||
function modifier_general_froze.prototype.OnRefresh(self)
|
||||
if IsServer() then
|
||||
self:CheckFrozenState()
|
||||
end
|
||||
end
|
||||
function modifier_general_froze.prototype.OnDestroy(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
if self.particleId then
|
||||
ParticleManager:DestroyParticle(self.particleId, false)
|
||||
ParticleManager:ReleaseParticleIndex(self.particleId)
|
||||
end
|
||||
if self.frozenParticleId then
|
||||
ParticleManager:DestroyParticle(self.frozenParticleId, false)
|
||||
ParticleManager:ReleaseParticleIndex(self.frozenParticleId)
|
||||
end
|
||||
self.frozenParticleId = nil
|
||||
end
|
||||
function modifier_general_froze.prototype.OnIntervalThink(self)
|
||||
if not self:GetParent() then
|
||||
return
|
||||
end
|
||||
if "modifier_general_fired" ~= nil then
|
||||
local firedModifier = self:GetParent():FindModifierByName("modifier_general_fired")
|
||||
local firedStacks = firedModifier and firedModifier:GetStackCount() or 0
|
||||
if self:GetStackCount() > 0 then
|
||||
local decreaseAmount = math.max(
|
||||
1,
|
||||
math.ceil(self:GetStackCount() * 0.1)
|
||||
)
|
||||
self:SetStackCount(self:GetStackCount() - decreaseAmount)
|
||||
self:SetDuration(1.01, true)
|
||||
else
|
||||
self:GetParent():RemoveModifierByName("modifier_general_froze")
|
||||
end
|
||||
if firedStacks > 0 then
|
||||
local decreaseAmount = math.min(
|
||||
self:GetStackCount(),
|
||||
firedStacks
|
||||
)
|
||||
self:SetStackCount(self:GetStackCount() - decreaseAmount)
|
||||
if firedModifier then
|
||||
firedModifier:SetStackCount(firedStacks - decreaseAmount)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function modifier_general_froze.prototype.CheckState(self)
|
||||
if self.isFrozen and self:GetParent():IsBoss() then
|
||||
return {[MODIFIER_STATE_FROZEN] = true, [MODIFIER_STATE_ROOTED] = true}
|
||||
end
|
||||
return {}
|
||||
end
|
||||
function modifier_general_froze.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE, MODIFIER_PROPERTY_ATTACKSPEED_PERCENTAGE, MODIFIER_PROPERTY_INCOMING_DAMAGE_PERCENTAGE, MODIFIER_PROPERTY_HEALTH_REGEN_PERCENTAGE}
|
||||
end
|
||||
function modifier_general_froze.prototype.GetModifierMoveSpeedBonus_Percentage(self)
|
||||
return -self:GetStackCount()
|
||||
end
|
||||
function modifier_general_froze.prototype.GetModifierAttackSpeedPercentage(self)
|
||||
return -self:GetStackCount()
|
||||
end
|
||||
function modifier_general_froze.prototype.GetEffectName(self)
|
||||
return "particles/generic_gameplay/generic_slowed_cold.vpcf"
|
||||
end
|
||||
function modifier_general_froze.prototype.GetModifierIncomingDamage_Percentage(self)
|
||||
return self:GetStackCount() >= self.STACKS_TO_DAMAGEUP and self:GetStackCount() or 0
|
||||
end
|
||||
function modifier_general_froze.prototype.GetModifierHealthRegenPercentage(self)
|
||||
return -self:GetStackCount() * 0.01
|
||||
end
|
||||
function modifier_general_froze.prototype.GetEffectAttachType(self)
|
||||
return PATTACH_ABSORIGIN_FOLLOW
|
||||
end
|
||||
function modifier_general_froze.prototype.CheckFrozenState(self)
|
||||
local parent = self:GetParent()
|
||||
if self:GetStackCount() >= self.STACKS_TO_FREEZE and not self.isFrozen then
|
||||
self.isFrozen = true
|
||||
self.frozenParticleId = ParticleManager:CreateParticle("particles/units/heroes/hero_crystalmaiden/maiden_frostbite_buff.vpcf", PATTACH_ABSORIGIN_FOLLOW, parent)
|
||||
EmitSoundOn("Hero_Ancient_Apparition.ColdFeetCast", parent)
|
||||
elseif self:GetStackCount() < self.STACKS_TO_FREEZE and self.isFrozen then
|
||||
self.isFrozen = false
|
||||
if self.frozenParticleId then
|
||||
ParticleManager:DestroyParticle(self.frozenParticleId, false)
|
||||
ParticleManager:ReleaseParticleIndex(self.frozenParticleId)
|
||||
self.frozenParticleId = nil
|
||||
end
|
||||
parent:RemoveModifierByName("modifier_general_silenced")
|
||||
end
|
||||
end
|
||||
function modifier_general_froze.prototype.GetModifierStateImmune(self)
|
||||
return {[MODIFIER_STATE_FROZEN] = true, [MODIFIER_STATE_ROOTED] = true}
|
||||
end
|
||||
modifier_general_froze = __TS__Decorate(
|
||||
modifier_general_froze,
|
||||
modifier_general_froze,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_general_froze"}
|
||||
)
|
||||
____exports.modifier_general_froze = modifier_general_froze
|
||||
return ____exports
|
||||
@@ -0,0 +1,223 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_general_hunger = __TS__Class()
|
||||
local modifier_general_hunger = ____exports.modifier_general_hunger
|
||||
modifier_general_hunger.name = "modifier_general_hunger"
|
||||
modifier_general_hunger.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_hunger.lua"
|
||||
__TS__ClassExtends(modifier_general_hunger, BaseModifier)
|
||||
function modifier_general_hunger.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.maxstack = 100
|
||||
end
|
||||
function modifier_general_hunger.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_hunger.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_hunger.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_hunger.prototype.OnCreated(self, params)
|
||||
if IsServer() then
|
||||
self:SetDuration(3.01, true)
|
||||
self:StartIntervalThink(3)
|
||||
end
|
||||
end
|
||||
function modifier_general_hunger.prototype.OnRefresh(self, params)
|
||||
if IsServer() then
|
||||
self:SetDuration(3.01, true)
|
||||
self:StartIntervalThink(3)
|
||||
end
|
||||
end
|
||||
function modifier_general_hunger.prototype.OnIntervalThink(self)
|
||||
if IsServer() then
|
||||
self:SetStackCount(self:GetStackCount() - 1)
|
||||
self:SetDuration(3.01, true)
|
||||
if self:GetStackCount() < 1 then
|
||||
self:Destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
function modifier_general_hunger.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_STATS_AGILITY_BONUS, MODIFIER_PROPERTY_STATS_INTELLECT_BONUS, MODIFIER_PROPERTY_STATS_STRENGTH_BONUS}
|
||||
end
|
||||
function modifier_general_hunger.prototype.GetModifierBonusStats_Strength(self)
|
||||
if not IsServer() then
|
||||
return 0
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
if not parent then
|
||||
return 0
|
||||
end
|
||||
if not parent:IsRealHero() then
|
||||
return 0
|
||||
end
|
||||
do
|
||||
local function ____catch(e)
|
||||
return true, 0
|
||||
end
|
||||
local ____try, ____hasReturned, ____returnValue = pcall(function()
|
||||
local hero = parent
|
||||
local baseStr = hero:GetBaseStrength() or 0
|
||||
return true, math.ceil(baseStr * (self:GetStackCount() * 0.01))
|
||||
end)
|
||||
if not ____try then
|
||||
____hasReturned, ____returnValue = ____catch(____hasReturned)
|
||||
end
|
||||
if ____hasReturned then
|
||||
return ____returnValue
|
||||
end
|
||||
end
|
||||
end
|
||||
function modifier_general_hunger.prototype.GetModifierBonusStats_Agility(self)
|
||||
if not IsServer() then
|
||||
return 0
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
if not parent then
|
||||
return 0
|
||||
end
|
||||
if not parent:IsRealHero() then
|
||||
return 0
|
||||
end
|
||||
local hero = parent
|
||||
local baseAgi = hero:GetBaseAgility()
|
||||
return math.ceil(baseAgi * (self:GetStackCount() * 0.01))
|
||||
end
|
||||
function modifier_general_hunger.prototype.GetModifierBonusStats_Intellect(self)
|
||||
if not IsServer() then
|
||||
return 0
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
if not parent then
|
||||
return 0
|
||||
end
|
||||
if not parent:IsRealHero() then
|
||||
return 0
|
||||
end
|
||||
do
|
||||
local function ____catch(e)
|
||||
return true, 0
|
||||
end
|
||||
local ____try, ____hasReturned, ____returnValue = pcall(function()
|
||||
local hero = parent
|
||||
local baseInt = hero:GetBaseIntellect() or 0
|
||||
return true, math.ceil(baseInt * (self:GetStackCount() * 0.01))
|
||||
end)
|
||||
if not ____try then
|
||||
____hasReturned, ____returnValue = ____catch(____hasReturned)
|
||||
end
|
||||
if ____hasReturned then
|
||||
return ____returnValue
|
||||
end
|
||||
end
|
||||
end
|
||||
function modifier_general_hunger.prototype.IncrementStackCount(self)
|
||||
if self:GetStackCount() >= self.maxstack then
|
||||
self:SetStackCount(self.maxstack)
|
||||
else
|
||||
BaseModifier.prototype.SetStackCount(
|
||||
self,
|
||||
self:GetStackCount() + 1
|
||||
)
|
||||
end
|
||||
end
|
||||
function modifier_general_hunger.prototype.GetTexture(self)
|
||||
return "life_stealer_rage"
|
||||
end
|
||||
modifier_general_hunger = __TS__Decorate(
|
||||
modifier_general_hunger,
|
||||
modifier_general_hunger,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_general_hunger"}
|
||||
)
|
||||
____exports.modifier_general_hunger = modifier_general_hunger
|
||||
--- Несколько экземпляров на юните — у каждого свой таймер (каждый приём пищи живёт 60 сек).
|
||||
____exports.modifier_general_hunger_fulled = __TS__Class()
|
||||
local modifier_general_hunger_fulled = ____exports.modifier_general_hunger_fulled
|
||||
modifier_general_hunger_fulled.name = "modifier_general_hunger_fulled"
|
||||
modifier_general_hunger_fulled.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_hunger.lua"
|
||||
__TS__ClassExtends(modifier_general_hunger_fulled, BaseModifier)
|
||||
function modifier_general_hunger_fulled.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_hunger_fulled.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_hunger_fulled.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_hunger_fulled.prototype.GetAttributes(self)
|
||||
return MODIFIER_ATTRIBUTE_MULTIPLE
|
||||
end
|
||||
function modifier_general_hunger_fulled.prototype.OnCreated(self, params)
|
||||
if IsServer() then
|
||||
local duration = params.duration or 60
|
||||
self:SetDuration(duration, true)
|
||||
end
|
||||
end
|
||||
modifier_general_hunger_fulled = __TS__Decorate(
|
||||
modifier_general_hunger_fulled,
|
||||
modifier_general_hunger_fulled,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_general_hunger_fulled"}
|
||||
)
|
||||
____exports.modifier_general_hunger_fulled = modifier_general_hunger_fulled
|
||||
--- Максимум «слотов» сытости для еды с баффами (энерго-напиток и т.п.). Каждый слот = один приём, свой таймер 60 сек.
|
||||
____exports.BUFF_FOOD_MAX_SLOTS = 3
|
||||
--- Слот сытости от еды с баффами. Вешается только такими предметами (energy_drink и т.д.). Лимит BUFF_FOOD_MAX_SLOTS штук.
|
||||
____exports.modifier_buff_food_slot = __TS__Class()
|
||||
local modifier_buff_food_slot = ____exports.modifier_buff_food_slot
|
||||
modifier_buff_food_slot.name = "modifier_buff_food_slot"
|
||||
modifier_buff_food_slot.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_hunger.lua"
|
||||
__TS__ClassExtends(modifier_buff_food_slot, BaseModifier)
|
||||
function modifier_buff_food_slot.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_buff_food_slot.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_buff_food_slot.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_buff_food_slot.prototype.GetAttributes(self)
|
||||
return MODIFIER_ATTRIBUTE_MULTIPLE
|
||||
end
|
||||
function modifier_buff_food_slot.prototype.OnCreated(self, params)
|
||||
if IsServer() then
|
||||
local duration = params.duration or 60
|
||||
self:SetDuration(duration, true)
|
||||
end
|
||||
end
|
||||
function modifier_buff_food_slot.prototype.GetTexture(self)
|
||||
return "life_stealer_rage"
|
||||
end
|
||||
modifier_buff_food_slot = __TS__Decorate(
|
||||
modifier_buff_food_slot,
|
||||
modifier_buff_food_slot,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_buff_food_slot"}
|
||||
)
|
||||
____exports.modifier_buff_food_slot = modifier_buff_food_slot
|
||||
--- Считает, сколько слотов бафф-еды сейчас на юните (для проверки лимита).
|
||||
function ____exports.getBuffFoodSlotCount(self, unit)
|
||||
local count = 0
|
||||
do
|
||||
local i = 0
|
||||
while i < unit:GetModifierCount() do
|
||||
if unit:GetModifierNameByIndex(i) == ____exports.modifier_buff_food_slot.name then
|
||||
count = count + 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
return ____exports
|
||||
@@ -0,0 +1,154 @@
|
||||
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 BaseModifierMotionBoth = ____dota_ts_adapter.BaseModifierMotionBoth
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_general_knockback = __TS__Class()
|
||||
local modifier_general_knockback = ____exports.modifier_general_knockback
|
||||
modifier_general_knockback.name = "modifier_general_knockback"
|
||||
modifier_general_knockback.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_knockback.lua"
|
||||
__TS__ClassExtends(modifier_general_knockback, BaseModifierMotionBoth)
|
||||
function modifier_general_knockback.prototype.____constructor(self, ...)
|
||||
BaseModifierMotionBoth.prototype.____constructor(self, ...)
|
||||
self.distance = 0
|
||||
self.height = 0
|
||||
self.duration = 0
|
||||
self.anim = 0
|
||||
self.direction = 0
|
||||
self.tree = 0
|
||||
self.hVelocity = 0
|
||||
self.vVelocity = 0
|
||||
self.gravity = 0
|
||||
self.stun = false
|
||||
self.flail = false
|
||||
self.interrupted = false
|
||||
end
|
||||
function modifier_general_knockback.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_knockback.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_general_knockback.prototype.GetAttributes(self)
|
||||
return MODIFIER_ATTRIBUTE_MULTIPLE
|
||||
end
|
||||
function modifier_general_knockback.prototype.OnCreated(self, params)
|
||||
if IsServer() then
|
||||
self.distance = params.distance or 0
|
||||
self.height = params.height or 0
|
||||
self.duration = params.duration or 0
|
||||
if not not params.direction_x and not not params.direction_y then
|
||||
self.direction = Vector(params.direction_x, params.direction_y, 0):Normalized()
|
||||
else
|
||||
self.direction = -self:GetParent():GetForwardVector()
|
||||
end
|
||||
self.tree = params.tree_destroy_radius or self:GetParent():GetHullRadius()
|
||||
self.stun = not not params.isStun
|
||||
self.flail = not not params.isFlail
|
||||
if self.duration == 0 then
|
||||
return self:Destroy()
|
||||
end
|
||||
self.parent = self:GetParent()
|
||||
self.origin = self.parent:GetOrigin()
|
||||
self.hVelocity = self.distance / self.duration
|
||||
local half_duration = self.duration / 2
|
||||
self.gravity = 2 * self.height / (half_duration * half_duration)
|
||||
self.vVelocity = self.gravity * half_duration
|
||||
if self.distance > 0 then
|
||||
if self:ApplyHorizontalMotionController() == false then
|
||||
return self:Destroy()
|
||||
end
|
||||
end
|
||||
if self.height >= 0 then
|
||||
if self:ApplyVerticalMotionController() == false then
|
||||
return self:Destroy()
|
||||
end
|
||||
end
|
||||
if self.flail then
|
||||
self:SetStackCount(1)
|
||||
elseif self.stun then
|
||||
self:SetStackCount(2)
|
||||
end
|
||||
else
|
||||
self.anim = self:GetStackCount()
|
||||
self:SetStackCount(0)
|
||||
end
|
||||
end
|
||||
function modifier_general_knockback.prototype.OnDestroy(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
if not self.interrupted then
|
||||
if self.tree > 0 then
|
||||
GridNav:DestroyTreesAroundPoint(
|
||||
self.parent:GetOrigin(),
|
||||
self.tree,
|
||||
true
|
||||
)
|
||||
end
|
||||
end
|
||||
self.parent:InterruptMotionControllers(true)
|
||||
end
|
||||
function modifier_general_knockback.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_OVERRIDE_ANIMATION}
|
||||
end
|
||||
function modifier_general_knockback.prototype.GetOverrideAnimation(self)
|
||||
if self.anim == 1 then
|
||||
return ACT_DOTA_FLAIL
|
||||
elseif self.anim == 2 then
|
||||
return ACT_DOTA_DISABLED
|
||||
end
|
||||
return ACT_DOTA_FLAIL
|
||||
end
|
||||
function modifier_general_knockback.prototype.CheckState(self)
|
||||
return {[MODIFIER_STATE_STUNNED] = self.stun}
|
||||
end
|
||||
function modifier_general_knockback.prototype.UpdateHorizontalMotion(self, me, dt)
|
||||
local target = self.direction * self.distance * (dt / self.duration)
|
||||
self.parent:SetOrigin(self.parent:GetOrigin() + target)
|
||||
end
|
||||
function modifier_general_knockback.prototype.UpdateVerticalMotion(self, me, dt)
|
||||
local time = dt / self.duration
|
||||
self.parent:SetOrigin(self.parent:GetOrigin() + Vector(0, 0, self.vVelocity * dt))
|
||||
self.vVelocity = self.vVelocity - self.gravity * dt
|
||||
end
|
||||
function modifier_general_knockback.prototype.OnHorizontalMotionInterrupted(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
self.interrupted = true
|
||||
self:Destroy()
|
||||
end
|
||||
function modifier_general_knockback.prototype.OnVerticalMotionInterrupted(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
self.interrupted = true
|
||||
self:Destroy()
|
||||
end
|
||||
function modifier_general_knockback.prototype.GetEffectName(self)
|
||||
if IsClient() then
|
||||
return ""
|
||||
end
|
||||
if self.stun then
|
||||
return "particles/generic_gameplay/generic_stunned.vpcf"
|
||||
end
|
||||
return ""
|
||||
end
|
||||
function modifier_general_knockback.prototype.GetEffectAttachType(self)
|
||||
if IsClient() then
|
||||
return PATTACH_INVALID
|
||||
end
|
||||
return PATTACH_OVERHEAD_FOLLOW
|
||||
end
|
||||
modifier_general_knockback = __TS__Decorate(
|
||||
modifier_general_knockback,
|
||||
modifier_general_knockback,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_general_knockback"}
|
||||
)
|
||||
____exports.modifier_general_knockback = modifier_general_knockback
|
||||
return ____exports
|
||||
@@ -0,0 +1,36 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_general_silenced = __TS__Class()
|
||||
local modifier_general_silenced = ____exports.modifier_general_silenced
|
||||
modifier_general_silenced.name = "modifier_general_silenced"
|
||||
modifier_general_silenced.____file_path = "scripts/vscripts/abilities/modifiers/modifier_general_silenced.lua"
|
||||
__TS__ClassExtends(modifier_general_silenced, BaseModifier)
|
||||
function modifier_general_silenced.prototype.IsDebuff(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_silenced.prototype.IsPurgable(self)
|
||||
return true
|
||||
end
|
||||
function modifier_general_silenced.prototype.CheckState(self)
|
||||
return {[MODIFIER_STATE_SILENCED] = true}
|
||||
end
|
||||
function modifier_general_silenced.prototype.GetEffectName(self)
|
||||
return "particles/generic_gameplay/generic_silenced.vpcf"
|
||||
end
|
||||
function modifier_general_silenced.prototype.GetEffectAttachType(self)
|
||||
return PATTACH_OVERHEAD_FOLLOW
|
||||
end
|
||||
modifier_general_silenced = __TS__Decorate(
|
||||
modifier_general_silenced,
|
||||
modifier_general_silenced,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_general_silenced"}
|
||||
)
|
||||
____exports.modifier_general_silenced = modifier_general_silenced
|
||||
return ____exports
|
||||
@@ -0,0 +1,154 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
local ____modifier_general_arc = require("abilities.modifiers.modifier_general_arc")
|
||||
local modifier_general_arc = ____modifier_general_arc.modifier_general_arc
|
||||
____exports.KITTY_FLEX_CATAKEET_MODEL = "models/items/courier/catakeet/catakeet_head_curious.vmdl"
|
||||
--- Декоративная головка-курьер для эффекта kitty_flex: без выделения, урона и коллизий.
|
||||
____exports.modifier_kitty_flex_catakeet = __TS__Class()
|
||||
local modifier_kitty_flex_catakeet = ____exports.modifier_kitty_flex_catakeet
|
||||
modifier_kitty_flex_catakeet.name = "modifier_kitty_flex_catakeet"
|
||||
modifier_kitty_flex_catakeet.____file_path = "scripts/vscripts/abilities/modifiers/modifier_kitty_flex_catakeet.lua"
|
||||
__TS__ClassExtends(modifier_kitty_flex_catakeet, BaseModifier)
|
||||
function modifier_kitty_flex_catakeet.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.bounceRadiusMin = 80
|
||||
self.bounceRadiusMax = 360
|
||||
self.bounceHeightMin = 110
|
||||
self.bounceHeightMax = 220
|
||||
self.bounceIntervalMin = 0.55
|
||||
self.bounceIntervalMax = 1
|
||||
self.lookIntervalMin = 0.35
|
||||
self.lookIntervalMax = 0.75
|
||||
self.nextLookAt = 0
|
||||
self.nextJumpAt = 0
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.OnCreated(self, params)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self.bounceRadiusMin = params.bounce_radius_min or self.bounceRadiusMin
|
||||
self.bounceRadiusMax = params.bounce_radius_max or self.bounceRadiusMax
|
||||
self.bounceHeightMin = params.bounce_height_min or self.bounceHeightMin
|
||||
self.bounceHeightMax = params.bounce_height_max or self.bounceHeightMax
|
||||
self.bounceIntervalMin = params.bounce_interval_min or self.bounceIntervalMin
|
||||
self.bounceIntervalMax = params.bounce_interval_max or self.bounceIntervalMax
|
||||
self.lookIntervalMin = params.look_interval_min or self.lookIntervalMin
|
||||
self.lookIntervalMax = params.look_interval_max or self.lookIntervalMax
|
||||
local parent = self:GetParent()
|
||||
parent:SetModel(____exports.KITTY_FLEX_CATAKEET_MODEL)
|
||||
parent:SetOriginalModel(____exports.KITTY_FLEX_CATAKEET_MODEL)
|
||||
parent:SetModelScale(1.35)
|
||||
parent:SetHullRadius(1)
|
||||
parent:SetControllableByPlayer(-1, false)
|
||||
parent:SetMoveCapability(DOTA_UNIT_CAP_MOVE_GROUND)
|
||||
parent:SetAttackCapability(DOTA_UNIT_CAP_NO_ATTACK)
|
||||
local now = GameRules:GetGameTime()
|
||||
self.nextLookAt = now + RandomFloat(0.05, 0.25)
|
||||
self.nextJumpAt = now + RandomFloat(self.bounceIntervalMin, self.bounceIntervalMax)
|
||||
self:StartIntervalThink(0.1)
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.OnIntervalThink(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
if not parent or parent:IsNull() or not IsValidEntity(parent) then
|
||||
return
|
||||
end
|
||||
local hero = self:GetCaster()
|
||||
local now = GameRules:GetGameTime()
|
||||
if now >= self.nextLookAt and hero and IsValidEntity(hero) and not hero:IsNull() then
|
||||
parent:FaceTowards(hero:GetAbsOrigin())
|
||||
self.nextLookAt = now + RandomFloat(self.lookIntervalMin, self.lookIntervalMax)
|
||||
end
|
||||
if now < self.nextJumpAt or parent:HasModifier(modifier_general_arc.name) then
|
||||
return
|
||||
end
|
||||
self:performBounceJumpNearHero(parent, hero)
|
||||
self.nextJumpAt = now + RandomFloat(self.bounceIntervalMin, self.bounceIntervalMax)
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.performBounceJumpNearHero(self, parent, hero)
|
||||
local parentOrigin = parent:GetAbsOrigin()
|
||||
local targetPos = parentOrigin
|
||||
if hero and IsValidEntity(hero) and not hero:IsNull() then
|
||||
local heroOrigin = hero:GetAbsOrigin()
|
||||
local angle = RandomFloat(0, 2 * math.pi)
|
||||
local distance = RandomFloat(self.bounceRadiusMin, self.bounceRadiusMax)
|
||||
targetPos = Vector(
|
||||
heroOrigin.x + math.cos(angle) * distance,
|
||||
heroOrigin.y + math.sin(angle) * distance,
|
||||
heroOrigin.z
|
||||
)
|
||||
targetPos = GetGroundPosition(targetPos, parent)
|
||||
else
|
||||
local randomOffset = RandomVector(RandomFloat(self.bounceRadiusMin * 0.4, self.bounceRadiusMax * 0.6))
|
||||
targetPos = GetGroundPosition(
|
||||
parentOrigin + Vector(randomOffset.x, randomOffset.y, 0),
|
||||
parent
|
||||
)
|
||||
end
|
||||
local jumpDirection = targetPos - parentOrigin
|
||||
if jumpDirection:Length2D() > 16 then
|
||||
parent:SetForwardVector(jumpDirection:Normalized())
|
||||
end
|
||||
local jumpDistance = jumpDirection:Length2D()
|
||||
modifier_general_arc:apply(
|
||||
parent,
|
||||
hero or parent,
|
||||
nil,
|
||||
{
|
||||
x = targetPos.x,
|
||||
y = targetPos.y,
|
||||
z = targetPos.z,
|
||||
duration = RandomFloat(0.28, 0.42),
|
||||
distance = jumpDistance,
|
||||
height = RandomFloat(self.bounceHeightMin, self.bounceHeightMax),
|
||||
isFlail = true
|
||||
}
|
||||
)
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local parent = self:GetParent()
|
||||
if parent and IsValidEntity(parent) and not parent:IsNull() then
|
||||
UTIL_Remove(parent)
|
||||
end
|
||||
end
|
||||
function modifier_kitty_flex_catakeet.prototype.CheckState(self)
|
||||
return {
|
||||
[MODIFIER_STATE_INVULNERABLE] = true,
|
||||
[MODIFIER_STATE_UNSELECTABLE] = true,
|
||||
[MODIFIER_STATE_UNTARGETABLE] = true,
|
||||
[MODIFIER_STATE_NO_HEALTH_BAR] = true,
|
||||
[MODIFIER_STATE_NOT_ON_MINIMAP] = true,
|
||||
[MODIFIER_STATE_NO_UNIT_COLLISION] = true,
|
||||
[MODIFIER_STATE_DISARMED] = true,
|
||||
[MODIFIER_STATE_COMMAND_RESTRICTED] = true,
|
||||
[MODIFIER_STATE_IGNORING_MOVE_AND_ATTACK_ORDERS] = true
|
||||
}
|
||||
end
|
||||
modifier_kitty_flex_catakeet = __TS__Decorate(
|
||||
modifier_kitty_flex_catakeet,
|
||||
modifier_kitty_flex_catakeet,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_kitty_flex_catakeet"}
|
||||
)
|
||||
____exports.modifier_kitty_flex_catakeet = modifier_kitty_flex_catakeet
|
||||
return ____exports
|
||||
@@ -0,0 +1,64 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_swamp_slow = __TS__Class()
|
||||
local modifier_swamp_slow = ____exports.modifier_swamp_slow
|
||||
modifier_swamp_slow.name = "modifier_swamp_slow"
|
||||
modifier_swamp_slow.____file_path = "scripts/vscripts/abilities/modifiers/modifier_swamp_slow.lua"
|
||||
__TS__ClassExtends(modifier_swamp_slow, BaseModifier)
|
||||
function modifier_swamp_slow.prototype.OnCreated(self)
|
||||
self:StartIntervalThink(0.33)
|
||||
end
|
||||
function modifier_swamp_slow.prototype.OnIntervalThink(self)
|
||||
if IsClient() then
|
||||
return
|
||||
end
|
||||
local movespeed = self:GetParent():GetMoveSpeedModifier(
|
||||
self:GetParent():GetBaseMoveSpeed(),
|
||||
false
|
||||
)
|
||||
local damagetable = {
|
||||
victim = self:GetParent(),
|
||||
attacker = self:GetParent(),
|
||||
damage = self:GetStackCount() * 1,
|
||||
damage_type = DAMAGE_TYPE_PURE
|
||||
}
|
||||
ApplyDamage({
|
||||
victim = damagetable.victim,
|
||||
attacker = damagetable.attacker,
|
||||
damage = movespeed <= 100 and damagetable.damage + self:GetParent():GetMaxHealth() * 0.01 or damagetable.damage,
|
||||
damage_type = damagetable.damage_type
|
||||
})
|
||||
self:IncrementStackCount()
|
||||
end
|
||||
function modifier_swamp_slow.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_swamp_slow.prototype.IsDebuff(self)
|
||||
return true
|
||||
end
|
||||
function modifier_swamp_slow.prototype.IsPurgable(self)
|
||||
return true
|
||||
end
|
||||
function modifier_swamp_slow.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MOVESPEED_BONUS_CONSTANT}
|
||||
end
|
||||
function modifier_swamp_slow.prototype.GetModifierMoveSpeedBonus_Constant(self)
|
||||
return -30
|
||||
end
|
||||
function modifier_swamp_slow.prototype.GetTexture(self)
|
||||
return "night_stalker_darkness"
|
||||
end
|
||||
modifier_swamp_slow = __TS__Decorate(
|
||||
modifier_swamp_slow,
|
||||
modifier_swamp_slow,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_swamp_slow"}
|
||||
)
|
||||
____exports.modifier_swamp_slow = modifier_swamp_slow
|
||||
return ____exports
|
||||
@@ -0,0 +1,123 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_vampirism = __TS__Class()
|
||||
local modifier_vampirism = ____exports.modifier_vampirism
|
||||
modifier_vampirism.name = "modifier_vampirism"
|
||||
modifier_vampirism.____file_path = "scripts/vscripts/abilities/modifiers/modifier_vampirism.lua"
|
||||
__TS__ClassExtends(modifier_vampirism, BaseModifier)
|
||||
function modifier_vampirism.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_vampirism.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_vampirism.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_vampirism.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_EVENT_ON_ATTACK_LANDED, MODIFIER_EVENT_ON_TAKEDAMAGE}
|
||||
end
|
||||
function modifier_vampirism.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_vampirism.prototype.OnAttackLanded(self, event)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if event.attacker ~= self:GetParent() then
|
||||
return
|
||||
end
|
||||
local hero = self:GetParent()
|
||||
local physicalVampirism = getPhysicalVampirism(nil, hero)
|
||||
if physicalVampirism <= 0 then
|
||||
return
|
||||
end
|
||||
local attackDamage = event.damage or 0
|
||||
if attackDamage <= 0 then
|
||||
return
|
||||
end
|
||||
local healAmount = attackDamage * physicalVampirism / 100
|
||||
if healAmount <= 0 then
|
||||
return
|
||||
end
|
||||
hero:HealWithParams(
|
||||
healAmount,
|
||||
self:GetAbility(),
|
||||
false,
|
||||
true,
|
||||
hero,
|
||||
false
|
||||
)
|
||||
SendOverheadEventMessage(
|
||||
nil,
|
||||
OVERHEAD_ALERT_HEAL,
|
||||
hero,
|
||||
healAmount,
|
||||
hero:GetPlayerOwner()
|
||||
)
|
||||
self:CreateVampirismEffect(event.target)
|
||||
end
|
||||
function modifier_vampirism.prototype.OnTakeDamage(self, event)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
if event.attacker ~= self:GetParent() then
|
||||
return
|
||||
end
|
||||
local hero = self:GetParent()
|
||||
local magicalVampirism = getMagicalVampirism(nil, hero)
|
||||
if magicalVampirism <= 0 then
|
||||
return
|
||||
end
|
||||
local damage = event.damage
|
||||
local healAmount = 0
|
||||
if magicalVampirism > 0 and event.inflictor ~= nil then
|
||||
local magicalHeal = damage * magicalVampirism / 100
|
||||
healAmount = healAmount + magicalHeal
|
||||
end
|
||||
if healAmount > 0 then
|
||||
hero:HealWithParams(
|
||||
healAmount,
|
||||
self:GetAbility(),
|
||||
false,
|
||||
true,
|
||||
hero,
|
||||
false
|
||||
)
|
||||
SendOverheadEventMessage(
|
||||
nil,
|
||||
OVERHEAD_ALERT_HEAL,
|
||||
hero,
|
||||
healAmount,
|
||||
hero:GetPlayerOwner()
|
||||
)
|
||||
self:CreateVampirismEffect(event.unit)
|
||||
end
|
||||
end
|
||||
function modifier_vampirism.prototype.CreateVampirismEffect(self, target)
|
||||
local attackerParticle = ParticleManager:CreateParticle(
|
||||
"particles/units/heroes/hero_bloodseeker/bloodseeker_bloodbath.vpcf",
|
||||
PATTACH_ABSORIGIN_FOLLOW,
|
||||
self:GetParent()
|
||||
)
|
||||
ParticleManager:SetParticleControl(
|
||||
attackerParticle,
|
||||
0,
|
||||
self:GetParent():GetAbsOrigin()
|
||||
)
|
||||
ParticleManager:ReleaseParticleIndex(attackerParticle)
|
||||
end
|
||||
modifier_vampirism = __TS__Decorate(
|
||||
modifier_vampirism,
|
||||
modifier_vampirism,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_vampirism"}
|
||||
)
|
||||
____exports.modifier_vampirism = modifier_vampirism
|
||||
return ____exports
|
||||
@@ -0,0 +1,58 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
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 PET_PIG_EVENT_INCOMING_SOURCE = "modifier_pet_buff_npc_pig_event"
|
||||
____exports.modifier_pet_buff_npc_pig_event = __TS__Class()
|
||||
local modifier_pet_buff_npc_pig_event = ____exports.modifier_pet_buff_npc_pig_event
|
||||
modifier_pet_buff_npc_pig_event.name = "modifier_pet_buff_npc_pig_event"
|
||||
modifier_pet_buff_npc_pig_event.____file_path = "scripts/vscripts/abilities/modifiers/pets/modifier_pet_buff_npc_pig_event.lua"
|
||||
__TS__ClassExtends(modifier_pet_buff_npc_pig_event, BaseModifier)
|
||||
function modifier_pet_buff_npc_pig_event.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_pig_event.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_pig_event.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_pig_event.prototype.OnCreated(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
setIncomingDamageReductionSource(
|
||||
nil,
|
||||
self:GetParent(),
|
||||
PET_PIG_EVENT_INCOMING_SOURCE,
|
||||
function() return 10 end
|
||||
)
|
||||
end
|
||||
function modifier_pet_buff_npc_pig_event.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
removeIncomingDamageReductionSource(
|
||||
nil,
|
||||
self:GetParent(),
|
||||
PET_PIG_EVENT_INCOMING_SOURCE
|
||||
)
|
||||
end
|
||||
function modifier_pet_buff_npc_pig_event.prototype.GetTexture(self)
|
||||
return "primal_beast_onslaught"
|
||||
end
|
||||
modifier_pet_buff_npc_pig_event = __TS__Decorate(
|
||||
modifier_pet_buff_npc_pig_event,
|
||||
modifier_pet_buff_npc_pig_event,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_pet_buff_npc_pig_event"}
|
||||
)
|
||||
____exports.modifier_pet_buff_npc_pig_event = modifier_pet_buff_npc_pig_event
|
||||
return ____exports
|
||||
@@ -0,0 +1,39 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_pet_buff_npc_squirrel_event = __TS__Class()
|
||||
local modifier_pet_buff_npc_squirrel_event = ____exports.modifier_pet_buff_npc_squirrel_event
|
||||
modifier_pet_buff_npc_squirrel_event.name = "modifier_pet_buff_npc_squirrel_event"
|
||||
modifier_pet_buff_npc_squirrel_event.____file_path = "scripts/vscripts/abilities/modifiers/pets/modifier_pet_buff_npc_squirrel_event.lua"
|
||||
__TS__ClassExtends(modifier_pet_buff_npc_squirrel_event, BaseModifier)
|
||||
function modifier_pet_buff_npc_squirrel_event.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_squirrel_event.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_squirrel_event.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_squirrel_event.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_EXP_RATE_BOOST}
|
||||
end
|
||||
function modifier_pet_buff_npc_squirrel_event.prototype.GetModifierPercentageExpRateBoost(self)
|
||||
return 35
|
||||
end
|
||||
function modifier_pet_buff_npc_squirrel_event.prototype.GetTexture(self)
|
||||
return "default_items/xp"
|
||||
end
|
||||
modifier_pet_buff_npc_squirrel_event = __TS__Decorate(
|
||||
modifier_pet_buff_npc_squirrel_event,
|
||||
modifier_pet_buff_npc_squirrel_event,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_pet_buff_npc_squirrel_event"}
|
||||
)
|
||||
____exports.modifier_pet_buff_npc_squirrel_event = modifier_pet_buff_npc_squirrel_event
|
||||
return ____exports
|
||||
@@ -0,0 +1,52 @@
|
||||
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 BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_pet_buff_npc_wolf_event = __TS__Class()
|
||||
local modifier_pet_buff_npc_wolf_event = ____exports.modifier_pet_buff_npc_wolf_event
|
||||
modifier_pet_buff_npc_wolf_event.name = "modifier_pet_buff_npc_wolf_event"
|
||||
modifier_pet_buff_npc_wolf_event.____file_path = "scripts/vscripts/abilities/modifiers/pets/modifier_pet_buff_npc_wolf_event.lua"
|
||||
__TS__ClassExtends(modifier_pet_buff_npc_wolf_event, BaseModifier)
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.IsDebuff(self)
|
||||
return false
|
||||
end
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.OnCreated(self, params)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
local stackingCritMod = self:GetParent():FindModifierByName("modifier_stacking_crit")
|
||||
if stackingCritMod then
|
||||
local ability = self:GetAbility()
|
||||
stackingCritMod:AddCustomCrit(15, 160, "modifier_pet_buff_npc_wolf_event")
|
||||
end
|
||||
end
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_DAMAGEOUTGOING_PERCENTAGE, MODIFIER_PROPERTY_SPELL_AMPLIFY_PERCENTAGE}
|
||||
end
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.GetModifierDamageOutgoing_Percentage(self, event)
|
||||
return 15
|
||||
end
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.GetModifierSpellAmplify_Percentage(self, event)
|
||||
return 15
|
||||
end
|
||||
function modifier_pet_buff_npc_wolf_event.prototype.GetTexture(self)
|
||||
return "lycan_feral_impulse"
|
||||
end
|
||||
modifier_pet_buff_npc_wolf_event = __TS__Decorate(
|
||||
modifier_pet_buff_npc_wolf_event,
|
||||
modifier_pet_buff_npc_wolf_event,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_pet_buff_npc_wolf_event"}
|
||||
)
|
||||
____exports.modifier_pet_buff_npc_wolf_event = modifier_pet_buff_npc_wolf_event
|
||||
return ____exports
|
||||
Reference in New Issue
Block a user