304 lines
14 KiB
Lua
304 lines
14 KiB
Lua
local ____lualib = require("lualib_bundle")
|
|
local __TS__Class = ____lualib.__TS__Class
|
|
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
|
local __TS__Decorate = ____lualib.__TS__Decorate
|
|
local ____exports = {}
|
|
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
|
local BaseAbility = ____dota_ts_adapter.BaseAbility
|
|
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
|
local registerAbility = ____dota_ts_adapter.registerAbility
|
|
local registerModifier = ____dota_ts_adapter.registerModifier
|
|
local ____incoming_damage_reduction_combine = require("utils.incoming_damage_reduction_combine")
|
|
local removeIncomingDamageReductionSource = ____incoming_damage_reduction_combine.removeIncomingDamageReductionSource
|
|
local setIncomingDamageReductionEventSource = ____incoming_damage_reduction_combine.setIncomingDamageReductionEventSource
|
|
local BRISTLEBACK_INCOMING_SOURCE = "modifier_bristleback_bristleback_custom"
|
|
____exports.bristleback_bristleback_custom = __TS__Class()
|
|
local bristleback_bristleback_custom = ____exports.bristleback_bristleback_custom
|
|
bristleback_bristleback_custom.name = "bristleback_bristleback_custom"
|
|
bristleback_bristleback_custom.____file_path = "scripts/vscripts/abilities/heroes/bristleback/bristleback_bristleback_custom.lua"
|
|
__TS__ClassExtends(bristleback_bristleback_custom, BaseAbility)
|
|
function bristleback_bristleback_custom.prototype.____constructor(self, ...)
|
|
BaseAbility.prototype.____constructor(self, ...)
|
|
self.caster = self:GetCaster()
|
|
end
|
|
function bristleback_bristleback_custom.prototype.GetIntrinsicModifierName(self)
|
|
return ____exports.modifier_bristleback_bristleback_custom.name
|
|
end
|
|
function bristleback_bristleback_custom.prototype.IsFacingBack(self, attacker)
|
|
local convert_attacker = EntIndexToHScript(attacker)
|
|
local forwardVector = self.caster:GetForwardVector()
|
|
local forwardAngle = math.deg(math.atan2(forwardVector.x, forwardVector.y))
|
|
local reverseEnemyVector = (self.caster:GetAbsOrigin() - convert_attacker:GetAbsOrigin()):Normalized()
|
|
local reverseEnemyAngle = math.deg(math.atan2(reverseEnemyVector.x, reverseEnemyVector.y))
|
|
local back_angle = self:GetSpecialValueFor("back_angle")
|
|
local difference = math.abs(forwardAngle - reverseEnemyAngle)
|
|
if difference <= back_angle / 1 or difference >= 360 - back_angle / 1 then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
function bristleback_bristleback_custom.prototype.IncStacks(self, add_stack)
|
|
local stack = add_stack
|
|
local mod = self.caster:FindModifierByName(____exports.modifier_bristleback_bristleback_custom.name)
|
|
local quill_release_threshold = self:GetSpecialValueFor("quill_release_threshold")
|
|
if mod == nil then
|
|
return
|
|
end
|
|
local all_stack = mod:GetStackCount() + stack
|
|
if self.caster:HasScepter() then
|
|
local scepter_thresholds = {
|
|
self:GetSpecialValueFor("quill_release_threshold"),
|
|
self:GetSpecialValueFor("quill_release_threshold_scepter1"),
|
|
self:GetSpecialValueFor("quill_release_threshold_scepter2"),
|
|
self:GetSpecialValueFor("quill_release_threshold_scepter3"),
|
|
self:GetSpecialValueFor("quill_release_threshold_scepter4")
|
|
}
|
|
local spray_count = 0
|
|
if all_stack >= scepter_thresholds[5] then
|
|
spray_count = 5
|
|
elseif all_stack >= scepter_thresholds[4] and all_stack < scepter_thresholds[5] then
|
|
spray_count = 4
|
|
elseif all_stack >= scepter_thresholds[3] and all_stack < scepter_thresholds[4] then
|
|
spray_count = 3
|
|
elseif all_stack >= scepter_thresholds[2] and all_stack < scepter_thresholds[3] then
|
|
spray_count = 2
|
|
elseif all_stack >= scepter_thresholds[1] and all_stack < scepter_thresholds[2] then
|
|
spray_count = 1
|
|
end
|
|
if spray_count >= 1 then
|
|
do
|
|
local i = 0
|
|
while i < spray_count do
|
|
____exports.modifier_bristleback_bristleback_custom_make_spray:apply(self.caster, self.caster, self, {})
|
|
i = i + 1
|
|
end
|
|
end
|
|
mod:SetStackCount(all_stack - spray_count * quill_release_threshold)
|
|
return
|
|
end
|
|
end
|
|
if all_stack >= quill_release_threshold then
|
|
local count = math.floor(all_stack / quill_release_threshold)
|
|
do
|
|
local i = 0
|
|
while i < count do
|
|
____exports.modifier_bristleback_bristleback_custom_make_spray:apply(self.caster, self.caster, self, {})
|
|
i = i + 1
|
|
end
|
|
end
|
|
mod:SetStackCount(all_stack - count * quill_release_threshold)
|
|
else
|
|
mod:SetStackCount(all_stack)
|
|
end
|
|
end
|
|
bristleback_bristleback_custom = __TS__Decorate(
|
|
bristleback_bristleback_custom,
|
|
bristleback_bristleback_custom,
|
|
{registerAbility(nil)},
|
|
{kind = "class", name = "bristleback_bristleback_custom"}
|
|
)
|
|
____exports.bristleback_bristleback_custom = bristleback_bristleback_custom
|
|
____exports.modifier_bristleback_bristleback_custom = __TS__Class()
|
|
local modifier_bristleback_bristleback_custom = ____exports.modifier_bristleback_bristleback_custom
|
|
modifier_bristleback_bristleback_custom.name = "modifier_bristleback_bristleback_custom"
|
|
modifier_bristleback_bristleback_custom.____file_path = "scripts/vscripts/abilities/heroes/bristleback/bristleback_bristleback_custom.lua"
|
|
__TS__ClassExtends(modifier_bristleback_bristleback_custom, BaseModifier)
|
|
function modifier_bristleback_bristleback_custom.prototype.____constructor(self, ...)
|
|
BaseModifier.prototype.____constructor(self, ...)
|
|
self.ability = self:GetAbility()
|
|
self.parent = self:GetParent()
|
|
self.side_angle = 0
|
|
self.back_angle = 0
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.IsPurgable(self)
|
|
return false
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.IsPurgeException(self)
|
|
return false
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.IsHidden(self)
|
|
return true
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.DeclareFunctions(self)
|
|
return {MODIFIER_EVENT_ON_TAKEDAMAGE}
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.OnCreated(self)
|
|
self.side_angle = self.ability:GetSpecialValueFor("side_angle")
|
|
self.back_angle = self.ability:GetSpecialValueFor("back_angle")
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
setIncomingDamageReductionEventSource(
|
|
nil,
|
|
self.parent,
|
|
BRISTLEBACK_INCOMING_SOURCE,
|
|
function(____, event)
|
|
if self.parent:PassivesDisabled() then
|
|
return 0
|
|
end
|
|
if bit.band(event.damage_flags, DOTA_DAMAGE_FLAG_REFLECTION) == DOTA_DAMAGE_FLAG_REFLECTION then
|
|
return 0
|
|
end
|
|
if bit.band(event.damage_flags, DOTA_DAMAGE_FLAG_HPLOSS) == DOTA_DAMAGE_FLAG_HPLOSS then
|
|
return 0
|
|
end
|
|
local forwardVector = self.parent:GetForwardVector()
|
|
local forwardAngle = math.deg(math.atan2(forwardVector.x, forwardVector.y))
|
|
local reverseEnemyVector = (self.parent:GetAbsOrigin() - event.attacker:GetAbsOrigin()):Normalized()
|
|
local reverseEnemyAngle = math.deg(math.atan2(reverseEnemyVector.x, reverseEnemyVector.y))
|
|
local difference = math.abs(forwardAngle - reverseEnemyAngle)
|
|
local sideDamageReduction = self.ability:GetSpecialValueFor("side_damage_reduction")
|
|
local backDamageReduction = self.ability:GetSpecialValueFor("back_damage_reduction")
|
|
if difference <= self.back_angle / 1 or difference >= 360 - self.back_angle / 1 then
|
|
local particle = ParticleManager:CreateParticle("particles/units/heroes/hero_bristleback/bristleback_back_dmg.vpcf", PATTACH_ABSORIGIN_FOLLOW, self.parent)
|
|
ParticleManager:SetParticleControl(
|
|
particle,
|
|
1,
|
|
self.parent:GetAbsOrigin()
|
|
)
|
|
ParticleManager:SetParticleControlEnt(
|
|
particle,
|
|
1,
|
|
self.parent,
|
|
PATTACH_POINT_FOLLOW,
|
|
"attach_hitloc",
|
|
self.parent:GetAbsOrigin(),
|
|
true
|
|
)
|
|
ParticleManager:ReleaseParticleIndex(particle)
|
|
local particle2 = ParticleManager:CreateParticle("particles/units/heroes/hero_bristleback/bristleback_back_lrg_dmg.vpcf", PATTACH_ABSORIGIN_FOLLOW, self.parent)
|
|
ParticleManager:SetParticleControlEnt(
|
|
particle2,
|
|
1,
|
|
self.parent,
|
|
PATTACH_POINT_FOLLOW,
|
|
"attach_hitloc",
|
|
self.parent:GetAbsOrigin(),
|
|
true
|
|
)
|
|
ParticleManager:ReleaseParticleIndex(particle2)
|
|
EmitSoundOn("Hero_Bristleback.Bristleback", self.parent)
|
|
return math.max(0, backDamageReduction)
|
|
end
|
|
if difference <= self.side_angle or difference >= 360 - self.side_angle then
|
|
local particle = ParticleManager:CreateParticle("particles/units/heroes/hero_bristleback/bristleback_back_dmg.vpcf", PATTACH_ABSORIGIN_FOLLOW, self.parent)
|
|
ParticleManager:SetParticleControl(
|
|
particle,
|
|
1,
|
|
self.parent:GetAbsOrigin()
|
|
)
|
|
ParticleManager:SetParticleControlEnt(
|
|
particle,
|
|
1,
|
|
self.parent,
|
|
PATTACH_POINT_FOLLOW,
|
|
"attach_hitloc",
|
|
self.parent:GetAbsOrigin(),
|
|
true
|
|
)
|
|
ParticleManager:ReleaseParticleIndex(particle)
|
|
return math.max(0, sideDamageReduction)
|
|
end
|
|
return 0
|
|
end
|
|
)
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.OnRefresh(self)
|
|
self:OnCreated()
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.OnDestroy(self)
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
removeIncomingDamageReductionSource(nil, self.parent, BRISTLEBACK_INCOMING_SOURCE)
|
|
end
|
|
function modifier_bristleback_bristleback_custom.prototype.OnTakeDamage(self, event)
|
|
if event.attacker == nil then
|
|
return
|
|
end
|
|
if event.unit ~= self.parent then
|
|
return
|
|
end
|
|
if self.parent:PassivesDisabled() then
|
|
return
|
|
end
|
|
if bit.band(event.damage_flags, DOTA_DAMAGE_FLAG_REFLECTION) == DOTA_DAMAGE_FLAG_REFLECTION then
|
|
return
|
|
end
|
|
if bit.band(event.damage_flags, DOTA_DAMAGE_FLAG_HPLOSS) == DOTA_DAMAGE_FLAG_HPLOSS then
|
|
return
|
|
end
|
|
if not self.parent:HasAbility("bristleback_quill_spray_custom") then
|
|
return
|
|
end
|
|
if not self.parent:FindAbilityByName("bristleback_quill_spray_custom"):IsTrained() then
|
|
return
|
|
end
|
|
if self.ability:IsFacingBack(event.attacker:GetEntityIndex()) then
|
|
self.ability:IncStacks(event.damage)
|
|
end
|
|
end
|
|
modifier_bristleback_bristleback_custom = __TS__Decorate(
|
|
modifier_bristleback_bristleback_custom,
|
|
modifier_bristleback_bristleback_custom,
|
|
{registerModifier(nil)},
|
|
{kind = "class", name = "modifier_bristleback_bristleback_custom"}
|
|
)
|
|
____exports.modifier_bristleback_bristleback_custom = modifier_bristleback_bristleback_custom
|
|
____exports.modifier_bristleback_bristleback_custom_make_spray = __TS__Class()
|
|
local modifier_bristleback_bristleback_custom_make_spray = ____exports.modifier_bristleback_bristleback_custom_make_spray
|
|
modifier_bristleback_bristleback_custom_make_spray.name = "modifier_bristleback_bristleback_custom_make_spray"
|
|
modifier_bristleback_bristleback_custom_make_spray.____file_path = "scripts/vscripts/abilities/heroes/bristleback/bristleback_bristleback_custom.lua"
|
|
__TS__ClassExtends(modifier_bristleback_bristleback_custom_make_spray, BaseModifier)
|
|
function modifier_bristleback_bristleback_custom_make_spray.prototype.IsHidden(self)
|
|
return true
|
|
end
|
|
function modifier_bristleback_bristleback_custom_make_spray.prototype.OnCreated(self, params)
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
self:SetStackCount(1)
|
|
self:Active()
|
|
self:StartIntervalThink(self:GetAbility():GetSpecialValueFor("quill_release_interval"))
|
|
end
|
|
function modifier_bristleback_bristleback_custom_make_spray.prototype.OnRefresh(self, params)
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
self:IncrementStackCount()
|
|
end
|
|
function modifier_bristleback_bristleback_custom_make_spray.prototype.Active(self)
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
if self:GetStackCount() <= 0 then
|
|
return
|
|
end
|
|
self:DecrementStackCount()
|
|
local ability_quill = self:GetParent():FindAbilityByName("bristleback_quill_spray_custom")
|
|
if not ability_quill then
|
|
return
|
|
end
|
|
if ability_quill:GetLevel() <= 0 then
|
|
return
|
|
end
|
|
ability_quill:MakeSpray(nil, true)
|
|
end
|
|
function modifier_bristleback_bristleback_custom_make_spray.prototype.OnIntervalThink(self)
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
self:Active()
|
|
if self:GetStackCount() <= 0 then
|
|
self:Destroy()
|
|
end
|
|
end
|
|
modifier_bristleback_bristleback_custom_make_spray = __TS__Decorate(
|
|
modifier_bristleback_bristleback_custom_make_spray,
|
|
modifier_bristleback_bristleback_custom_make_spray,
|
|
{registerModifier(nil)},
|
|
{kind = "class", name = "modifier_bristleback_bristleback_custom_make_spray"}
|
|
)
|
|
____exports.modifier_bristleback_bristleback_custom_make_spray = modifier_bristleback_bristleback_custom_make_spray
|
|
return ____exports
|