initial commit
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
aghanim_shard_attack = class( {} )
|
||||
|
||||
LinkLuaModifier( "modifier_aghanim_shard_attack", "modifiers/creatures/modifier_aghanim_shard_attack", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
_G.PATTERN_SPIRAL = 0
|
||||
_G.PATTERN_REBOUND = 1
|
||||
_G.PATTERN_JITTER = 2
|
||||
_G.CAST_ESCLATION_PCT = 17
|
||||
|
||||
_G.FAST_COLOR = Vector( 0, 0, 255 )
|
||||
_G.SLOW_COLOR = Vector( 350, 0, 0 ) -- looks weird, but it's because it can't go to 0 speed
|
||||
_G.HEAL_COLOR = Vector( 0, 255, 0 )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_shard_channel.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_shard_proj.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_lich/lich_frost_nova.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_dark_willow.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_silencer.vsndevts", context )
|
||||
|
||||
self.nPattern = PATTERN_SPIRAL
|
||||
self.nCastCount = 0
|
||||
self.Projectiles = {}
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
StartSoundEventFromPositionReliable( "Aghanim.ShardAttack.Channel", self:GetCaster():GetAbsOrigin() )
|
||||
self.nChannelFX = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_shard_channel.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:OnChannelThink( flInterval )
|
||||
if IsServer() then
|
||||
if self.nPattern == PATTERN_SPIRAL then
|
||||
self:ThinkSpirals( flInterval )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
StopSoundOn( "Aghanim.ShardAttack.Loop", self:GetCaster() )
|
||||
ParticleManager:DestroyParticle( self.nChannelFX, false )
|
||||
self.nCastCount = self.nCastCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:OnSpellStart()
|
||||
if IsServer() then
|
||||
EmitSoundOn( "Aghanim.ShardAttack.Loop", self:GetCaster() )
|
||||
if self.nPattern == PATTERN_SPIRAL then
|
||||
self:BeginSpirals()
|
||||
end
|
||||
if self.nPattern == PATTERN_REBOUND then
|
||||
self:BeginRebound()
|
||||
end
|
||||
if self.nPattern == PATTERN_JITTER then
|
||||
self:BeginJitter()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:BeginSpirals()
|
||||
self.Projectiles = {}
|
||||
|
||||
self.spiral_projectiles = self:GetSpecialValueFor( "spiral_projectiles" )
|
||||
self.spiral_projectile_waves = self:GetSpecialValueFor( "spiral_projectile_waves" )
|
||||
self.spiral_projectile_speed = self:GetSpecialValueFor( "spiral_projectile_speed" )
|
||||
|
||||
self.spiral_projectiles = math.min( self.spiral_projectiles * 2, math.floor( self.spiral_projectiles + ( self.spiral_projectiles * CAST_ESCLATION_PCT * self.nCastCount / 100 ) ) )
|
||||
self.spiral_projectile_waves = math.min( self.spiral_projectile_waves * 2, math.floor( self.spiral_projectile_waves + ( self.spiral_projectile_waves * CAST_ESCLATION_PCT * self.nCastCount / 100 ) ) )
|
||||
self.spiral_projectile_speed = math.min( self.spiral_projectile_speed * 2, math.floor( self.spiral_projectile_speed + ( self.spiral_projectile_speed * CAST_ESCLATION_PCT * self.nCastCount / 100 ) ) )
|
||||
|
||||
self.spiral_projectile_rotation_speed = self:GetSpecialValueFor( "spiral_projectile_rotation_speed" )
|
||||
self.spiral_projectile_width = self:GetSpecialValueFor( "spiral_projectile_width" )
|
||||
self.spiral_projectile_damage = self:GetSpecialValueFor( "spiral_projectile_damage" )
|
||||
self.spiral_projectile_speed_change_interval = self:GetSpecialValueFor( "spiral_projectile_speed_change_interval" )
|
||||
|
||||
self.flSpiralYaw = RandomInt( 0, 360 )
|
||||
self.flSpiralWaveInterval = self:GetChannelTime() / self.spiral_projectile_waves
|
||||
self.flSpiralNextWaveTime = GameRules:GetGameTime()
|
||||
self.flSpiralYawStep = 360 / self.spiral_projectiles
|
||||
self.bReverse = false
|
||||
|
||||
if RandomInt( 0, 1 ) == 1 then
|
||||
self.bReverse = true
|
||||
end
|
||||
|
||||
self.flSpiralSpeedToggleTime = GameRules:GetGameTime() + self.spiral_projectile_speed_change_interval
|
||||
self.bSpiralSpeedingUp = true
|
||||
self.flCurSpeed = self.spiral_projectile_speed
|
||||
self.nToggleCount = 0
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:ThinkSpirals( flInterval )
|
||||
local flNow = GameRules:GetGameTime()
|
||||
if flNow > self.flSpiralSpeedToggleTime then
|
||||
self.flSpiralSpeedToggleTime = flNow + self.spiral_projectile_speed_change_interval
|
||||
self.bSpiralSpeedingUp = not self.bSpiralSpeedingUp
|
||||
self.nToggleCount = self.nToggleCount + 1
|
||||
if self.nToggleCount == 2 then
|
||||
self.bReverse = not self.bReverse
|
||||
self.nToggleCount = 0
|
||||
end
|
||||
end
|
||||
|
||||
local flRate = ( self.spiral_projectile_speed / self.spiral_projectile_speed_change_interval ) * flInterval
|
||||
if self.bSpiralSpeedingUp then
|
||||
self.flCurSpeed = math.min( self.spiral_projectile_speed, self.flCurSpeed + flRate )
|
||||
else
|
||||
self.flCurSpeed = math.max( 100, self.flCurSpeed - flRate )
|
||||
end
|
||||
|
||||
if self.flSpiralNextWaveTime > flNow then
|
||||
return
|
||||
end
|
||||
|
||||
self.flSpiralNextWaveTime = flNow + self.flSpiralWaveInterval
|
||||
EmitSoundOn( "Aghanim.ShardAttack.Wave", self:GetCaster() )
|
||||
|
||||
for i=1,self.spiral_projectiles do
|
||||
local Angle = QAngle( 0, self.flSpiralYaw, 0 )
|
||||
local vVelocity = ( RotatePosition( Vector( 0, 0, 0 ), Angle, Vector( 1, 0, 0 ) ) ) * self.flCurSpeed
|
||||
local nProjectileHandle = self:LaunchCrystals( vVelocity, 5000, self.spiral_projectile_width )
|
||||
|
||||
local ProjectileInfo = {}
|
||||
ProjectileInfo.nHandle = nProjectileHandle
|
||||
ProjectileInfo.flYaw = self.flSpiralYaw
|
||||
ProjectileInfo.nFXIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_shard_proj.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
|
||||
local vLoc = self:GetCaster():GetAbsOrigin()
|
||||
vLoc.z = GetGroundHeight( vLoc, self:GetCaster() ) + 50
|
||||
ProjectileInfo.attachEnt = CreateUnitByName( "npc_dota_wisp_spirit", vLoc, false, self:GetCaster(), self:GetCaster(), DOTA_TEAM_GOODGUYS )
|
||||
if ProjectileInfo.attachEnt ~= nil then
|
||||
ProjectileInfo.attachEnt:AddNewModifier( self:GetCaster(), self, "modifier_wisp_spirit_invulnerable", {} )
|
||||
end
|
||||
ParticleManager:SetParticleControlEnt( ProjectileInfo.nFXIndex, 0, ProjectileInfo.attachEnt, PATTACH_ABSORIGIN_FOLLOW, nil, vLoc, false )
|
||||
ParticleManager:SetParticleControl( ProjectileInfo.nFXIndex, 1, Vector( self.spiral_projectile_width, self.spiral_projectile_width, self.spiral_projectile_width ) )
|
||||
ParticleManager:SetParticleControl( ProjectileInfo.nFXIndex, 2, Vector( 6, 6, 6 ) )
|
||||
|
||||
--local flSpeedColorFactor = self.flCurSpeed / self.spiral_projectile_speed
|
||||
--local vColor = LerpVectors( SLOW_COLOR, FAST_COLOR, flSpeedColorFactor )
|
||||
--ParticleManager:SetParticleControl( ProjectileInfo.nFXIndex, 15, vColor )
|
||||
|
||||
table.insert( self.Projectiles, ProjectileInfo )
|
||||
|
||||
if self.bReverse then
|
||||
self.flSpiralYaw = self.flSpiralYaw - self.flSpiralYawStep
|
||||
else
|
||||
self.flSpiralYaw = self.flSpiralYaw + self.flSpiralYawStep
|
||||
end
|
||||
end
|
||||
|
||||
self.flSpiralYaw = self.flSpiralYaw + self.flSpiralYawStep * 0.5
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:ThinkSpiralProjectile( info )
|
||||
if self:IsChanneling() then
|
||||
local flNewYaw = 0
|
||||
if self.bReverse then
|
||||
flNewYaw = info.flYaw - self.spiral_projectile_rotation_speed
|
||||
else
|
||||
flNewYaw = info.flYaw + self.spiral_projectile_rotation_speed
|
||||
end
|
||||
|
||||
info.flYaw = flNewYaw
|
||||
|
||||
local Angle = QAngle( 0, flNewYaw, 0 )
|
||||
local vNewVelocity = ( RotatePosition( Vector( 0, 0, 0 ), Angle, Vector( 1, 0, 0 ) ) ) * self.flCurSpeed
|
||||
ProjectileManager:UpdateLinearProjectileDirection( info.nHandle, vNewVelocity, 5000 )
|
||||
end
|
||||
|
||||
|
||||
local vLoc = ProjectileManager:GetLinearProjectileLocation( info.nHandle )
|
||||
vLoc.z = GetGroundHeight( vLoc, self:GetCaster() ) + 50
|
||||
info.attachEnt:SetAbsOrigin( vLoc )
|
||||
--ParticleManager:SetParticleControl( info.nFXIndex, 0, vLoc )
|
||||
|
||||
--local flSpeedColorFactor = self.flCurSpeed / self.spiral_projectile_speed
|
||||
--local vColor = LerpVectors( SLOW_COLOR, FAST_COLOR, flSpeedColorFactor )
|
||||
--ParticleManager:SetParticleControl( info.nFXIndex, 15, vColor )
|
||||
|
||||
--rint( "setting new velocity on spiral projectile" )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:BeginRebound()
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:ThinkRebound( flInterval )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:ThinkReboundProjectile( info )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:BeginJitter()
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:ThinkJitter( flInterval )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:ThinkJitterProjectile( info )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:LaunchCrystals( vVel, flDist, flRadius )
|
||||
local info =
|
||||
{
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetAbsOrigin(),
|
||||
fStartRadius = flRadius,
|
||||
fEndRadius = flRadius,
|
||||
vVelocity = vVel,
|
||||
fDistance = flDist,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
}
|
||||
|
||||
return ProjectileManager:CreateLinearProjectile( info )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:OnProjectileThinkHandle( iProjectileHandle )
|
||||
if IsServer() then
|
||||
local info = nil
|
||||
for _,v in pairs ( self.Projectiles ) do
|
||||
if v.nHandle == iProjectileHandle then
|
||||
info = v
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if info == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if self.nPattern == PATTERN_SPIRAL then
|
||||
self:ThinkSpiralProjectile( info )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_shard_attack:OnProjectileHitHandle( hTarget, vLocation, iProjectileHandle )
|
||||
if IsServer() then
|
||||
local info = nil
|
||||
for _,v in pairs ( self.Projectiles ) do
|
||||
if v.nHandle == iProjectileHandle then
|
||||
info = v
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if info == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
if self.nPattern == PATTERN_SPIRAL then
|
||||
ParticleManager:DestroyParticle( info.nFXIndex, false )
|
||||
UTIL_Remove( info.attachEnt )
|
||||
info.attachEnt = nil
|
||||
end
|
||||
|
||||
if hTarget and not hTarget:IsMagicImmune() and not hTarget:IsInvulnerable() then
|
||||
local damage =
|
||||
{
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.spiral_projectile_damage,
|
||||
damage_type = DAMAGE_TYPE_PURE,
|
||||
ability = self,
|
||||
}
|
||||
|
||||
ApplyDamage( damage )
|
||||
|
||||
EmitSoundOn( "Hero_Silencer.LastWord.Damage", hTarget )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_lich/lich_frost_nova.vpcf", PATTACH_WORLDORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, hTarget:GetAbsOrigin() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( self.spiral_projectile_width, self.spiral_projectile_width, self.spiral_projectile_width ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
Reference in New Issue
Block a user